From 34328a5313a150d6e6225008819c222e24c79704 Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Wed, 4 Nov 2020 17:26:16 +0100 Subject: [PATCH] manager: add site export (#48100) --- chrono/manager/forms.py | 7 +++++ .../templates/chrono/manager_home.html | 4 +++ chrono/manager/urls.py | 1 + chrono/manager/utils.py | 12 ++++--- chrono/manager/views.py | 25 ++++++++++++++- tests/test_manager.py | 31 +++++++++++++++++++ 6 files changed, 74 insertions(+), 6 deletions(-) diff --git a/chrono/manager/forms.py b/chrono/manager/forms.py index 3c36b81..ff33e9f 100644 --- a/chrono/manager/forms.py +++ b/chrono/manager/forms.py @@ -596,3 +596,10 @@ class AgendaReminderForm(forms.ModelForm): if cleaned_data['days'] and not (cleaned_data['send_email'] or cleaned_data.get('send_sms')): raise ValidationError(_('Select at least one notification medium.')) return cleaned_data + + +class SiteExportForm(forms.Form): + agendas = forms.BooleanField(label=_('Agendas'), required=False, initial=True) + unavailability_calendars = forms.BooleanField( + label=_('Unavailability calendars'), required=False, initial=True + ) diff --git a/chrono/manager/templates/chrono/manager_home.html b/chrono/manager/templates/chrono/manager_home.html index 7a20607..9aea5a4 100644 --- a/chrono/manager/templates/chrono/manager_home.html +++ b/chrono/manager/templates/chrono/manager_home.html @@ -5,6 +5,10 @@

{% trans 'Agendas' %}

{% if user.is_staff %} + + {% trans 'Categories' %} {% endif %} {% trans 'Unavailability calendars' %} diff --git a/chrono/manager/urls.py b/chrono/manager/urls.py index 856aed2..edbd9bf 100644 --- a/chrono/manager/urls.py +++ b/chrono/manager/urls.py @@ -20,6 +20,7 @@ from . import views urlpatterns = [ url(r'^$', views.homepage, name='chrono-manager-homepage'), + url(r'^site-export/$', views.site_export, name='chrono-manager-site-export'), url( r'^unavailability-calendars/$', views.unavailability_calendar_list, diff --git a/chrono/manager/utils.py b/chrono/manager/utils.py index 5d289ce..0f5cdf0 100644 --- a/chrono/manager/utils.py +++ b/chrono/manager/utils.py @@ -24,13 +24,15 @@ from django.db.models import Q from chrono.agendas.models import Agenda, AgendaImportError, UnavailabilityCalendar -def export_site(): +def export_site(agendas=True, unavailability_calendars=True): '''Dump site objects to JSON-dumpable dictionnary''' data = collections.OrderedDict() - data['unavailability_calendars'] = [x.export_json() for x in UnavailabilityCalendar.objects.all()] - qs1 = Agenda.objects.filter(~Q(kind='virtual')) - qs2 = Agenda.objects.filter(kind='virtual') - data['agendas'] = [x.export_json() for x in itertools.chain(qs1, qs2)] + if unavailability_calendars: + data['unavailability_calendars'] = [x.export_json() for x in UnavailabilityCalendar.objects.all()] + if agendas: + qs1 = Agenda.objects.filter(~Q(kind='virtual')) + qs2 = Agenda.objects.filter(kind='virtual') + data['agendas'] = [x.export_json() for x in itertools.chain(qs1, qs2)] return data diff --git a/chrono/manager/views.py b/chrono/manager/views.py index 40ddaa5..e7cdc8e 100644 --- a/chrono/manager/views.py +++ b/chrono/manager/views.py @@ -98,8 +98,9 @@ from .forms import ( AgendaReminderForm, UnavailabilityCalendarAddForm, UnavailabilityCalendarEditForm, + SiteExportForm, ) -from .utils import import_site +from .utils import import_site, export_site FUTURE_BOOKING_ERROR_MSG = _('This cannot be removed as there are bookings for a future date.') @@ -119,6 +120,28 @@ class HomepageView(ListView): homepage = HomepageView.as_view() +class SiteExportView(FormView): + form_class = SiteExportForm + template_name = 'chrono/manager_site_export_form.html' + + def dispatch(self, request, *args, **kwargs): + if not request.user.is_staff: + raise PermissionDenied() + return super().dispatch(request, *args, **kwargs) + + def form_valid(self, form): + response = HttpResponse(content_type='application/json') + today = datetime.date.today() + response['Content-Disposition'] = 'attachment; filename="export_site_{}.json"'.format( + today.strftime('%Y%m%d') + ) + json.dump(export_site(**form.cleaned_data), response, indent=2) + return response + + +site_export = SiteExportView.as_view() + + class ResourceListView(ListView): template_name = 'chrono/manager_resource_list.html' model = Resource diff --git a/tests/test_manager.py b/tests/test_manager.py index ec7ce11..47bb781 100644 --- a/tests/test_manager.py +++ b/tests/test_manager.py @@ -5001,3 +5001,34 @@ def test_unavailability_calendar_delete_unavailability_permissions(app, manager_ unavailability_calendar.edit_role = group unavailability_calendar.save() app.get(url) + + +def test_export_site(app, admin_user): + login(app) + resp = app.get('/manage/') + resp = resp.click('Export Site') + + with freezegun.freeze_time('2020-06-15'): + resp = resp.form.submit() + assert resp.headers['content-type'] == 'application/json' + assert resp.headers['content-disposition'] == 'attachment; filename="export_site_20200615.json"' + + site_json = json.loads(resp.text) + assert site_json == {'unavailability_calendars': [], 'agendas': []} + + agenda = Agenda.objects.create(label=u'Foo Bar', kind='events') + unavailability_calendar = UnavailabilityCalendar.objects.create(label='Calendar 1') + resp = app.get('/manage/site-export/') + resp = resp.form.submit() + + site_json = json.loads(resp.text) + assert len(site_json['agendas']) == 1 + assert len(site_json['unavailability_calendars']) == 1 + + resp = app.get('/manage/site-export/') + resp.form['agendas'] = False + resp = resp.form.submit() + + site_json = json.loads(resp.text) + assert 'agendas' not in site_json + assert 'unavailability_calendars' in site_json -- 2.20.1