Projet

Général

Profil

0001-api-expose-ods-as-endpoint-40995.patch

Frédéric Péters, 25 mars 2020 10:04

Télécharger (5,1 ko)

Voir les différences:

Subject: [PATCH] api: expose /ods as endpoint (#40995)

 tests/test_api.py            | 63 +++++++++++++++++++++++++++++++++++-
 wcs/api.py                   |  3 +-
 wcs/backoffice/management.py |  8 +++--
 3 files changed, 70 insertions(+), 4 deletions(-)
tests/test_api.py
13 13
import time
14 14
import json
15 15
import sys
16
import xml.etree.ElementTree as ET
17
import zipfile
16 18

  
17 19
from django.utils.encoding import force_bytes, force_text
18
from django.utils.six import StringIO
20
from django.utils.six import StringIO, BytesIO
19 21
from django.utils.six.moves.urllib import parse as urllib
20 22
from django.utils.six.moves.urllib import parse as urlparse
21 23

  
22 24
from quixote import cleanup, get_publisher
23 25
from wcs.qommon.http_request import HTTPRequest
24 26
from wcs.qommon.form import PicklableUpload
27
from wcs.qommon import ods
25 28
from wcs.users import User
26 29
from wcs.roles import Role
27 30
from wcs.carddef import CardDef
......
1970 1973
    resp = get_app(pub).get(sign_uri('/api/forms/test/geojson', user=local_user), status=404)
1971 1974

  
1972 1975

  
1976
def test_api_ods_formdata(pub, local_user):
1977
    Role.wipe()
1978
    role = Role(name='test')
1979
    role.store()
1980

  
1981
    FormDef.wipe()
1982
    formdef = FormDef()
1983
    formdef.name = 'test'
1984
    formdef.workflow_roles = {'_receiver': role.id}
1985
    formdef.fields = [
1986
        fields.StringField(id='0', label='foobar', varname='foobar', type='string'),
1987
    ]
1988
    formdef.store()
1989

  
1990
    data_class = formdef.data_class()
1991
    data_class.wipe()
1992

  
1993
    # check access is denied if the user has not the appropriate role
1994
    resp = get_app(pub).get(sign_uri('/api/forms/test/ods', user=local_user), status=403)
1995
    # even if there's an anonymise parameter
1996
    resp = get_app(pub).get(sign_uri('/api/forms/test/ods?anonymise', user=local_user), status=403)
1997

  
1998
    data = {'0': 'foobar'}
1999
    for i in range(30):
2000
        formdata = data_class()
2001
        formdata.data = data
2002
        formdata.user_id = local_user.id
2003
        formdata.just_created()
2004
        if i % 3 == 0:
2005
            formdata.jump_status('new')
2006
        else:
2007
            formdata.jump_status('finished')
2008
        formdata.store()
2009

  
2010
    # add proper role to user
2011
    local_user.roles = [role.id]
2012
    local_user.store()
2013

  
2014
    # check it gets the data
2015
    resp = get_app(pub).get(sign_uri('/api/forms/test/ods', user=local_user))
2016
    assert resp.content_type == 'application/vnd.oasis.opendocument.spreadsheet'
2017

  
2018
    # check it still gives a ods file when there is more date
2019
    for i in range(300):
2020
        formdata = data_class()
2021
        formdata.data = data
2022
        formdata.user_id = local_user.id
2023
        formdata.just_created()
2024
        formdata.jump_status('new')
2025
        formdata.store()
2026

  
2027
    resp = get_app(pub).get(sign_uri('/api/forms/test/ods', user=local_user))
2028
    assert resp.content_type == 'application/vnd.oasis.opendocument.spreadsheet'
2029
    zipf = zipfile.ZipFile(BytesIO(resp.body))
2030
    ods_sheet = ET.parse(zipf.open('content.xml'))
2031
    assert len(ods_sheet.findall('.//{%s}table-row' % ods.NS['table'])) == 311
2032

  
2033

  
1973 2034
def test_api_global_geojson(pub, local_user):
1974 2035
    Role.wipe()
1975 2036
    role = Role(name='test')
wcs/api.py
164 164

  
165 165

  
166 166
class ApiFormPage(BackofficeFormPage):
167
    _q_exports = [('list', 'json'), 'geojson'] # restrict to API endpoints
167
    _q_exports = [('list', 'json'), 'geojson', 'ods']  # restrict to API endpoints
168 168
    formdef_class = FormDef
169
    is_api = True
169 170

  
170 171
    def __init__(self, component):
171 172
        try:
wcs/backoffice/management.py
1771 1771

  
1772 1772
    def ods(self):
1773 1773
        self.check_access()
1774
        if 'anonymise' in get_request().form:
1775
            # api/ will let this pass but we don't want that.
1776
            raise errors.AccessForbiddenError()
1774 1777
        fields = self.get_fields_from_query()
1775 1778
        selected_filter = self.get_filter_from_query()
1776
        user = get_request().user
1779
        user = get_user_from_api_query_string() or get_request().user
1777 1780
        query = get_request().form.get('q')
1778 1781
        criterias = self.get_criterias_from_query()
1779 1782

  
......
1814 1817

  
1815 1818
        count = self.formdef.data_class().count()
1816 1819
        exporter = Exporter(self, self.formdef, fields, selected_filter)
1817
        if count > 100: # Arbitrary threshold
1820
        if count > 100 and not getattr(self, 'is_api', False):
1821
            # The "100" threshold is arbitrary
1818 1822
            job = get_response().add_after_job(
1819 1823
                str(N_('Exporting forms in Open Document format')),
1820 1824
                exporter.export)
1821
-