Projet

Général

Profil

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

Frédéric Péters, 05 mai 2020 15:27

Télécharger (10,5 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                | 15 ++++++----
 wcs/formdata.py              | 55 +++++++++++++++++-------------------
 wcs/qommon/upload_storage.py | 21 ++++++++------
 5 files changed, 57 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
            out['url'] = self.get_download_url(formdata)
1148 1153
        out['field_id'] = self.id
1149 1154
        return out
1150 1155

  
......
1323 1328
        span.text = od_clean_text(self.get_view_value(value))
1324 1329
        return span
1325 1330

  
1326
    def get_json_value(self, value):
1331
    def get_json_value(self, value, **kwargs):
1327 1332
        try:
1328 1333
            return strftime('%Y-%m-%d', value)
1329 1334
        except TypeError:
......
2406 2411
            return None
2407 2412
        return value
2408 2413

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

  
110 110

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

  
136

  
137 111
class Evolution(object):
138 112
    who = None
139 113
    status = None
......
1018 992
                return field.get_json_value(self.data[field.id])
1019 993
        return None
1020 994

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

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

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

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

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

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

  
86 87
    def can_thumbnail(self):
87 88
        return get_storage_object(getattr(self, 'storage', None)).can_thumbnail(self)
......
136 137
            upload.fp.seek(0)
137 138
            atomic_write(filepath, upload.fp, async_op=False)
138 139

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

  
146 149
    def can_thumbnail(self, upload):
147 150
        return can_thumbnail(upload.content_type)
......
217 220
    def save(self, upload):
218 221
        pass
219 222

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

  
229 234
    def can_thumbnail(self, upload):
230 235
        return False
231
-