0005-backoffice-button-to-refresh-agendas-48282.patch
tests/admin_pages/test_datasource.py | ||
---|---|---|
1 | 1 |
# -*- coding: utf-8 -*- |
2 | 2 | |
3 | 3 |
import json |
4 |
import mock |
|
4 | 5 |
import os |
5 | 6 |
import xml.etree.ElementTree as ET |
6 | 7 | |
... | ... | |
111 | 112 |
resp = app.get('/backoffice/settings/data-sources/') |
112 | 113 |
assert 'Agendas' not in resp.text |
113 | 114 |
assert 'There are no data sources from agendas.' not in resp.text |
115 |
assert 'sync-agendas' not in resp.text |
|
114 | 116 | |
115 | 117 | |
116 | 118 |
def test_data_sources_agenda(pub, chrono_url): |
... | ... | |
121 | 123 |
resp = app.get('/backoffice/settings/data-sources/') |
122 | 124 |
assert 'Agendas' in resp.text |
123 | 125 |
assert 'There are no agendas.' in resp.text |
126 |
assert 'sync-agendas' in resp.text |
|
124 | 127 | |
125 | 128 |
data_source = NamedDataSource(name='foobar') |
126 | 129 |
data_source.data_source = {'type': 'json', 'value': 'http://some.url'} |
... | ... | |
614 | 617 |
resp = resp.click(href='edit') |
615 | 618 |
assert 'form_slug' in resp.text |
616 | 619 |
resp = resp.form.submit('submit') |
620 | ||
621 | ||
622 |
@mock.patch('wcs.data_sources.collect_agenda_data') |
|
623 |
def test_data_sources_agenda_refresh(mock_collect, pub, chrono_url): |
|
624 |
create_superuser(pub) |
|
625 |
NamedDataSource.wipe() |
|
626 | ||
627 |
mock_collect.return_value = [ |
|
628 |
{'text': 'Events A', 'url': 'http://chrono.example.net/api/agenda/events-A/datetimes/'}, |
|
629 |
{'text': 'Events B', 'url': 'http://chrono.example.net/api/agenda/events-B/datetimes/'}, |
|
630 |
] |
|
631 | ||
632 |
app = login(get_app(pub)) |
|
633 |
resp = app.get('/backoffice/settings/data-sources/sync-agendas') |
|
634 |
assert resp.location == 'http://example.net/backoffice/settings/data-sources/' |
|
635 |
assert NamedDataSource.count() == 2 |
wcs/admin/data_sources.py | ||
---|---|---|
32 | 32 |
from wcs.qommon import misc |
33 | 33 |
from wcs.qommon.backoffice.menu import html_top |
34 | 34 |
from wcs.carddef import CardDef |
35 |
from wcs.data_sources import NamedDataSource, DataSourceSelectionWidget, get_structured_items, has_chrono |
|
35 |
from wcs.data_sources import ( |
|
36 |
NamedDataSource, |
|
37 |
DataSourceSelectionWidget, |
|
38 |
get_structured_items, |
|
39 |
has_chrono, |
|
40 |
RefreshAgendas, |
|
41 |
) |
|
36 | 42 |
from wcs.formdef import FormDef, get_formdefs_of_all_kinds |
37 | 43 |
from wcs.backoffice.snapshots import SnapshotsDirectory |
38 | 44 | |
... | ... | |
364 | 370 | |
365 | 371 | |
366 | 372 |
class NamedDataSourcesDirectory(Directory): |
367 |
_q_exports = ['', 'new', ('import', 'p_import')] |
|
373 |
_q_exports = ['', 'new', ('import', 'p_import'), ('sync-agendas', 'sync_agendas')]
|
|
368 | 374 | |
369 | 375 |
def _q_traverse(self, path): |
370 | 376 |
get_response().breadcrumb.append(('data-sources/', _('Data Sources'))) |
... | ... | |
463 | 469 |
datasource.slug = None # a new one will be set in .store() |
464 | 470 |
datasource.store() |
465 | 471 |
return redirect('%s/' % datasource.id) |
472 | ||
473 |
def sync_agendas(self): |
|
474 |
get_response().add_after_job(RefreshAgendas()) |
|
475 |
get_session().message = ('info', _('Agendas will be updated in the background.')) |
|
476 |
return redirect('.') |
wcs/data_sources.py | ||
---|---|---|
27 | 27 |
from quixote import get_publisher, get_request, get_session |
28 | 28 |
from quixote.html import TemplateIO |
29 | 29 | |
30 |
from .qommon import _, force_str |
|
30 |
from .qommon import _, N_, force_str
|
|
31 | 31 |
from .qommon import misc |
32 | 32 |
from .qommon import get_logger |
33 | 33 |
from .qommon.cron import CronJob |
... | ... | |
35 | 35 |
from .qommon.humantime import seconds2humanduration |
36 | 36 |
from .qommon.misc import get_variadic_url |
37 | 37 |
from .qommon.publisher import get_publisher_class |
38 |
from .qommon.afterjobs import AfterJob |
|
38 | 39 |
from .qommon.storage import StorableObject |
39 | 40 |
from .qommon.template import Template |
40 | 41 |
from .qommon.xml_storage import XmlStorableObject |
... | ... | |
843 | 844 |
datasource.remove_self() |
844 | 845 | |
845 | 846 | |
847 |
class RefreshAgendas(AfterJob): |
|
848 |
label = N_('Refreshing agendas') |
|
849 | ||
850 |
def execute(self): |
|
851 |
build_agenda_datasources(get_publisher()) |
|
852 | ||
853 | ||
846 | 854 |
if get_publisher_class(): |
847 | 855 |
# every hour: check for agenda datasources |
848 | 856 |
get_publisher_class().register_cronjob( |
wcs/templates/wcs/backoffice/data-sources.html | ||
---|---|---|
4 | 4 |
{% block appbar-title %}{% trans "Data Sources" %}{% endblock %} |
5 | 5 | |
6 | 6 |
{% block appbar-actions %} |
7 |
{% if has_chrono %} |
|
8 |
<a href="sync-agendas">{% trans "Refresh agendas" %}</a> |
|
9 |
{% endif %} |
|
7 | 10 |
<a data-popup href="import">{% trans "Import" %}</a> |
8 | 11 |
<a href="new">{% trans "New Data Source" %}</a> |
9 | 12 |
{% endblock %} |
10 |
- |