diff --git a/tests/admin_pages/test_datasource.py b/tests/admin_pages/test_datasource.py index 43a00561c..87a1e8587 100644 --- a/tests/admin_pages/test_datasource.py +++ b/tests/admin_pages/test_datasource.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import json +import mock import os import xml.etree.ElementTree as ET @@ -111,6 +112,7 @@ def test_data_sources_agenda_without_chrono(pub): resp = app.get('/backoffice/settings/data-sources/') assert 'Agendas' not in resp.text assert 'There are no data sources from agendas.' not in resp.text + assert 'sync-agendas' not in resp.text def test_data_sources_agenda(pub, chrono_url): @@ -121,6 +123,7 @@ def test_data_sources_agenda(pub, chrono_url): resp = app.get('/backoffice/settings/data-sources/') assert 'Agendas' in resp.text assert 'There are no agendas.' in resp.text + assert 'sync-agendas' in resp.text data_source = NamedDataSource(name='foobar') data_source.data_source = {'type': 'json', 'value': 'http://some.url'} @@ -614,3 +617,19 @@ def test_data_sources_in_use_edit_slug(pub): resp = resp.click(href='edit') assert 'form_slug' in resp.text resp = resp.form.submit('submit') + + +@mock.patch('wcs.data_sources.collect_agenda_data') +def test_data_sources_agenda_refresh(mock_collect, pub, chrono_url): + create_superuser(pub) + NamedDataSource.wipe() + + mock_collect.return_value = [ + {'text': 'Events A', 'url': 'http://chrono.example.net/api/agenda/events-A/datetimes/'}, + {'text': 'Events B', 'url': 'http://chrono.example.net/api/agenda/events-B/datetimes/'}, + ] + + app = login(get_app(pub)) + resp = app.get('/backoffice/settings/data-sources/sync-agendas') + assert resp.location == 'http://example.net/backoffice/settings/data-sources/' + assert NamedDataSource.count() == 2 diff --git a/wcs/admin/data_sources.py b/wcs/admin/data_sources.py index 5046f3975..d835aa701 100644 --- a/wcs/admin/data_sources.py +++ b/wcs/admin/data_sources.py @@ -32,7 +32,13 @@ from wcs.qommon.form import get_session from wcs.qommon import misc from wcs.qommon.backoffice.menu import html_top from wcs.carddef import CardDef -from wcs.data_sources import NamedDataSource, DataSourceSelectionWidget, get_structured_items, has_chrono +from wcs.data_sources import ( + NamedDataSource, + DataSourceSelectionWidget, + get_structured_items, + has_chrono, + RefreshAgendas, +) from wcs.formdef import FormDef, get_formdefs_of_all_kinds from wcs.backoffice.snapshots import SnapshotsDirectory @@ -364,7 +370,7 @@ class NamedDataSourcePage(Directory): class NamedDataSourcesDirectory(Directory): - _q_exports = ['', 'new', ('import', 'p_import')] + _q_exports = ['', 'new', ('import', 'p_import'), ('sync-agendas', 'sync_agendas')] def _q_traverse(self, path): get_response().breadcrumb.append(('data-sources/', _('Data Sources'))) @@ -463,3 +469,8 @@ class NamedDataSourcesDirectory(Directory): datasource.slug = None # a new one will be set in .store() datasource.store() return redirect('%s/' % datasource.id) + + def sync_agendas(self): + get_response().add_after_job(RefreshAgendas()) + get_session().message = ('info', _('Agendas will be updated in the background.')) + return redirect('.') diff --git a/wcs/data_sources.py b/wcs/data_sources.py index 95978635e..9ca96beee 100644 --- a/wcs/data_sources.py +++ b/wcs/data_sources.py @@ -27,7 +27,7 @@ from django.utils.six.moves.urllib import parse as urlparse from quixote import get_publisher, get_request, get_session from quixote.html import TemplateIO -from .qommon import _, force_str +from .qommon import _, N_, force_str from .qommon import misc from .qommon import get_logger from .qommon.cron import CronJob @@ -35,6 +35,7 @@ from .qommon.form import * from .qommon.humantime import seconds2humanduration from .qommon.misc import get_variadic_url from .qommon.publisher import get_publisher_class +from .qommon.afterjobs import AfterJob from .qommon.storage import StorableObject from .qommon.template import Template from .qommon.xml_storage import XmlStorableObject @@ -843,6 +844,13 @@ def build_agenda_datasources(publisher): datasource.remove_self() +class RefreshAgendas(AfterJob): + label = N_('Refreshing agendas') + + def execute(self): + build_agenda_datasources(get_publisher()) + + if get_publisher_class(): # every hour: check for agenda datasources get_publisher_class().register_cronjob( diff --git a/wcs/templates/wcs/backoffice/data-sources.html b/wcs/templates/wcs/backoffice/data-sources.html index deb75c353..8d32272d6 100644 --- a/wcs/templates/wcs/backoffice/data-sources.html +++ b/wcs/templates/wcs/backoffice/data-sources.html @@ -4,6 +4,9 @@ {% block appbar-title %}{% trans "Data Sources" %}{% endblock %} {% block appbar-actions %} +{% if has_chrono %} +{% trans "Refresh agendas" %} +{% endif %} {% trans "Import" %} {% trans "New Data Source" %} {% endblock %}