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