api: allow specifying the endtime field in ics URL (#20557)

This commit is contained in:
Frédéric Péters 2017-12-11 20:19:36 +01:00
parent f845d30849
commit 93704be427
2 changed files with 45 additions and 8 deletions

View File

@ -1599,6 +1599,7 @@ def ics_data(local_user):
formdef.workflow_roles = {'_receiver': role.id}
formdef.fields = [
fields.StringField(id='0', label='foobar', varname='foobar'),
fields.StringField(id='1', label='foobar2', varname='foobar2'),
]
formdef.store()
@ -1609,6 +1610,7 @@ def ics_data(local_user):
for i in range(30):
formdata = data_class()
formdata.data = {'0': (date + datetime.timedelta(days=i)).strftime('%Y-%m-%d %H:%M')}
formdata.data['1'] = (date + datetime.timedelta(days=i, minutes=i+1)).strftime('%Y-%m-%d %H:%M')
formdata.user_id = local_user.id
formdata.just_created()
if i%3 == 0:
@ -1631,6 +1633,8 @@ def test_api_ics_formdata(pub, local_user, ics_data):
# check it gets the data
resp = get_app(pub).get(sign_uri('/api/forms/test/ics/foobar', user=local_user))
resp2 = get_app(pub).get(sign_uri('/api/forms/test/ics/foobar/', user=local_user))
assert resp.body == resp2.body
assert resp.headers['content-type'] == 'text/calendar; charset=utf-8'
assert resp.body.count('BEGIN:VEVENT') == 10
# check that description contains form name, display id, workflow status,
@ -1639,6 +1643,7 @@ def test_api_ics_formdata(pub, local_user, ics_data):
m = pattern.findall(resp.body)
assert len(m) == 10
assert resp.body.count('Jean Darmette') == 10
assert resp.body.count('DTSTART') == 10
# check with a filter
resp = get_app(pub).get(sign_uri('/api/forms/test/ics/foobar?filter=done', user=local_user))
@ -1651,6 +1656,19 @@ def test_api_ics_formdata(pub, local_user, ics_data):
# check 404 on erroneous field var
resp = get_app(pub).get(sign_uri('/api/forms/test/ics/xxx', user=local_user), status=404)
# check 404 on an erroneous field var for endtime
resp = get_app(pub).get(sign_uri('/api/forms/test/ics/foobar/xxx', user=local_user), status=404)
# check 404 on too many path elements
resp = get_app(pub).get(sign_uri('/api/forms/test/ics/foobar/foobar2/xxx', user=local_user), status=404)
# check ics data with start and end varnames
resp = get_app(pub).get(sign_uri('/api/forms/test/ics/foobar/foobar2', user=local_user))
resp2 = get_app(pub).get(sign_uri('/api/forms/test/ics/foobar/foobar2/', user=local_user))
assert resp.body == resp2.body
assert resp.body.count('DTSTART') == 10
assert resp.body.count('DTEND') == 10
def test_api_ics_formdata_http_auth(pub, local_user, ics_data):
role = Role.select()[0]

View File

@ -1609,13 +1609,30 @@ class FormPage(Directory):
# ics/<component> with <component> being the identifier (varname)
# of the field to use as start date (may be a date field or a
# string field).
def _q_lookup(self, component):
# ics/<component>/<component2> with <component2> as the identifier
# of the field to use as end date (ditto, date or string field)
def _q_traverse(self, path):
if not path[-1]:
# allow trailing slash
path = path[:-1]
start_date_field_varname = path[0]
end_date_field_varname = None
if len(path) == 2:
end_date_field_varname = path[1]
elif len(path) > 2:
raise errors.TraversalError()
start_date_field_id = None
end_date_field_id = None
for field in formdef.get_all_fields():
if not getattr(field, 'varname', None) == component:
continue
datefield_field_id = field.id
break
else:
if getattr(field, 'varname', None) == start_date_field_varname:
start_date_field_id = field.id
if end_date_field_varname and getattr(field, 'varname', None) == end_date_field_varname:
end_date_field_id = field.id
if not start_date_field_id:
raise errors.TraversalError()
if end_date_field_varname and not end_date_field_id:
raise errors.TraversalError()
formdatas, total_count = FormDefUI(formdef).get_listing_items(
@ -1624,7 +1641,7 @@ class FormPage(Directory):
cal = vobject.iCalendar()
cal.add('prodid').value = '-//Entr\'ouvert//NON SGML Publik'
for formdata in formdatas:
if not formdata.data.get(datefield_field_id):
if not formdata.data.get(start_date_field_id):
continue
vevent = vobject.newFromBehavior('vevent')
vevent.add('uid').value = '%s-%s-%s' % (
@ -1632,7 +1649,9 @@ class FormPage(Directory):
formdef.url_name,
formdata.id)
vevent.add('summary').value = unicode(formdata.get_display_name(), charset)
vevent.add('dtstart').value = make_datetime(formdata.data[datefield_field_id])
vevent.add('dtstart').value = make_datetime(formdata.data[start_date_field_id])
if end_date_field_id and formdata.data.get(end_date_field_id):
vevent.add('dtend').value = make_datetime(formdata.data[end_date_field_id])
vevent.dtstart.value_param = 'DATE'
backoffice_url = formdata.get_url(backoffice=True)
vevent.add('url').value = backoffice_url