api: add ics export API view (#16797)
This commit is contained in:
parent
78db869ae2
commit
412844fbdd
|
@ -9,7 +9,7 @@ X-Python-Version: 2.7
|
|||
|
||||
Package: wcs
|
||||
Architecture: all
|
||||
Depends: ${python:Depends}, python-quixote, python-scgi, graphviz, python-feedparser, python-imaging
|
||||
Depends: ${python:Depends}, python-quixote, python-scgi, graphviz, python-feedparser, python-imaging, python-vobject
|
||||
Recommends: python-dns, python-xlwt, python-qrcode, libjs-leaflet, python-magic
|
||||
Suggests: libapache2-mod-scgi | libapache-mod-scgi, python-libxml2, python-lasso, python-psycopg2
|
||||
Description: web application to design and set up online forms
|
||||
|
|
|
@ -1445,6 +1445,56 @@ def test_api_geojson_formdata(pub, local_user):
|
|||
formdef.store()
|
||||
resp = get_app(pub).get(sign_uri('/api/forms/test/geojson', user=local_user), status=404)
|
||||
|
||||
def test_api_ics_formdata(pub, local_user):
|
||||
Role.wipe()
|
||||
role = Role(name='test')
|
||||
role.store()
|
||||
|
||||
FormDef.wipe()
|
||||
formdef = FormDef()
|
||||
formdef.name = 'test'
|
||||
formdef.workflow_roles = {'_receiver': role.id}
|
||||
formdef.fields = [
|
||||
fields.StringField(id='0', label='foobar', varname='foobar'),
|
||||
]
|
||||
formdef.store()
|
||||
|
||||
data_class = formdef.data_class()
|
||||
data_class.wipe()
|
||||
|
||||
# check access is denied if the user has not the appropriate role
|
||||
resp = get_app(pub).get(sign_uri('/api/forms/test/ics/foobar', user=local_user), status=403)
|
||||
# even if there's an anonymse parameter
|
||||
resp = get_app(pub).get(sign_uri('/api/forms/test/ics/foobar?anonymise', user=local_user), status=403)
|
||||
|
||||
date = datetime.datetime(2014, 1, 20, 12, 00)
|
||||
for i in range(30):
|
||||
formdata = data_class()
|
||||
formdata.data = {'0': (date + datetime.timedelta(days=i)).strftime('%Y-%m-%d %H:%M')}
|
||||
formdata.user_id = local_user.id
|
||||
formdata.just_created()
|
||||
if i%3 == 0:
|
||||
formdata.jump_status('new')
|
||||
else:
|
||||
formdata.jump_status('finished')
|
||||
formdata.store()
|
||||
|
||||
# add proper role to user
|
||||
local_user.roles = [role.id]
|
||||
local_user.store()
|
||||
|
||||
# check it gets the data
|
||||
resp = get_app(pub).get(sign_uri('/api/forms/test/ics/foobar', user=local_user))
|
||||
assert resp.headers['content-type'] == 'text/calendar; charset=utf-8'
|
||||
assert resp.body.count('BEGIN:VEVENT') == 10
|
||||
|
||||
# check with a filter
|
||||
resp = get_app(pub).get(sign_uri('/api/forms/test/ics/foobar?filter=done', user=local_user))
|
||||
assert resp.body.count('BEGIN:VEVENT') == 20
|
||||
|
||||
# check 404 on erroneous field var
|
||||
resp = get_app(pub).get(sign_uri('/api/forms/test/ics/xxx', user=local_user), status=404)
|
||||
|
||||
def test_roles(pub, local_user):
|
||||
Role.wipe()
|
||||
role = Role(name='Hello World')
|
||||
|
|
|
@ -121,7 +121,6 @@ class ApiFormPage(BackofficeFormPage):
|
|||
# otherwise be accessible if the user is the submitter.
|
||||
self.check_access()
|
||||
|
||||
|
||||
def check_access(self):
|
||||
if 'anonymise' in get_request().form:
|
||||
if not is_url_signed() or (get_request().user and get_request().user.is_admin):
|
||||
|
@ -136,6 +135,9 @@ class ApiFormPage(BackofficeFormPage):
|
|||
raise AccessForbiddenError('unsufficient roles')
|
||||
|
||||
def _q_lookup(self, component):
|
||||
if component == 'ics':
|
||||
return self.ics()
|
||||
|
||||
try:
|
||||
formdata = self.formdef.data_class().get(component)
|
||||
except KeyError:
|
||||
|
|
|
@ -20,6 +20,7 @@ import datetime
|
|||
import json
|
||||
import time
|
||||
import urllib
|
||||
import vobject
|
||||
|
||||
try:
|
||||
import xlwt
|
||||
|
@ -36,6 +37,7 @@ from qommon.admin.menu import command_icon
|
|||
from qommon.backoffice.menu import html_top
|
||||
from qommon.backoffice.listing import pagination_links
|
||||
from qommon import misc, get_logger
|
||||
from qommon.evalutils import make_datetime
|
||||
from qommon.misc import C_, ellipsize
|
||||
from qommon.afterjobs import AfterJob
|
||||
from qommon import emails
|
||||
|
@ -1598,6 +1600,57 @@ class FormPage(Directory):
|
|||
geoloc_key = self.formdef.geolocations.keys()[0]
|
||||
return json.dumps(geojson_formdatas(items, fields=fields))
|
||||
|
||||
def ics(self):
|
||||
if 'anonymise' in get_request().form:
|
||||
# api/ will let this pass but we don't want that.
|
||||
raise errors.AccessForbiddenError()
|
||||
self.check_access()
|
||||
|
||||
formdef = self.formdef
|
||||
selected_filter = self.get_filter_from_query()
|
||||
fields = self.get_fields_from_query()
|
||||
criterias = self.get_criterias_from_query()
|
||||
query = get_request().form.get('q')
|
||||
|
||||
class IcsDirectory(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):
|
||||
for field in formdef.get_all_fields():
|
||||
if not getattr(field, 'varname', None) == component:
|
||||
continue
|
||||
datefield_field_id = field.id
|
||||
break
|
||||
else:
|
||||
raise errors.TraversalError()
|
||||
|
||||
user = get_user_from_api_query_string() or get_request().user
|
||||
|
||||
formdatas, total_count = FormDefUI(formdef).get_listing_items(
|
||||
selected_filter, user=user, query=query, criterias=criterias)
|
||||
|
||||
cal = vobject.iCalendar()
|
||||
cal.add('prodid').value = '-//Entr\'ouvert//NON SGML Publik'
|
||||
for formdata in formdatas:
|
||||
if not formdata.data.get(datefield_field_id):
|
||||
continue
|
||||
vevent = vobject.newFromBehavior('vevent')
|
||||
vevent.add('uid').value = '%s-%s-%s' % (
|
||||
get_request().get_server().lower(),
|
||||
formdef.url_name,
|
||||
formdata.id)
|
||||
vevent.add('summary').value = formdata.get_display_name()
|
||||
vevent.add('dtstart').value = make_datetime(formdata.data[datefield_field_id])
|
||||
vevent.dtstart.value_param = 'DATE'
|
||||
vevent.add('url').value = formdata.get_url(backoffice=True)
|
||||
cal.add(vevent)
|
||||
|
||||
get_response().set_content_type('text/calendar')
|
||||
return cal.serialize()
|
||||
|
||||
return IcsDirectory()
|
||||
|
||||
def map(self):
|
||||
get_response().add_javascript(['qommon.map.js'])
|
||||
html_top('management', '%s - %s' % (_('Form'), self.formdef.name))
|
||||
|
@ -1830,6 +1883,9 @@ class FormPage(Directory):
|
|||
return r.getvalue()
|
||||
|
||||
def _q_lookup(self, component):
|
||||
if component == 'ics':
|
||||
return self.ics()
|
||||
|
||||
try:
|
||||
filled = self.formdef.data_class().get(component)
|
||||
except KeyError:
|
||||
|
|
Loading…
Reference in New Issue