Projet

Général

Profil

0001-mail-templates-add-possibility-to-pre-set-attachment.patch

Frédéric Péters, 08 avril 2020 11:51

Télécharger (9,55 ko)

Voir les différences:

Subject: [PATCH] mail templates: add possibility to pre-set attachments
 (#41319)

 tests/test_mail_templates.py | 65 ++++++++++++++++++++++++++++++++++++
 wcs/admin/mail_templates.py  | 13 +++++++-
 wcs/mail_templates.py        |  2 ++
 wcs/qommon/xml_storage.py    | 10 ++++++
 wcs/workflows.py             | 14 +++++---
 5 files changed, 99 insertions(+), 5 deletions(-)
tests/test_mail_templates.py
7 7
from django.utils.encoding import force_bytes
8 8
from quixote import cleanup
9 9
from wcs.formdef import FormDef
10
from wcs.fields import FileField
10 11
from wcs.logged_errors import LoggedError
11 12
from wcs.mail_templates import MailTemplate
12 13
from wcs.workflows import Workflow, SendmailWorkflowStatusItem
13 14
from wcs.qommon.http_request import HTTPRequest
15
from wcs.qommon.form import PicklableUpload
14 16
from wcs.qommon.ident.password_accounts import PasswordAccount
15 17

  
16 18
from utilities import (get_app, login, create_temporary_pub, clean_temporary_pub)
......
98 100
    resp = resp.click('Edit')
99 101
    resp.form['subject'] = 'edited mail subject'
100 102
    resp.form['body'] = 'edited mail body'
103
    resp.form['attachments$element0'] = 'plop'
104
    resp = resp.form.submit('submit').follow()
105

  
106
    resp = resp.click('Edit')
107
    assert resp.form['subject'].value == 'edited mail subject'
108
    assert resp.form['body'].value == 'edited mail body'
109
    assert resp.form['attachments$element0'].value == 'plop'
101 110
    resp = resp.form.submit('submit').follow()
102 111

  
103 112
    resp = resp.click('Delete')
......
220 229
    assert LoggedError.count() == 1
221 230
    logged_error = LoggedError.select()[0]
222 231
    assert logged_error.summary == 'reference to invalid mail template test-mail-template in status Status1'
232

  
233

  
234
def test_workflow_send_mail_template_attachments(pub, superuser, mail_templates_option, emails):
235
    Workflow.wipe()
236
    MailTemplate.wipe()
237

  
238
    mail_template = MailTemplate(name='test mail template')
239
    mail_template.subject = 'test subject'
240
    mail_template.body = 'test body'
241
    mail_template.attachments = ['form_var_file1_raw']
242
    mail_template.store()
243

  
244
    workflow = Workflow(name='test mail template')
245
    st1 = workflow.add_status('Status1')
246
    item = SendmailWorkflowStatusItem()
247
    item.to = 'xyz@localhost'
248
    item.subject = 'Foobar'
249
    item.body = 'Hello'
250
    item.mail_template = mail_template.slug
251
    st1.items.append(item)
252
    item.parent = st1
253
    workflow.store()
254

  
255
    formdef = FormDef()
256
    formdef.name = 'baz'
257
    formdef.fields = [
258
        FileField(id='1', label='File', type='file', varname='file1'),
259
    ]
260
    formdef.store()
261

  
262
    upload = PicklableUpload('test.jpeg', 'image/jpeg')
263
    jpg = open(os.path.join(os.path.dirname(__file__), 'image-with-gps-data.jpeg'), 'rb').read()
264
    upload.receive([jpg])
265
    formdata = formdef.data_class()()
266
    formdata.data = {'1': upload}
267
    formdata.just_created()
268
    formdata.store()
269
    pub.substitutions.feed(formdata)
270

  
271
    item.perform(formdata)
272
    pub.get_request().response.process_after_jobs()
273
    assert emails.count() == 1
274
    payloads = emails.get('test subject')['msg'].get_payload()
275
    assert len(payloads) == 2
276
    assert payloads[1].get_content_type() == 'image/jpeg'
277

  
278
    # check two files are sent if mail attachments are also defined on the
279
    # action itself.
280
    emails.empty()
281
    item.attachments = ['form_var_file1_raw']
282
    item.perform(formdata)
283
    pub.get_request().response.process_after_jobs()
284
    payloads = emails.get('test subject')['msg'].get_payload()
285
    assert len(payloads) == 3
286
    assert payloads[1].get_content_type() == 'image/jpeg'
287
    assert payloads[2].get_content_type() == 'image/jpeg'
wcs/admin/mail_templates.py
20 20

  
21 21
from wcs.qommon import _, errors, template
22 22
from wcs.qommon.backoffice.menu import html_top
23
from wcs.qommon.form import Form, HtmlWidget, StringWidget, TextWidget, ComputedExpressionWidget
23
from wcs.qommon.form import (Form, HtmlWidget, StringWidget, TextWidget,
24
        ComputedExpressionWidget, WidgetList)
24 25
from wcs.mail_templates import MailTemplate
25 26

  
26 27

  
......
100 101
                    title=_('Identifier'),
101 102
                    required=True, advanced=True,
102 103
                    )
