Barry Warsaw pushed to branch release-3.0 at mailman / Mailman

Commits:
a382ab7d by Aurélien Bompard at 2015-09-23T21:37:32Z
Fix the logging of the moderation reasons.

- - - - -


6 changed files:

- src/mailman/chains/hold.py
- src/mailman/chains/tests/test_hold.py
- src/mailman/core/docs/chains.rst
- src/mailman/docs/NEWS.rst
- src/mailman/templates/en/postauth.txt
- src/mailman/templates/en/postheld.txt


Changes:

=====================================
src/mailman/chains/hold.py
=====================================
--- a/src/mailman/chains/hold.py
+++ b/src/mailman/chains/hold.py
@@ -44,9 +44,12 @@ from zope.component import getUtility
 from zope.event import notify
 from zope.interface import implementer
 
+SEMISPACE = '; '
+SPACE = ' '
+NL = '\n'
+
 
 log = logging.getLogger('mailman.vette')
-SEMISPACE = '; '
 
 
 
@@ -56,6 +59,15 @@ class HeldMessagePendable(dict):
 
 
 
+def _compose_reasons(msgdata, column=66):
+    # Rules can add reasons to the metadata.
+    reasons = msgdata.get('moderation_reasons', [_('N/A')])
+    return NL.join(
+        [(SPACE * 4) + wrap(_(reason), column=column)
+         for reason in reasons])
+
+
+
 def autorespond_to_sender(mlist, sender, language=None):
     """Should Mailman automatically respond to this sender?
 
@@ -158,9 +170,7 @@ class HoldChain(TerminalChainBase):
             listname    = mlist.fqdn_listname,
             subject     = original_subject,
             sender      = msg.sender,
-            reason      = 'N/A', #reason,
-            confirmurl  = '{0}/{1}'.format(mlist.script_url('confirm'), token),
-            admindb_url = mlist.script_url('admindb'),
+            reasons     = _compose_reasons(msgdata),
             )
         # At this point the message is held, but now we have to craft at least
         # two responses.  The first will go to the original author of the
@@ -205,7 +215,7 @@ class HoldChain(TerminalChainBase):
                 charset = language.charset
                 # We need to regenerate or re-translate a few values in the
                 # substitution dictionary.
-                #d['reason'] = _(reason) # XXX reason
+                substitutions['reasons'] = _compose_reasons(msgdata, 55)
                 substitutions['subject'] = original_subject
                 # craft the admin notification message and deliver it
                 subject = _(
@@ -235,10 +245,11 @@ also appear in the first line of the body of the 
reply.""")),
                 nmsg.attach(MIMEMessage(msg))
                 nmsg.attach(MIMEMessage(dmsg))
                 nmsg.send(mlist, **dict(tomoderators=True))
-        # Log the held message
-        # XXX reason
-        reason = 'n/a'
-        log.info('HOLD: %s post from %s held, message-id=%s: %s',
-                 mlist.fqdn_listname, msg.sender,
-                 msg.get('message-id', 'n/a'), reason)
+        # Log the held message.  Log messages are not translated, so recast
+        # the reasons in the English.
+        with _.using('en'):
+            reasons = msgdata.get('moderation_reasons', ['N/A'])
+            log.info('HOLD: %s post from %s held, message-id=%s: %s',
+                     mlist.fqdn_listname, msg.sender,
+                     msg.get('message-id', 'n/a'), SEMISPACE.join(reasons))
         notify(HoldEvent(mlist, msg, msgdata, self))


=====================================
src/mailman/chains/tests/test_hold.py
=====================================
--- a/src/mailman/chains/tests/test_hold.py
+++ b/src/mailman/chains/tests/test_hold.py
@@ -26,9 +26,12 @@ import unittest
 
 from mailman.app.lifecycle import create_list
 from mailman.chains.hold import autorespond_to_sender
+from mailman.core.chains import process as process_chain
 from mailman.interfaces.autorespond import IAutoResponseSet, Response
 from mailman.interfaces.usermanager import IUserManager
-from mailman.testing.helpers import configuration, get_queue_messages
+from mailman.testing.helpers import (
+    LogFileMark, configuration, get_queue_messages,
+    specialized_message_from_string as mfs)
 from mailman.testing.layers import ConfigLayer
 from zope.component import getUtility
 
