From 5dacfa58a273ad68f768264bbff5020a7d18ebf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Tue, 28 Nov 2017 10:28:19 +0100 Subject: [PATCH] api: add possibility to get drafts from /api/user/forms endpoint (#20230) --- help/fr/api-user.page | 11 +++------ tests/test_api.py | 25 +++++++++++++++++++ wcs/api.py | 66 +++++++++++++++++++++------------------------------ 3 files changed, 55 insertions(+), 47 deletions(-) diff --git a/help/fr/api-user.page b/help/fr/api-user.page index 10c6bc4a..c4c0f156 100644 --- a/help/fr/api-user.page +++ b/help/fr/api-user.page @@ -128,15 +128,10 @@ l'adresse /user.

Il est possible de recevoir un ensemble plus complet de données en passant un -paramètre full=on à l'adresse. +paramètre full=on à l'adresse. Pour inclure également les +brouillons, un paramètre include-drafts=true peut être passé.

- -

Note de compatibilité : cette information est également disponible à -l'adresse /myspace/forms. -

-
-
Brouillons @@ -147,7 +142,7 @@ l'adresse /myspace/forms.

-$ curl https://www.example.net/myspace/drafts +$ curl https://www.example.net/api/user/drafts [ { "datetime": "2014-07-21 10:15:21", diff --git a/tests/test_api.py b/tests/test_api.py index 14a36c7d..cecedd54 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1096,6 +1096,8 @@ def test_user_forms(pub, local_user): fields.StringField(id='0', label='foobar', varname='foobar'), fields.StringField(id='1', label='foobar2'),] formdef.keywords = 'hello, world' + formdef.disabled = False + formdef.enable_tracking_codes = True formdef.store() formdef.data_class().wipe() @@ -1130,6 +1132,27 @@ def test_user_forms(pub, local_user): resp = get_app(pub).get(sign_uri('/api/user/forms', user=local_user)) assert len(resp.json) == 1 + formdata = formdef.data_class()() + formdata.user_id = local_user.id + formdata.status = 'draft' + formdata.receipt_time = datetime.datetime(2015, 1, 1).timetuple() + formdata.store() + + resp = get_app(pub).get(sign_uri('/api/user/forms', user=local_user)) + assert len(resp.json) == 1 + + resp = get_app(pub).get(sign_uri('/api/user/forms?include-drafts=true', user=local_user)) + assert len(resp.json) == 1 + + formdef.disabled = False + formdef.store() + + resp = get_app(pub).get(sign_uri('/api/user/forms?include-drafts=true', user=local_user)) + assert len(resp.json) == 2 + + draft_formdata = [x for x in resp.json if x['status'] == 'Draft'][0] + assert draft_formdata.get('url')[-1] != '/' + def test_user_drafts(pub, local_user): FormDef.wipe() formdef = FormDef() @@ -1143,6 +1166,8 @@ def test_user_drafts(pub, local_user): formdef.enable_tracking_codes = True formdef.store() + formdef.data_class().wipe() + resp = get_app(pub).get(sign_uri('/api/user/drafts', user=local_user)) assert len(resp.json) == 0 diff --git a/wcs/api.py b/wcs/api.py index ac06fafb..8c82ab53 100644 --- a/wcs/api.py +++ b/wcs/api.py @@ -24,6 +24,7 @@ from quixote.directory import Directory from qommon import _ from qommon import misc +from qommon.evalutils import make_datetime from qommon.errors import (AccessForbiddenError, QueryError, TraversalError, UnknownNameIdAccessForbiddenError) from qommon.form import ValidationError, ComputedExpressionWidget @@ -67,7 +68,7 @@ def posted_json_data_to_formdata_data(formdef, data): def get_formdata_dict(formdata, user, consider_status_visibility=True): - if consider_status_visibility: + if consider_status_visibility and not formdata.is_draft(): status = formdata.get_visible_status(user=user) if not status: # skip hidden forms @@ -75,21 +76,29 @@ def get_formdata_dict(formdata, user, consider_status_visibility=True): else: status = formdata.get_status() - title = _('%(name)s #%(id)s (%(status)s)') % { - 'name': formdata.formdef.name, - 'id': formdata.get_display_id(), - 'status': status.name, - } - d = {'title': title, + d = { 'name': formdata.formdef.name, 'url': formdata.get_url(), 'datetime': misc.strftime('%Y-%m-%d %H:%M:%S', formdata.receipt_time), - 'status': status.name, - 'status_css_class': status.extra_css_class, + 'status': status.name if not formdata.is_draft() else _('Draft'), + 'status_css_class': status.extra_css_class if status else None, 'keywords': formdata.formdef.keywords_list, + 'draft': formdata.is_draft(), } if formdata.last_update_time: d['last_update_time'] = misc.strftime('%Y-%m-%d %H:%M:%S', formdata.last_update_time) + + if formdata.is_draft(): + d['url'] = d['url'].rstrip('/') + d['form_number_raw'] = d['form_number'] = None + d['title'] = _('%(name)s (draft)') % {'name': formdata.formdef.name} + else: + d['title'] = _('%(name)s #%(id)s (%(status)s)') % { + 'name': formdata.formdef.name, + 'id': formdata.get_display_id(), + 'status': status.name, + } + d.update(formdata.get_substitution_variables(minimal=True)) if get_request().form.get('full') == 'on': d.update(formdata.get_json_export_dict(include_files=False)) @@ -520,44 +529,23 @@ class ApiUserDirectory(Directory): return user_forms def drafts(self): - get_response().set_content_type('application/json') - user = self.user or get_user_from_api_query_string() or get_request().user - if not user: - raise AccessForbiddenError('no user specified') - drafts = [] - for form in self.get_user_forms(user): - if not form.is_draft(): - continue - if form.formdef.is_disabled() or not form.formdef.enable_tracking_codes: - continue - title = _('%(name)s, draft saved on %(datetime)s') % { - 'name': form.formdef.name, - 'datetime': misc.localstrftime(form.receipt_time) - } - # !!! no trailing slash in the special draft case - url = form.get_url().rstrip('/') - d = {'title': title, - 'name': form.formdef.name, - 'url': url, - 'datetime': misc.strftime('%Y-%m-%d %H:%M:%S', form.receipt_time), - 'keywords': form.formdef.keywords_list, - } - if get_request().form.get('full') == 'on': - d.update(form.get_json_export_dict(include_files=False)) - drafts.append(d) - - return json.dumps(drafts, - cls=misc.JSONEncoder, - encoding=get_publisher().site_charset) + return self.forms(include_drafts=True, include_non_drafts=False) - def forms(self): + def forms(self, include_drafts=False, include_non_drafts=True): get_response().set_content_type('application/json') user = self.user or get_user_from_api_query_string() or get_request().user if not user: raise AccessForbiddenError('no user specified') forms = [] + include_drafts = include_drafts or get_request().form.get('include-drafts') == 'true' for form in self.get_user_forms(user): if form.is_draft(): + if not include_drafts: + continue + if form.formdef.is_disabled() or not form.formdef.enable_tracking_codes: + # the form or its draft support has been disabled + continue + elif not include_non_drafts: continue formdata_dict = get_formdata_dict(form, user) if not formdata_dict: -- 2.15.1