diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/mailman/app/digests.py | 7 | ||||
| -rw-r--r-- | src/mailman/commands/cli_digests.py | 42 | ||||
| -rw-r--r-- | src/mailman/commands/tests/test_digests.py | 89 |
3 files changed, 110 insertions, 28 deletions
diff --git a/src/mailman/app/digests.py b/src/mailman/app/digests.py index b66a4c54c..2190fdf98 100644 --- a/src/mailman/app/digests.py +++ b/src/mailman/app/digests.py @@ -28,9 +28,7 @@ import os from mailman.config import config from mailman.email.message import Message from mailman.interfaces.digests import DigestFrequency -from mailman.interfaces.listmanager import IListManager from mailman.utilities.datetime import now as right_now -from zope.component import getUtility @@ -95,7 +93,10 @@ def maybe_send_digest_now(mlist, force=False): # us exactly how big the resulting MIME and rfc1153 digest will # actually be, but it's the most easily available metric to decide # whether the size threshold has been reached. - size = os.path.getsize(mailbox_path) + try: + size = os.path.getsize(mailbox_path) + except FileNotFoundError: + size = 0 if (size >= mlist.digest_size_threshold * 1024.0 or (force and size > 0)): # Send the digest. Because we don't want to hold up this process diff --git a/src/mailman/commands/cli_digests.py b/src/mailman/commands/cli_digests.py index 9af91f1c3..7d3de92b9 100644 --- a/src/mailman/commands/cli_digests.py +++ b/src/mailman/commands/cli_digests.py @@ -24,7 +24,8 @@ __all__ = [ import sys -from mailman.app.digests import maybe_send_digest_now +from mailman.app.digests import ( + bump_digest_number_and_volume, maybe_send_digest_now) from mailman.core.i18n import _ from mailman.interfaces.command import ICLISubCommand from mailman.interfaces.listmanager import IListManager @@ -59,33 +60,28 @@ class Digests: default=False, action='store_true', help=_("""Increment the digest volume number and reset the digest number to one. If given with --send, the volume number is - incremented after any current digests are sent.""")) + incremented before any current digests are sent.""")) def process(self, args): """See `ICLISubCommand`.""" list_manager = getUtility(IListManager) - if args.send: - if not args.lists: - # Send the digests for every list. - for mlist in list_manager.mailing_lists: - maybe_send_digest_now(mlist, force=True) - return - for list_spec in args.lists: + if args.lists: + lists = [] + for spec in args.lists: # We'll accept list-ids or fqdn list names. - if '@' in list_spec: - mlist = list_manager.get(list_spec) + if '@' in spec: + mlist = list_manager.get(spec) else: - mlist = list_manager.get_by_list_id(list_spec) + mlist = list_manager.get_by_list_id(spec) if mlist is None: - print(_('No such list found: $list_spec'), file=sys.stderr) - continue - maybe_send_digest_now(mlist, force=True) - if args.bump: - if not args.lists: - mlists = list(list_manager.mailing_lists) - else: - # We'll accept list-ids or fqdn list names. - if '@' in list_spec: - mlist = list_manager.get(list_spec) + print(_('No such list found: $spec'), file=sys.stderr) else: - mlist = list_manager.get_by_list_id(list_spec) + lists.append(mlist) + else: + lists = list(list_manager.mailing_lists) + if args.bump: + for mlist in lists: + bump_digest_number_and_volume(mlist) + if args.send: + for mlist in lists: + maybe_send_digest_now(mlist, force=True) diff --git a/src/mailman/commands/tests/test_digests.py b/src/mailman/commands/tests/test_digests.py index 2640580af..607949f6e 100644 --- a/src/mailman/commands/tests/test_digests.py +++ b/src/mailman/commands/tests/test_digests.py @@ -18,6 +18,7 @@ """Test the send-digests subcommand.""" __all__ = [ + 'TestBumpVolume', 'TestSendDigests', ] @@ -25,16 +26,19 @@ __all__ = [ import os import unittest +from datetime import timedelta from io import StringIO from mailman.app.lifecycle import create_list from mailman.commands.cli_digests import Digests from mailman.config import config +from mailman.interfaces.digests import DigestFrequency from mailman.interfaces.member import DeliveryMode from mailman.runners.digest import DigestRunner from mailman.testing.helpers import ( get_queue_messages, make_testable_runner, specialized_message_from_string as mfs, subscribe) from mailman.testing.layers import ConfigLayer +from mailman.utilities.datetime import now as right_now from unittest.mock import patch @@ -48,8 +52,6 @@ class FakeArgs: class TestSendDigests(unittest.TestCase): - """Test the send-digests subcommand.""" - layer = ConfigLayer def setUp(self): @@ -361,3 +363,86 @@ Subject: message 3 digest_contents = str(bee) self.assertIn('Subject: message 3', digest_contents) self.assertIn('Subject: message 4', digest_contents) + + def test_send_no_digest_ready(self): + # If no messages have been sent through the mailing list, no digest + # can be sent. + mailbox_path = os.path.join(self._mlist.data_path, 'digest.mmdf') + self.assertFalse(os.path.exists(mailbox_path)) + args = FakeArgs() + args.send = True + args.lists.append('ant.example.com') + self._command.process(args) + self._runner.run() + items = get_queue_messages('virgin') + self.assertEqual(len(items), 0) + + def test_bump_after_send(self): + self._mlist.digest_volume_frequency = DigestFrequency.monthly + self._mlist.volume = 7 + self._mlist.next_digest_number = 4 + self._mlist.digest_last_sent_at = right_now() + timedelta( + days=-32) + msg = mfs("""\ +To: ant@example.com +From: anne@example.com +Subject: message 1 + +""") + self._handler.process(self._mlist, msg, {}) + args = FakeArgs() + args.bump = True + args.send = True + args.lists.append('ant.example.com') + self._command.process(args) + self._runner.run() + # The volume is 8 and the digest number is 2 because a digest was sent + # after the volume/number was bumped. + self.assertEqual(self._mlist.volume, 8) + self.assertEqual(self._mlist.next_digest_number, 2) + self.assertEqual(self._mlist.digest_last_sent_at, right_now()) + items = get_queue_messages('virgin') + self.assertEqual(len(items), 1) + self.assertEqual(items[0].msg['subject'], 'Ant Digest, Vol 8, Issue 1') + + + +class TestBumpVolume(unittest.TestCase): + layer = ConfigLayer + + def setUp(self): + self._mlist = create_list('ant@example.com') + self._mlist.digest_volume_frequency = DigestFrequency.monthly + self._mlist.volume = 7 + self._mlist.next_digest_number = 4 + self.right_now = right_now() + self._command = Digests() + + def test_bump_one_list(self): + self._mlist.digest_last_sent_at = self.right_now + timedelta( + days=-32) + args = FakeArgs() + args.bump = True + args.lists.append('ant.example.com') + self._command.process(args) + self.assertEqual(self._mlist.volume, 8) + self.assertEqual(self._mlist.next_digest_number, 1) + self.assertEqual(self._mlist.digest_last_sent_at, self.right_now) + + def test_bump_two_lists(self): + self._mlist.digest_last_sent_at = self.right_now + timedelta( + days=-32) + # Create the second list. + bee = create_list('bee@example.com') + bee.digest_volume_frequency = DigestFrequency.monthly + bee.volume = 7 + bee.next_digest_number = 4 + bee.digest_last_sent_at = self.right_now + timedelta( + days=-32) + args = FakeArgs() + args.bump = True + args.lists.extend(('ant.example.com', 'bee.example.com')) + self._command.process(args) + self.assertEqual(self._mlist.volume, 8) + self.assertEqual(self._mlist.next_digest_number, 1) + self.assertEqual(self._mlist.digest_last_sent_at, self.right_now) |