104

  
105
        form.add(WidgetList, 'attachments',
106
                title=_('Attachments (Python expressions)'),
107
                element_type=StringWidget,
108
                value=self.mail_template.attachments,
109
                add_element_label=_('Add attachment'),
110
                element_kwargs={'render_br': False, 'size': 50},
111
                advanced=True)
112

  
103 113
        form.add_submit('submit', _('Submit'))
104 114
        form.add_submit('cancel', _('Cancel'))
105 115
        return form
......
122 132
        self.mail_template.description = form.get_widget('description').parse()
123 133
        self.mail_template.subject = form.get_widget('subject').parse()
124 134
        self.mail_template.body = form.get_widget('body').parse()
135
        self.mail_template.attachments = form.get_widget('attachments').parse()
125 136
        if slug_widget:
126 137
            self.mail_template.slug = slug
127 138
        self.mail_template.store()
wcs/mail_templates.py
27 27
    description = None
28 28
    subject = None
29 29
    body = None
30
    attachments = []
30 31

  
31 32
    # declarations for serialization
32 33
    XML_NODES = [
......
35 36
            ('description', 'str'),
36 37
            ('subject', 'str'),
37 38
            ('body', 'str'),
39
            ('attachments', 'str_list'),
38 40
    ]
39 41

  
40 42
    def __init__(self, name=None):
wcs/qommon/xml_storage.py
67 67
    def export_datetime_to_xml(self, element, attribute_name, charset):
68 68
        element.text = getattr(self, attribute_name).isoformat()
69 69

  
70
    def export_str_list_to_xml(self, element, attribute_name, charset):
71
        for item in getattr(self, attribute_name, None) or []:
72
            ET.SubElement(element, 'item').text = item
73

  
70 74
    def export_to_xml_string(self, include_id=False):
71 75
        x = self.export_to_xml(include_id=include_id)
72 76
        indent_xml(x)
......
116 120

  
117 121
    def import_datetime_from_xml(self, element, charset):
118 122
        return datetime.datetime.strptime(element.text[:19], '%Y-%m-%dT%H:%M:%S')
123

  
124
    def import_str_list_from_xml(self, element, charset):
125
        value = []
126
        for item in element.findall('item'):
127
            value.append(item.text)
128
        return value
wcs/workflows.py
2075 2075
                           (attachment in varnameless))]
2076 2076
        return attachments_options, attachments
2077 2077

  
2078
    def convert_attachments_to_uploads(self):
2078
    def convert_attachments_to_uploads(self, extra_attachments=None):
2079 2079
        uploads = []
2080 2080

  
2081
        if self.attachments:
2081
        attachments = []
2082
        attachments.extend(self.attachments or [])
2083
        attachments.extend(extra_attachments or [])
2084

  
2085
        if attachments:
2082 2086
            global_eval_dict = get_publisher().get_global_eval_dict()
2083 2087
            local_eval_dict = get_publisher().substitutions.get_context_variables()
2084
            for attachment in self.attachments:
2088
            for attachment in attachments:
2085 2089
                if attachment.startswith('form_fbo') and '-' in attachment:
2086 2090
                    # detect varname-less backoffice fields that were set
2087 2091
                    # before #33366 was fixed, and fix them.
......
2563 2567
        url = formdata.get_url()
2564 2568
        body = self.body
2565 2569
        subject = self.subject
2570
        extra_attachments = None
2566 2571
        if self.mail_template:
2567 2572
            mail_template = MailTemplate.get_by_slug(self.mail_template)
2568 2573
            if mail_template:
2569 2574
                body = mail_template.body
2570 2575
                subject = mail_template.subject
2576
                extra_attachments = mail_template.attachments
2571 2577
            else:
2572 2578
                from wcs.logged_errors import LoggedError
2573 2579
                message = _('reference to invalid mail template %(mail_template)s in status %(status)s') % {
......
2647 2653
        if self.custom_from:
2648 2654
            email_from = self.compute(self.custom_from)
2649 2655

  
2650
        attachments = self.convert_attachments_to_uploads()
2656
        attachments = self.convert_attachments_to_uploads(extra_attachments)
2651 2657

  
2652 2658
        if len(addresses) > 1:
2653 2659
            emails.email(mail_subject, mail_body, email_rcpt=None,
2654
-