Projet

Général

Profil

0001-emails-ignore-unexpected-title-overlines-or-transiti.patch

Frédéric Péters, 11 janvier 2020 11:07

Télécharger (3,98 ko)

Voir les différences:

Subject: [PATCH] emails: ignore unexpected title overlines or transitions
 (#38817)

 tests/test_misc.py   | 26 ++++++++++++++++++++++++++
 wcs/qommon/emails.py | 27 +++++++++++++++++++++++++--
 2 files changed, 51 insertions(+), 2 deletions(-)
tests/test_misc.py
459 459
    assert b'arabic simple' in html
460 460
    assert b'M. Francis Kuntz' in html
461 461

  
462
@pytest.mark.skipif('docutils is None')
463
def test_email_with_unexpected_transition(emails):
464
    pub = create_temporary_pub()
465
    mail_body = '''
466
Value:
467
 A
468

  
469
Other value:
470
 ?????????
471

  
472
Plop:
473
 C
474

  
475
bye,
476
'''
477
    send_email('test', mail_body=mail_body, email_rcpt='test@localhost')
478
    assert emails.count() == 1
479
    assert emails.emails['test']['msg'].is_multipart()
480
    assert emails.emails['test']['msg'].get_content_subtype() == 'alternative'
481
    assert emails.emails['test']['msg'].get_payload()[0].get_content_type() == 'text/plain'
482
    assert emails.emails['test']['msg'].get_payload()[1].get_content_type() == 'text/html'
483
    text = emails.emails['test']['msg'].get_payload()[0].get_payload(decode=True)
484
    html = emails.emails['test']['msg'].get_payload()[1].get_payload(decode=True)
485
    assert text.count(b'\n ?????????\n') == 1
486
    assert html.count(b'<dd>?????????</dd>') == 1
487

  
462 488
def test_dict_from_prefix():
463 489
    d = evalutils.dict_from_prefix('var1', {})
464 490
    assert d == {}
wcs/qommon/emails.py
60 60

  
61 61

  
62 62
if docutils:
63
    # custom parser to only allow arabic sequences, this prevents the rst
64
    # parser to consider M. as starting a (upper alpha / roman) sequence.
63
    from docutils import statemachine
64

  
65 65
    class Body(docutils.parsers.rst.states.Body):
66 66
        def is_enumerated_list_item(self, ordinal, sequence, format):
67
            # customised to only allow arabic sequences, this prevents the rst
68
            # parser to consider M. as starting a (upper alpha / roman) sequence.
67 69
            if format == 'period' and sequence != 'arabic':
68 70
                return False
69 71
            return docutils.parsers.rst.states.Body.is_enumerated_list_item(
70 72
                    self, ordinal, sequence, format)
71 73

  
74
        def line(self, match, context, next_state):
75
            # customised to ignore unexpected overlines or transitions (due
76
            # for example by a field filled by question marks.
77
            if self.state_machine.match_titles:
78
                return [match.string], 'Line', []
79
            elif match.string.strip() == '::':
80
                raise statemachine.TransitionCorrection('text')
81
            else:
82
                # Unexpected possible title overline or transition.
83
                # Treating it as ordinary text.
84
                raise statemachine.TransitionCorrection('text')
85

  
72 86
    class CustomRstParser(docutils.parsers.rst.Parser):
73 87
        def __init__(self, *args, **kwargs):
74 88
            docutils.parsers.rst.Parser.__init__(self, *args, **kwargs)
75 89
            self.state_classes = tuple([Body] + list(self.state_classes[1:]))
90
            docutils.parsers.rst.states.state_classes = self.state_classes
91

  
92
    def custom_rststate_init(self, state_machine, debug=False):
93
        state_classes = tuple([Body] + list(docutils.parsers.rst.states.state_classes[1:]))
94
        self.nested_sm_kwargs = {'state_classes': state_classes,
95
                                 'initial_state': 'Body'}
96
        docutils.parsers.rst.states.StateWS.__init__(self, state_machine, debug)
97

  
98
    docutils.parsers.rst.states.RSTState.__init__ = custom_rststate_init
76 99

  
77 100

  
78 101
def custom_template_email(key, mail_body_data, email_rcpt, **kwargs):
79
-