Projet

Général

Profil

0001-api-include-file-info-in-list-API-42371.patch

Frédéric Péters, 01 mai 2020 17:41

Télécharger (10,6 ko)

Voir les différences:

Subject: [PATCH] api: include file info in list API (#42371)

 help/fr/api-get.page         |  7 +++--
 tests/test_api.py            |  6 ++--
 wcs/fields.py                | 18 ++++++++----
 wcs/formdata.py              | 55 +++++++++++++++++-------------------
 wcs/qommon/upload_storage.py | 21 ++++++++------
 5 files changed, 60 insertions(+), 47 deletions(-)
help/fr/api-get.page
238 238
        "photo": {
239 239
            "filename": "exemple.txt",
240 240
            "content_type": "text/plain",
241
            "content": "Q2VjaSBuJ2VzdCBwYXMgdW4gZXhlbXBsZS4="
241
            "content": "Q2VjaSBuJ2VzdCBwYXMgdW4gZXhlbXBsZS4=",
242
            "url": "https://.../"
242 243
        }
243 244
    },
244 245
    (...)
......
333 334
</screen>
334 335

  
335 336
<p>
336
À noter que pour ne pas alourdir l'export en mode <code>full=on</code>, les
337
champs de type « Fichier » ne sont pas exportés.
337
À noter que pour ne pas alourdir l'export en mode <code>full=on</code>, le
338
contenu des champs de type « Fichier » n'est pas exporté.
338 339
</p>
339 340

  
340 341
</section>
tests/test_api.py
1633 1633
    assert resp.json['err'] == 0
1634 1634
    assert 'fields' in resp.json['data'][0]
1635 1635
    assert resp.json['data'][0]['fields']['foobar'] == 'foo@localhost'
1636
    assert 'file' not in resp.json['data'][0]['fields']  # no file export in full lists
1636
    assert 'url' in resp.json['data'][0]['fields']['file']
1637
    assert 'content' not in resp.json['data'][0]['fields']['file']  # no file content in full lists
1637 1638
    assert resp.json['data'][0]['keywords'] == ['hello', 'world']
1638 1639

  
1639 1640
    formdef.enable_tracking_codes = False
......
1724 1725
    assert len(resp.json) == 30
1725 1726
    assert 'receipt_time' in resp.json[0]
1726 1727
    assert 'fields' in resp.json[0]
1727
    assert 'file' not in resp.json[0]['fields'] # no file export in full lists
1728
    assert 'url' in resp.json[0]['fields']['file']
1729
    assert 'content' not in resp.json[0]['fields']['file']  # no file content in full lists
1728 1730
    assert 'user' in resp.json[0]
1729 1731
    assert 'evolution' in resp.json[0]
1730 1732
    assert len(resp.json[0]['evolution']) == 2
wcs/fields.py
1127 1127
        t += htmltext('</div>')
1128 1128
        return t.getvalue()
1129 1129

  
1130
    def get_download_url(self, formdata):
1131
        return '%sdownload?f=%s' % (formdata.get_url(), self.id)
1132

  
1130 1133
    def get_opendocument_node_value(self, value, formdata=None, **kwargs):
1131 1134
        show_link = True
1132 1135
        if value.has_redirect_url():
......
1134 1137
            show_link = bool(value.get_redirect_url(backoffice=is_in_backoffice))
1135 1138
        if show_link and formdata:
1136 1139
            node = ET.Element('{%s}a' % OD_NS['text'])
1137
            node.attrib['{%s}href' % OD_NS['xlink']] = '%sdownload?f=%s' % (formdata.get_url(), self.id)
1140
            node.attrib['{%s}href' % OD_NS['xlink']] = self.get_download_url(formdata)
1138 1141
        else:
1139 1142
            node = ET.Element('{%s}span' % OD_NS['text'])
1140 1143
        node.text = od_clean_text(force_text(value))
......
1143 1146
    def get_csv_value(self, value, **kwargs):
1144 1147
        return [str(value) if value else '']
1145 1148

  
1146
    def get_json_value(self, value):
1147
        out = value.get_json_value()
1149
    def get_json_value(self, value, formdata=None, include_file_content=True, **kwargs):
1150
        out = value.get_json_value(include_file_content=include_file_content)
1151
        if formdata:
1152
            if value.has_redirect_url():
1153
                out['url'] = value.get_redirect_url()
1154
            else:
1155
                out['url'] = self.get_download_url(formdata)
1148 1156
        out['field_id'] = self.id
1149 1157
        return out
1150 1158

  
......
1323 1331
        span.text = od_clean_text(self.get_view_value(value))
1324 1332
        return span
1325 1333

  
1326
    def get_json_value(self, value):
1334
    def get_json_value(self, value, **kwargs):
1327 1335
        try:
1328 1336
            return strftime('%Y-%m-%d', value)
1329 1337
        except TypeError:
......
2406 2414
            return None
2407 2415
        return value
2408 2416

  
2409
    def get_json_value(self, value):
2417
    def get_json_value(self, value, **kwargs):
2410 2418
        if not value or ';' not in value:
2411 2419
            return None
2412 2420
        lat, lon = value.split(';')
wcs/formdata.py
107 107
            del d[k]