@@ -86,3 +89,48 @@ further responses today.  Please try again tomorrow.
 
 If you believe this message is in error, or if you have any questions,
 please contact the list owner at test-ow...@example.com.""")
+
+
+
+class TestHoldChain(unittest.TestCase):
+    """Test the hold chain code."""
+
+    layer = ConfigLayer
+
+    def setUp(self):
+        self._mlist = create_list('t...@example.com')
+
+    def test_hold_chain(self):
+        msg = mfs("""\
+From: a...@example.com
+To: t...@example.com
+Subject: A message
+Message-ID: <ant>
+MIME-Version: 1.0
+
+A message body.
+""")
+        msgdata = dict(moderation_reasons=[
+            'TEST-REASON-1',
+            'TEST-REASON-2',
+            ])
+        logfile = LogFileMark('mailman.vette')
+        process_chain(self._mlist, msg, msgdata, start_chain='hold')
+        messages = get_queue_messages('virgin')
+        self.assertEqual(len(messages), 2)
+        payloads = {}
+        for item in messages:
+            if item.msg['to'] == 'test-ow...@example.com':
+                part = item.msg.get_payload(0)
+                payloads['owner'] = part.get_payload().splitlines()
+            elif item.msg['To'] == 'a...@example.com':
+                payloads['sender'] = item.msg.get_payload().splitlines()
+            else:
+                self.fail('Unexpected message: %s' % item.msg)
+        self.assertIn('    TEST-REASON-1', payloads['owner'])
+        self.assertIn('    TEST-REASON-2', payloads['owner'])
+        self.assertIn('    TEST-REASON-1', payloads['sender'])
+        self.assertIn('    TEST-REASON-2', payloads['sender'])
+        logged = logfile.read()
+        self.assertIn('TEST-REASON-1', logged)
+        self.assertIn('TEST-REASON-2', logged)


=====================================
src/mailman/core/docs/chains.rst
=====================================
--- a/src/mailman/core/docs/chains.rst
+++ b/src/mailman/core/docs/chains.rst
@@ -132,7 +132,10 @@ This one is addressed to the list moderators.
         List:    t...@example.com
         From:    aper...@example.com
         Subject: My first post
-        Reason:  N/A
+    <BLANKLINE>
+    The message is being held because:
+    <BLANKLINE>
+        N/A
     <BLANKLINE>
     At your convenience, visit your dashboard to approve or deny the
     request.
@@ -184,63 +187,12 @@ This message is addressed to the sender of the message.
     <BLANKLINE>
     Is being held until the list moderator can review it for approval.
     <BLANKLINE>
-    The reason it is being held:
+    The message is being held because:
     <BLANKLINE>
         N/A
     <BLANKLINE>
     Either the message will get posted to the list, or you will receive
-    notification of the moderator's decision.  If you would like to cancel
-    this posting, please visit the following URL:
-    <BLANKLINE>
-        http://lists.example.com/confirm/t...@example.com/...
-    <BLANKLINE>
-    <BLANKLINE>
-
-In addition, the pending database is holding the original messages, waiting
-for them to be disposed of by the original author or the list moderators.  The
-database is essentially a dictionary, with the keys being the randomly
-selected tokens included in the urls and the values being a 2-tuple where the
-first item is a type code and the second item is a message id.
-::
-
-    >>> import re
-    >>> cookie = None
-    >>> for line in messages[1].get_payload().splitlines():
-    ...     mo = re.search('confirm/[^/]+/(?P<cookie>.*)$', line)
-    ...     if mo:
-    ...         cookie = mo.group('cookie')
-    ...         break
-    >>> assert cookie is not None, 'No confirmation token found'
-
-    >>> from mailman.interfaces.pending import IPendings
-    >>> from zope.component import getUtility
-
-    >>> data = getUtility(IPendings).confirm(cookie)
-    >>> dump_msgdata(data)
-    id  : 1
-    type: held message
-
-The message itself is held in the message store.
-::
-
-    >>> from mailman.interfaces.requests import IListRequests
-    >>> list_requests = IListRequests(mlist)
-    >>> rkey, rdata = list_requests.get_request(data['id'])
-
-    >>> from mailman.interfaces.messages import IMessageStore
-    >>> from zope.component import getUtility
-    >>> msg = getUtility(IMessageStore).get_message_by_id(
-    ...     rdata['_mod_message_id'])
-
-    >>> print(msg.as_string())
-    From: aper...@example.com
-    To: t...@example.com
-    Subject: My first post
-    Message-ID: <first>
-    X-Message-ID-Hash: RXJU4JL6N2OUN3OYMXXPPSCR7P7JE2BW
-    <BLANKLINE>
-    An important message.
-    <BLANKLINE>
+    notification of the moderator's decision.
 
 
 The Accept chain


=====================================
src/mailman/docs/NEWS.rst
=====================================
--- a/src/mailman/docs/NEWS.rst
+++ b/src/mailman/docs/NEWS.rst
@@ -44,6 +44,9 @@ Bugs
  * Bulk emails are now decorated with headers and footers.  Given by Aurélien
    Bompard.  (Closes #145)
  * Core no longer depends on the standalone `mock` module.  (Closes: #146)
+ * Fix the logging of moderation reasons.  Given by Aurélien Bompard.  Also,
+   update the postauth.txt and postheld.txt templates to not include the bogus
+   URLs, and to include the translated moderation reasons.
 
 
 3.0.0 -- "Show Don't Tell"


=====================================
src/mailman/templates/en/postauth.txt
=====================================
--- a/src/mailman/templates/en/postauth.txt
+++ b/src/mailman/templates/en/postauth.txt
@@ -4,7 +4,10 @@ following mailing list posting:
     List:    $listname
     From:    $sender
     Subject: $subject
-    Reason:  $reason
+
+The message is being held because:
+
+$reasons
 
 At your convenience, visit your dashboard to approve or deny the
 request.


=====================================
src/mailman/templates/en/postheld.txt
=====================================
--- a/src/mailman/templates/en/postheld.txt
+++ b/src/mailman/templates/en/postheld.txt
@@ -4,12 +4,9 @@ Your mail to '$listname' with the subject
 
 Is being held until the list moderator can review it for approval.
 
-The reason it is being held:
+The message is being held because:
 
-    $reason
+$reasons
 
 Either the message will get posted to the list, or you will receive
-notification of the moderator's decision.  If you would like to cancel
-this posting, please visit the following URL:
-
-    $confirmurl
+notification of the moderator's decision.



View it on GitLab: 
https://gitlab.com/mailman/mailman/commit/a382ab7d78c9dad1f90120651f51de78fc92ff03
_______________________________________________
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
https://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org

Reply via email to