0001-manager-add-site-export-48100.patch
chrono/manager/forms.py | ||
---|---|---|
596 | 596 |
if cleaned_data['days'] and not (cleaned_data['send_email'] or cleaned_data.get('send_sms')): |
597 | 597 |
raise ValidationError(_('Select at least one notification medium.')) |
598 | 598 |
return cleaned_data |
599 | ||
600 | ||
601 |
class SiteExportForm(forms.Form): |
|
602 |
agendas = forms.BooleanField(label=_('Agendas'), required=False, initial=True) |
|
603 |
unavailability_calendars = forms.BooleanField( |
|
604 |
label=_('Unavailability calendars'), required=False, initial=True |
|
605 |
) |
chrono/manager/templates/chrono/manager_home.html | ||
---|---|---|
5 | 5 |
<h2>{% trans 'Agendas' %}</h2> |
6 | 6 |
<span class="actions"> |
7 | 7 |
{% if user.is_staff %} |
8 |
<a class="extra-actions-menu-opener"></a> |
|
9 |
<ul class="extra-actions-menu"> |
|
10 |
<li><a rel="popup" href="{% url 'chrono-manager-site-export' %}">{% trans 'Export Site' %}</a></li> |
|
11 |
</ul> |
|
8 | 12 |
<a href="{% url 'chrono-manager-category-list' %}">{% trans 'Categories' %}</a> |
9 | 13 |
{% endif %} |
10 | 14 |
<a href="{% url 'chrono-manager-unavailability-calendar-list' %}">{% trans 'Unavailability calendars' %}</a> |
chrono/manager/urls.py | ||
---|---|---|
20 | 20 | |
21 | 21 |
urlpatterns = [ |
22 | 22 |
url(r'^$', views.homepage, name='chrono-manager-homepage'), |
23 |
url(r'^site-export/$', views.site_export, name='chrono-manager-site-export'), |
|
23 | 24 |
url( |
24 | 25 |
r'^unavailability-calendars/$', |
25 | 26 |
views.unavailability_calendar_list, |
chrono/manager/utils.py | ||
---|---|---|
24 | 24 |
from chrono.agendas.models import Agenda, AgendaImportError, UnavailabilityCalendar |
25 | 25 | |
26 | 26 | |
27 |
def export_site(): |
|
27 |
def export_site(agendas=True, unavailability_calendars=True):
|
|
28 | 28 |
'''Dump site objects to JSON-dumpable dictionnary''' |
29 | 29 |
data = collections.OrderedDict() |
30 |
data['unavailability_calendars'] = [x.export_json() for x in UnavailabilityCalendar.objects.all()] |
|
31 |
qs1 = Agenda.objects.filter(~Q(kind='virtual')) |
|
32 |
qs2 = Agenda.objects.filter(kind='virtual') |
|
33 |
data['agendas'] = [x.export_json() for x in itertools.chain(qs1, qs2)] |
|
30 |
if unavailability_calendars: |
|
31 |
data['unavailability_calendars'] = [x.export_json() for x in UnavailabilityCalendar.objects.all()] |
|
32 |
if agendas: |
|
33 |
qs1 = Agenda.objects.filter(~Q(kind='virtual')) |
|
34 |
qs2 = Agenda.objects.filter(kind='virtual') |
|
35 |
data['agendas'] = [x.export_json() for x in itertools.chain(qs1, qs2)] |
|
34 | 36 |
return data |
35 | 37 | |
36 | 38 |
chrono/manager/views.py | ||
---|---|---|
98 | 98 |
AgendaReminderForm, |
99 | 99 |
UnavailabilityCalendarAddForm, |
100 | 100 |
UnavailabilityCalendarEditForm, |
101 |
SiteExportForm, |
|
101 | 102 |
) |
102 |
from .utils import import_site |
|
103 |
from .utils import import_site, export_site
|
|
103 | 104 | |
104 | 105 |
FUTURE_BOOKING_ERROR_MSG = _('This cannot be removed as there are bookings for a future date.') |
105 | 106 | |
... | ... | |
119 | 120 |
homepage = HomepageView.as_view() |
120 | 121 | |
121 | 122 | |
123 |
class SiteExportView(FormView): |
|
124 |
form_class = SiteExportForm |
|
125 |
template_name = 'chrono/manager_site_export_form.html' |
|
126 | ||
127 |
def dispatch(self, request, *args, **kwargs): |
|
128 |
if not request.user.is_staff: |
|
129 |
raise PermissionDenied() |
|
130 |
return super().dispatch(request, *args, **kwargs) |
|
131 | ||
132 |
def form_valid(self, form): |
|
133 |
response = HttpResponse(content_type='application/json') |
|
134 |
today = datetime.date.today() |
|
135 |
response['Content-Disposition'] = 'attachment; filename="export_site_{}.json"'.format( |
|
136 |
today.strftime('%Y%m%d') |
|
137 |
) |
|
138 |
json.dump(export_site(**form.cleaned_data), response, indent=2) |
|
139 |
return response |
|
140 | ||
141 | ||
142 |
site_export = SiteExportView.as_view() |
|
143 | ||
144 | ||
122 | 145 |
class ResourceListView(ListView): |
123 | 146 |
template_name = 'chrono/manager_resource_list.html' |
124 | 147 |
model = Resource |
tests/test_manager.py | ||
---|---|---|
5001 | 5001 |
unavailability_calendar.edit_role = group |
5002 | 5002 |
unavailability_calendar.save() |
5003 | 5003 |
app.get(url) |
5004 | ||
5005 | ||
5006 |
def test_export_site(app, admin_user): |
|
5007 |
login(app) |
|
5008 |
resp = app.get('/manage/') |
|
5009 |
resp = resp.click('Export Site') |
|
5010 | ||
5011 |
with freezegun.freeze_time('2020-06-15'): |
|
5012 |
resp = resp.form.submit() |
|
5013 |
assert resp.headers['content-type'] == 'application/json' |
|
5014 |
assert resp.headers['content-disposition'] == 'attachment; filename="export_site_20200615.json"' |
|
5015 | ||
5016 |
site_json = json.loads(resp.text) |
|
5017 |
assert site_json == {'unavailability_calendars': [], 'agendas': []} |
|
5018 | ||
5019 |
agenda = Agenda.objects.create(label=u'Foo Bar', kind='events') |
|
5020 |
unavailability_calendar = UnavailabilityCalendar.objects.create(label='Calendar 1') |
|
5021 |
resp = app.get('/manage/site-export/') |
|
5022 |
resp = resp.form.submit() |
|
5023 | ||
5024 |
site_json = json.loads(resp.text) |
|
5025 |
assert len(site_json['agendas']) == 1 |
|
5026 |
assert len(site_json['unavailability_calendars']) == 1 |
|
5027 | ||
5028 |
resp = app.get('/manage/site-export/') |
|
5029 |
resp.form['agendas'] = False |
|
5030 |
resp = resp.form.submit() |
|
5031 | ||
5032 |
site_json = json.loads(resp.text) |
|
5033 |
assert 'agendas' not in site_json |
|
5034 |
assert 'unavailability_calendars' in site_json |
|
5004 |
- |