From fa7f9ff286d3a00ab30c6ef3677a31a72a696bed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Sun, 8 Nov 2015 14:26:40 +0100 Subject: [PATCH] backoffice: add jsonp endpoints to get various counters (#8915) --- tests/test_backoffice_pages.py | 72 ++++++++++++++++++++++++++++++++++++++++++ wcs/backoffice/management.py | 30 ++++++++++++------ wcs/backoffice/root.py | 13 +------- wcs/backoffice/submission.py | 31 +++++++++++++++--- wcs/qommon/misc.py | 17 +++++++++- 5 files changed, 135 insertions(+), 28 deletions(-) diff --git a/tests/test_backoffice_pages.py b/tests/test_backoffice_pages.py index e8bba14..a28fb05 100644 --- a/tests/test_backoffice_pages.py +++ b/tests/test_backoffice_pages.py @@ -66,6 +66,7 @@ def create_superuser(pub): create_user(pub, is_admin=True) def create_environment(pub, set_receiver=True): + Workflow.wipe() Category.wipe() FormDef.wipe() formdef = FormDef() @@ -1005,3 +1006,74 @@ def test_backoffice_sidebar_user_context(pub): assert '>cat1<' in resp.body assert '>Misc<' in resp.body assert resp.body.index('>Misc<') < resp.body.index('>cat1<') + +def test_count_open(pub): + if not pub.is_using_postgresql(): + pytest.skip('this requires SQL') + return + create_user(pub) + create_environment(pub) + resp = login(get_app(pub)).get('/backoffice/management/count') + assert resp.json['count'] == 37 + + formdef = FormDef.get_by_urlname('form-title') + formdef.workflow_roles = {'_receiver': 2} # role the user doesn't have + formdef.store() + formdef.data_class().rebuild_security() + resp = login(get_app(pub)).get('/backoffice/management/count') + assert resp.json['count'] == 20 + + formdef = FormDef.get_by_urlname('form-title') + formdef.workflow_roles = {'_receiver': 2, '_foobar': 1} + formdef.store() + formdef.data_class().rebuild_security() + resp = login(get_app(pub)).get('/backoffice/management/count') + assert resp.json['count'] == 20 + resp = login(get_app(pub)).get('/backoffice/management/count?waiting=yes') + assert resp.json['count'] == 20 + + formdef = FormDef.get_by_urlname('form-title') + workflow = Workflow.get_default_workflow() + workflow.roles['_foobar'] = 'Foobar' + workflow.id = '2' + workflow.store() + formdef.workflow_id = workflow.id + formdef.workflow_roles = {'_receiver': 2, '_foobar': '1'} + formdef.store() + formdef.data_class().rebuild_security() + resp = login(get_app(pub)).get('/backoffice/management/count?waiting=no') + assert resp.json['count'] == 37 + +def test_count_backoffice_drafts(pub): + user = create_user(pub) + create_environment(pub) + + formdef = FormDef.get_by_urlname('form-title') + formdef.backoffice_submission_roles = user.roles[:] + formdef.store() + + resp = login(get_app(pub)).get('/backoffice/submission/count') + assert resp.json['count'] == 0 + + formdata1, formdata2, formdata3 = formdef.data_class().select()[:3] + for formdata in (formdata1, formdata2, formdata3): + formdata.status = 'draft' + formdata.store() + + resp = login(get_app(pub)).get('/backoffice/submission/count') + assert resp.json['count'] == 0 + + for formdata in (formdata1, formdata2, formdata3): + formdata.backoffice_submission = True + formdata.store() + + resp = login(get_app(pub)).get('/backoffice/submission/count') + assert resp.json['count'] == 3 + + formdata1.data = {} + formdata1.store() + + resp = login(get_app(pub)).get('/backoffice/submission/count?mode=empty') + assert resp.json['count'] == 1 + resp = login(get_app(pub)).get('/backoffice/submission/count?mode=existing') + assert resp.json['count'] == 2 diff --git a/wcs/backoffice/management.py b/wcs/backoffice/management.py index ff67d3e..84bfbbc 100644 --- a/wcs/backoffice/management.py +++ b/wcs/backoffice/management.py @@ -47,7 +47,7 @@ from wcs.roles import logged_users_role class ManagementDirectory(Directory): - _q_exports = ['', 'listing', 'statistics', 'code'] + _q_exports = ['', 'listing', 'statistics', 'code', 'count'] def is_accessible(self, user): return user.can_go_in_backoffice() @@ -309,6 +309,17 @@ class ManagementDirectory(Directory): r += htmltext('') return r.getvalue() + def get_global_listing_criterias(self): + parsed_values = {} + user_roles = [logged_users_role().id] + (get_request().user.roles or []) + criterias = get_global_criteria(get_request(), parsed_values) + criterias.append(Equal('is_at_endpoint', False)) + if not get_request().form or get_request().form.get('waiting') == 'yes': + criterias.append(Intersects('actions_roles_array', user_roles)) + else: + criterias.append(Intersects('concerned_roles_array', user_roles)) + return criterias + def listing(self): if not get_publisher().is_using_postgresql(): raise errors.TraversalError() @@ -318,19 +329,11 @@ class ManagementDirectory(Directory): from wcs import sql html_top('management', _('Management')) - user_roles = [logged_users_role().id] + (get_request().user.roles or []) - limit = int(get_request().form.get('limit', get_publisher().get_site_option('default-page-size') or 20)) offset = int(get_request().form.get('offset', 0)) - parsed_values = {} - criterias = get_global_criteria(get_request(), parsed_values) - criterias.append(Equal('is_at_endpoint', False)) - if not get_request().form or get_request().form.get('waiting') == 'yes': - criterias.append(Intersects('actions_roles_array', user_roles)) - else: - criterias.append(Intersects('concerned_roles_array', user_roles)) + criterias = self.get_global_listing_criterias() total_count = sql.AnyFormData.count(criterias) formdatas = sql.AnyFormData.select(criterias, order_by='receipt_time', limit=limit, offset=offset) @@ -395,6 +398,13 @@ class ManagementDirectory(Directory): r = rt return rt.getvalue() + def count(self): + if not get_publisher().is_using_postgresql(): + raise errors.TraversalError() + from wcs import sql + criterias = self.get_global_listing_criterias() + count = sql.AnyFormData.count(criterias) + return misc.json_response({'count': count}) def _q_lookup(self, component): return FormPage(component) diff --git a/wcs/backoffice/root.py b/wcs/backoffice/root.py index e3cd8ab..3ef102e 100644 --- a/wcs/backoffice/root.py +++ b/wcs/backoffice/root.py @@ -212,20 +212,9 @@ class RootDirectory(BackofficeRootDirectory): return r.getvalue() def menu_json(self): - get_response().set_content_type('application/json') - if get_request().get_environ('HTTP_ORIGIN'): - get_response().set_header('Access-Control-Allow-Origin', - get_request().get_environ('HTTP_ORIGIN')) - get_response().set_header('Access-Control-Allow-Credentials', 'true') - get_response().set_header('Access-Control-Allow-Headers', 'x-requested-with') menu_items = [] backoffice_url = get_publisher().get_backoffice_url() - json_str = json.dumps(self.get_menu_items()) - for variable in ('jsonpCallback', 'callback'): - if variable in get_request().form: - json_str = '%s(%s);' % (get_request().form[variable], json_str) - break - return json_str + return misc.json_response(self.get_menu_items()) def pending(self): # kept as a redirection for compatibility with possible bookmarks diff --git a/wcs/backoffice/submission.py b/wcs/backoffice/submission.py index f0004ff..64586b8 100644 --- a/wcs/backoffice/submission.py +++ b/wcs/backoffice/submission.py @@ -99,7 +99,7 @@ class FormFillPage(PublicFormFillPage): class SubmissionDirectory(Directory): - _q_exports = [''] + _q_exports = ['', 'count'] def is_accessible(self, user): if not user.can_go_in_backoffice(): @@ -111,9 +111,7 @@ class SubmissionDirectory(Directory): return True return False - def _q_index(self): - get_response().breadcrumb.append(('submission/', _('Submission'))) - html_top('submission', _('Submission')) + def get_submittable_formdefs(self): user = get_request().user list_forms = [] @@ -129,8 +127,13 @@ class SubmissionDirectory(Directory): continue list_forms.append(formdef) - r = TemplateIO(html=True) + return list_forms + + def _q_index(self): + get_response().breadcrumb.append(('submission/', _('Submission'))) + html_top('submission', _('Submission')) + list_forms = self.get_submittable_formdefs() cats = Category.select() Category.sort_by_position(cats) for cat in cats: @@ -139,6 +142,7 @@ class SubmissionDirectory(Directory): misc_cat.formdefs = [x for x in list_forms if not x.category] cats.append(misc_cat) + r = TemplateIO(html=True) for mode in ['create', 'existing', 'empty']: list_content = TemplateIO() for cat in cats: @@ -216,6 +220,23 @@ class SubmissionDirectory(Directory): return r.getvalue() + def count(self): + formdefs = self.get_submittable_formdefs() + count = 0 + mode = get_request().form.get('mode') + for formdef in formdefs: + if not hasattr(formdef, '_formdatas'): + data_class = formdef.data_class() + formdata_ids = data_class.get_ids_with_indexed_value('status', 'draft') + formdatas = [x for x in data_class.get_ids(formdata_ids) + if x.backoffice_submission is True] + if mode == 'empty': + formdatas = [x for x in formdatas if x.has_empty_data()] + elif mode == 'existing': + formdatas = [x for x in formdatas if not x.has_empty_data()] + count += len(formdatas) + return misc.json_response({'count': count}) + def _q_lookup(self, component): get_response().breadcrumb.append(('submission/', _('Submission'))) return FormFillPage(component) diff --git a/wcs/qommon/misc.py b/wcs/qommon/misc.py index 79bde9c..06ec38c 100644 --- a/wcs/qommon/misc.py +++ b/wcs/qommon/misc.py @@ -27,7 +27,7 @@ import subprocess import tempfile import unicodedata -from quixote import get_publisher, get_session, get_response +from quixote import get_publisher, get_session, get_response, get_request from quixote.html import htmltext from qommon import get_cfg, get_logger, ezt @@ -440,3 +440,18 @@ def decorate_as_pdf(content): os.unlink(tmpfile.name + '.pdf') os.unlink(tmpfile.name) return pdf_content + +def json_response(data): + get_response().set_content_type('application/json') + if get_request().get_environ('HTTP_ORIGIN'): + get_response().set_header('Access-Control-Allow-Origin', + get_request().get_environ('HTTP_ORIGIN')) + get_response().set_header('Access-Control-Allow-Credentials', 'true') + get_response().set_header('Access-Control-Allow-Headers', 'x-requested-with') + json_str = json.dumps(data) + for variable in ('jsonpCallback', 'callback'): + if variable in get_request().form: + get_response().set_content_type('application/javascript') + json_str = '%s(%s);' % (get_request().form[variable], json_str) + break + return json_str -- 2.6.2