108 108

  
109 109

  
110
def get_json_dict(fields, data, include_files=True, anonymise=False):
111
    new_data = {}
112
    for field in fields:
113
        if anonymise and field.anonymise:
114
            continue
115
        if not field.varname: # exports only named fields
116
            continue
117
        if not include_files and isinstance(field, FileField):
118
            continue
119
        if data is not None:
120
            value = data.get(field.id)
121
            if value and hasattr(field, 'get_json_value'):
122
                value = field.get_json_value(value)
123
        else:
124
            value = display_value = None
125
        if field.store_display_value:
126
            new_data[field.varname + '_raw'] = value
127
            new_data[field.varname] = data.get('%s_display' % field.id)
128
        else:
129
            new_data[field.varname] = value
130
        if field.store_structured_value:
131
            if data.get('%s_structured' % field.id):
132
                new_data[field.varname + '_structured'] = data.get('%s_structured' % field.id)
133
    return new_data
134

  
135

  
136 110
class Evolution(object):
137 111
    who = None
138 112
    status = None
......
1017 991
                return field.get_json_value(self.data[field.id])
1018 992
        return None
1019 993

  
994
    def get_json_dict(self, fields, include_files=True, anonymise=False):
995
        new_data = {}
996
        for field in fields:
997
            if anonymise and field.anonymise:
998
                continue
999
            if not field.varname:  # exports only named fields
1000
                continue
1001
            if self.data is not None:
1002
                value = self.data.get(field.id)
1003
                if value and hasattr(field, 'get_json_value'):
1004
                    value = field.get_json_value(value, formdata=self, include_file_content=include_files)
1005
            else:
1006
                value = None
1007
            if field.store_display_value:
1008
                new_data[field.varname + '_raw'] = value
1009
                new_data[field.varname] = self.data.get('%s_display' % field.id)
1010
            else:
1011
                new_data[field.varname] = value
1012
            if field.store_structured_value:
1013
                if self.data.get('%s_structured' % field.id):
1014
                    new_data[field.varname + '_structured'] = self.data.get('%s_structured' % field.id)
1015
        return new_data
1016

  
1020 1017
    def get_json_export_dict(self, include_files=True, anonymise=False, user=None):
1021 1018
        data = {}
1022 1019
        data['id'] = str(self.id)
......
1037 1034
            if user:
1038 1035
                data['user'] = user.get_json_export_dict()
1039 1036

  
1040
        data['fields'] = get_json_dict(self.formdef.fields, self.data,
1037
        data['fields'] = self.get_json_dict(self.formdef.fields,
1041 1038
                include_files=include_files, anonymise=anonymise)
1042 1039

  
1043 1040
        data['workflow'] = {}
......
1048 1045
        if self.workflow_data and not anonymise:
1049 1046
            data['workflow']['data'] = self.workflow_data
1050 1047
        if self.formdef.workflow.get_backoffice_fields():
1051
            data['workflow']['fields'] = get_json_dict(
1048
            data['workflow']['fields'] = self.get_json_dict(
1052 1049
                    self.formdef.workflow.get_backoffice_fields(),
1053
                    self.data, include_files=include_files, anonymise=anonymise)
1050
                    include_files=include_files, anonymise=anonymise)
1054 1051

  
1055 1052
        # add a roles dictionary, with workflow functions and two special
1056 1053
        # entries for concerned/actions roles.
wcs/qommon/upload_storage.py
78 78
            return base64.encodestring(content)
79 79
        return b''
80 80

  
81
    def get_json_value(self):
82
        return get_storage_object(getattr(self, 'storage', None)).get_json_value(self)
81
    def get_json_value(self, include_file_content=True):
82
        return get_storage_object(getattr(self, 'storage', None)).get_json_value(
83
                self, include_file_content=include_file_content)
83 84

  
84 85
    def can_thumbnail(self):
85 86
        return get_storage_object(getattr(self, 'storage', None)).can_thumbnail(self)
......
134 135
            upload.fp.seek(0)
135 136
            atomic_write(filepath, upload.fp, async_op=False)
136 137

  
137
    def get_json_value(self, upload):
138
        return {
138
    def get_json_value(self, upload, include_file_content=True):
139
        value = {
139 140
            'filename': upload.base_filename,
140 141
            'content_type': upload.content_type or 'application/octet-stream',
141
            'content': force_text(base64.b64encode(upload.get_content())),
142 142
        }
143
        if include_file_content:
144
            value['content'] = force_text(base64.b64encode(upload.get_content()))
145
        return value
143 146

  
144 147
    def can_thumbnail(self, upload):
145 148
        return can_thumbnail(upload.content_type)
......
215 218
    def save(self, upload):
216 219
        pass
217 220

  
218
    def get_json_value(self, upload):
219
        return {
221
    def get_json_value(self, upload, include_file_content=True):
222
        value = {
220 223
            'filename': upload.base_filename,
221 224
            'content_type': upload.content_type or 'application/octet-stream',
222
            'content': '',
223 225
            'storage': upload.storage,
224 226
            'storage_attrs': upload.storage_attrs,
225 227
        }
228
        if include_file_content:  # actually not possible
229
            value['content'] = ''
230
        return value
226 231

  
227 232
    def can_thumbnail(self, upload):
228 233
        return False
229
-