summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mailman/app/digests.py7
-rw-r--r--src/mailman/commands/cli_digests.py42
-rw-r--r--src/mailman/commands/tests/test_digests.py89
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)