Projet

Général

Profil

0001-misc-reference-attachments-using-a-relative-path-217.patch

Frédéric Péters, 01 novembre 2021 09:30

Télécharger (8,9 ko)

Voir les différences:

Subject: [PATCH] misc: reference attachments using a relative path (#21731)

 tests/test_formdata.py     | 35 +++++++++++++++++++++++++++++++++++
 tests/workflow/test_all.py | 18 +++++++++---------
 wcs/workflows.py           | 27 ++++++++++++++++++---------
 3 files changed, 62 insertions(+), 18 deletions(-)
tests/test_formdata.py
1 1
import collections
2 2
import datetime
3
import io
4
import os.path
3 5
import time
4 6
from unittest import mock
5 7

  
......
23 25
from wcs.wf.register_comment import JournalEvolutionPart
24 26
from wcs.wf.wscall import JournalWsCallErrorPart
25 27
from wcs.workflows import (
28
    AttachmentEvolutionPart,
26 29
    Workflow,
27 30
    WorkflowBackofficeFieldsFormDef,
28 31
    WorkflowCriticalityLevel,
......
3183 3186
    formdata.store()
3184 3187
    tmpl = Template('{{ form_var_block|getlist:"foo"|sum }} {{ form_var_block|getlist:"bar"|sum }}')
3185 3188
    assert tmpl.render(context) == '9 2'
3189

  
3190

  
3191
def test_attachment_part_path_migration(pub):
3192
    FormDef.wipe()
3193
    formdef = FormDef()
3194
    formdef.name = 'test'
3195
    formdef.fields = []
3196
    formdef.store()
3197

  
3198
    formdef.data_class().wipe()
3199
    formdata = formdef.data_class()()
3200
    formdata.just_created()
3201
    formdata.status = 'wf-new'
3202
    formdata.evolution[-1].status = 'wf-new'
3203
    formdata.evolution[-1].parts = [
3204
        AttachmentEvolutionPart(
3205
            'hello.txt', fp=io.BytesIO(b'test'), content_type='text/plain', varname='testfile'
3206
        )
3207
    ]
3208
    formdata.store()
3209
    assert formdata.evolution[-1].parts[0].filename.startswith('attachments/')
3210
    assert os.path.exists(formdata.evolution[-1].parts[0].get_file_path())
3211

  
3212
    # add full path as it was done before
3213
    formdata.evolution[-1].parts[0].filename = os.path.join(
3214
        pub.app_dir, formdata.evolution[-1].parts[0].filename
3215
    )
3216
    formdata.store()
3217

  
3218
    # check it was converted to relative path
3219
    formdata = formdef.data_class().get(formdata.id)
3220
    assert formdata.evolution[-1].parts[0].filename.startswith('attachments/')
tests/workflow/test_all.py
3417 3417
    item.perform(formdata)
3418 3418

  
3419 3419
    assert formdata.evolution[-1].parts[-1].base_filename == 'template.odt'
3420
    with zipfile.ZipFile(formdata.evolution[-1].parts[0].filename, mode='r') as zfile:
3420
    with zipfile.ZipFile(formdata.evolution[-1].parts[0].get_file_path(), mode='r') as zfile:
3421 3421
        zinfo = zfile.getinfo('Pictures/10000000000000320000003276E9D46581B55C88.jpg')
3422 3422
    # check the image has been replaced by the one from the formdata
3423 3423
    assert zinfo.file_size == len(image_data)
......
3432 3432

  
3433 3433
        item.perform(formdata)
3434 3434

  
3435
        with zipfile.ZipFile(formdata.evolution[-1].parts[0].filename, mode='r') as zfile:
3435
        with zipfile.ZipFile(formdata.evolution[-1].parts[0].get_file_path(), mode='r') as zfile:
3436 3436
            zinfo = zfile.getinfo('Pictures/10000000000000320000003276E9D46581B55C88.jpg')
3437 3437
        # check the original image has been left
3438 3438
        assert zinfo.file_size == 580
......
3476 3476
    item.perform(formdata)
3477 3477

  
3478 3478
    assert formdata.evolution[-1].parts[-1].base_filename == 'template.odt'
3479
    with zipfile.ZipFile(formdata.evolution[-1].parts[0].filename, mode='r') as zfile:
3479
    with zipfile.ZipFile(formdata.evolution[-1].parts[0].get_file_path(), mode='r') as zfile:
3480 3480
        # base template use a jpg images and export_to_model does not rename it
3481 3481
        # event when content is PNG, but it still works inside LibreOffice
3482 3482
        # which ignores the filename extension.
......
3583 3583
    item.convert_to_pdf = False
3584 3584
    item.perform(formdata)
3585 3585

  
3586
    with open(formdata.evolution[0].parts[0].filename, 'rb') as fd:
3586
    with open(formdata.evolution[0].parts[0].get_file_path(), 'rb') as fd:
3587 3587
        with zipfile.ZipFile(fd) as zout:
3588 3588
            new_content = zout.read('content.xml')
3589 3589
    assert b'>foo-export-to-template-with-django<' in new_content
......
3592 3592
    formdef.store()
3593 3593
    item.perform(formdata)
3594 3594

  
3595
    with open(formdata.evolution[0].parts[1].filename, 'rb') as fd:
3595
    with open(formdata.evolution[0].parts[1].get_file_path(), 'rb') as fd:
3596 3596
        with zipfile.ZipFile(fd) as zout:
3597 3597
            new_content = zout.read('content.xml')
3598 3598
    assert b'>Name with a \' simple quote<' in new_content
......
3601 3601
    formdef.store()
3602 3602
    item.perform(formdata)
3603 3603

  
3604
    with open(formdata.evolution[0].parts[2].filename, 'rb') as fd:
3604
    with open(formdata.evolution[0].parts[2].get_file_path(), 'rb') as fd:
3605 3605
        with zipfile.ZipFile(fd) as zout:
3606 3606
            new_content = zout.read('content.xml')
3607 3607
    assert b'>A &lt;&gt; name<' in new_content
......
3639 3639
        pub.substitutions.reset()
3640 3640
        pub.substitutions.feed(formdata)
3641 3641
        item.perform(formdata)
3642
        with open(formdata.evolution[0].parts[-1].filename) as fd:
3642
        with open(formdata.evolution[0].parts[-1].get_file_path()) as fd:
3643 3643
            return fd.read()
3644 3644

  
3645 3645
    # good XML
......
3738 3738
    item.convert_to_pdf = False
3739 3739
    item.perform(formdata)
3740 3740

  
3741
    with open(formdata.evolution[0].parts[0].filename, 'rb') as fd:
3741
    with open(formdata.evolution[0].parts[0].get_file_path(), 'rb') as fd:
3742 3742
        with zipfile.ZipFile(fd) as zout:
3743 3743
            new_content = force_text(zout.read('content.xml'))
3744 3744
    # section content has been removed
......
3762 3762
    assert 'XfooY, Xfoo2Y' in new_content
3763 3763

  
3764 3764
    if filename == 'template-form-details-no-styles.odt':
3765
        with open(formdata.evolution[0].parts[0].filename, 'rb') as fd:
3765
        with open(formdata.evolution[0].parts[0].get_file_path(), 'rb') as fd:
3766 3766
            with zipfile.ZipFile(fd) as zout:
3767 3767
                new_styles = force_text(zout.read('styles.xml'))
3768 3768
        assert 'Field_20_Label' in new_styles
wcs/workflows.py
258 258
            to=to,
259 259
        )
260 260

  
261
    def get_file_path(self):
262
        if os.path.isabs(self.filename):
263
            return self.filename
264
        else:
265
            return os.path.join(get_publisher().app_dir, self.filename)
266

  
261 267
    def get_file_pointer(self):
262 268
        if self.filename.startswith('uuid-'):
263 269
            return None
264
        return open(self.filename, 'rb')  # pylint: disable=consider-using-with
270
        return open(self.get_file_path(), 'rb')  # pylint: disable=consider-using-with
265 271

  
266 272
    def __getstate__(self):
267 273
        odict = self.__dict__.copy()
......
274 280
            return odict
275 281

  
276 282
        del odict['fp']
277
        dirname = os.path.join(get_publisher().app_dir, 'attachments')
278
        if not os.path.exists(dirname):
279
            os.mkdir(dirname)
280 283

  
281
        # there is not filename, or it was a temporary one: create it
284
        # there is no filename, or it was a temporary one: create it
282 285
        if 'filename' not in odict or odict['filename'].startswith('uuid-'):
283 286
            filename = file_digest(self.fp)
284
            dirname = os.path.join(dirname, filename[:4])
285
            if not os.path.exists(dirname):
286
                os.mkdir(dirname)
287
            # create subdirectory with digest prefix as name
288
            dirname = os.path.join('attachments', filename[:4])
289
            os.makedirs(os.path.join(get_publisher().app_dir, dirname), exist_ok=True)
287 290
            odict['filename'] = os.path.join(dirname, filename)
288 291
            self.filename = odict['filename']
289 292
            self.fp.seek(0)
290
            atomic_write(self.filename, self.fp)
293
            atomic_write(self.get_file_path(), self.fp)
294
        elif os.path.isabs(odict['filename']):
295
            # current value is an absolute path, update it quietly to be a relative path
296
            pub_app_path_prefix = os.path.join(get_publisher().app_dir, '')
297
            if os.path.exists(odict['filename']) and odict['filename'].startswith(pub_app_path_prefix):
298
                odict['filename'] = odict['filename'][len(pub_app_path_prefix) :]
299

  
291 300
        return odict
292 301

  
293 302
    def view(self):
294
-