------------------------------------------------------------
revno: 6527
committer: Barry Warsaw <[EMAIL PROTECTED]>
branch nick: 3.0
timestamp: Tue 2007-07-10 22:39:57 -0400
message:
  Conversion of the ToDigest tests to doctests, along with just enough handler
  module update to make the thing pass.  Much more coverage is still necessary,
  but this at least recreates the existing tests.
  
  Changes to the test infrastructure to make REPORT_ONLY_FIRST_FAILURE
  conditional on lower (default) verbosity.  Increase the verbosity via
  'bin/testall -v' and you get all the failure output.
added:
  Mailman/docs/digests.txt
modified:
  Mailman/Handlers/ToDigest.py
  Mailman/bin/testall.py
  Mailman/database/model/mailinglist.py
  Mailman/testing/test_documentation.py
  Mailman/testing/test_handlers.py

=== added file 'Mailman/docs/digests.txt'
--- a/Mailman/docs/digests.txt  1970-01-01 00:00:00 +0000
+++ b/Mailman/docs/digests.txt  2007-07-11 02:39:57 +0000
@@ -0,0 +1,539 @@
+Digests
+=======
+
+Digests are a way for a user to receive list traffic in collections instead of
+as individual messages when immediately posted.  There are several forms of
+digests, although only two are currently supported: MIME digests and RFC 1153
+(a.k.a. plain text) digests.
+
+    >>> from Mailman.Handlers.ToDigest import process
+    >>> from Mailman.Message import Message
+    >>> from Mailman.Queue.Switchboard import Switchboard
+    >>> from Mailman.configuration import config
+    >>> from Mailman.database import flush
+    >>> from email import message_from_string
+    >>> mlist = config.list_manager.create('[EMAIL PROTECTED]')
+    >>> mlist.preferred_language = 'en'
+    >>> mlist.web_page_url = 'http://www.example.com/'
+    >>> mlist.real_name = 'XTest'
+    >>> mlist.subject_prefix = '[_XTest] '
+    >>> mlist.one_last_digest = set()
+    >>> flush()
+    >>> switchboard = Switchboard(config.VIRGINQUEUE_DIR)
+
+This is a helper function used to iterate through all the accumulated digest
+messages, in the order in which they were posted.  This makes it easier to
+update the tests when we switch to a different mailbox format.
+
+    >>> import os, mailbox
+    >>> def digest_mbox():
+    ...     path = os.path.join(mlist.full_path, 'digest.mbox')
+    ...     return mailbox.mbox(path)
+
+    >>> def clear_mbox():
+    ...     path = os.path.join(mlist.full_path, 'digest.mbox')
+    ...     os.remove(path)
+
+    >>> from itertools import count
+    >>> from string import Template
+    >>> def makemsg():
+    ...     for i in count(1):
+    ...         text = Template("""\
+    ... From: [EMAIL PROTECTED]
+    ... To: [EMAIL PROTECTED]
+    ... Subject: Test message $i
+    ...
+    ... Here is message $i
+    ... """).substitute(i=i)
+    ...         yield message_from_string(text, Message)
+
+
+Short circuiting
+----------------
+
+When a message is posted to the mailing list, it is generally added to a
+running collection of messages.  For now, this is a Unix mailbox file,
+although in the future this may end up being converted to a maildir style
+mailbox.  In any event, there are several factors that would bypass the
+storing of posted messages to the mailbox.  For example, the mailing list may
+not allow digests...
+
+    >>> mlist.digestable = False
+    >>> flush()
+    >>> msg = makemsg().next()
+    >>> process(mlist, msg, {})
+    >>> sum(1 for mboxmsg in digest_mbox())
+    0
+    >>> switchboard.files
+    []
+
+...or they may allow digests but the message is already a digest.
+
+    >>> mlist.digestable = True
+    >>> flush()
+    >>> process(mlist, msg, dict(isdigest=True))
+    >>> sum(1 for mboxmsg in digest_mbox())
+    0
+    >>> switchboard.files
+    []
+
+
+Sending a digest
+----------------
+
+For messages which are not digests, but which are posted to a digestable
+mailing list, the messages will be stored until they reach a criteria
+triggering the sending of the digest.  If none of those criteria are met, then
+the message will just sit in the mailbox for a while.
+
+    >>> mlist.digest_size_threshold = 10000
+    >>> flush()
+    >>> process(mlist, msg, {})
+    >>> switchboard.files
+    []
+    >>> sum(1 for mboxmsg in digest_mbox())
+    1
+    >>> clear_mbox()
+
+When the size of the digest mbox reaches the maximum size threshold, a digest
+is crafted and sent out.  This puts two messages in the virgin queue, an HTML
+digest and an RFC 1153 plain text digest.  The size threshold is in KB.
+
+    >>> mlist.digest_size_threshold = 1
+    >>> mlist.volume = 2
+    >>> mlist.next_digest_number = 10
+    >>> flush()
+    >>> size = 0
+    >>> for msg in makemsg():
+    ...     process(mlist, msg, {})
+    ...     size += len(str(msg))
+    ...     if size > mlist.digest_size_threshold * 1024:
+    ...         break
+    >>> sum(1 for mboxmsg in digest_mbox())
+    0
+    >>> len(switchboard.files)
+    2
+    >>> for filebase in switchboard.files:
+    ...     qmsg, qdata = switchboard.dequeue(filebase)
+    ...     switchboard.finish(filebase)
+    ...     if qmsg.is_multipart():
+    ...         mimemsg = qmsg
+    ...         mimedata = qdata
+    ...     else:
+    ...         rfc1153msg = qmsg
+    ...         rfc1153data = qdata
+    >>> print mimemsg.as_string()
+    Content-Type: multipart/mixed; boundary="..."
+    MIME-Version: 1.0
+    From: [EMAIL PROTECTED]
+    Subject: XTest Digest, Vol 2, Issue 10
+    To: [EMAIL PROTECTED]
+    Reply-To: [EMAIL PROTECTED]
+    Date: ...
+    Message-ID: ...
+    <BLANKLINE>
+    --...
+    Content-Type: text/plain; charset="us-ascii"
+    MIME-Version: 1.0
+    Content-Transfer-Encoding: 7bit
+    Content-Description: XTest Digest, Vol 2, Issue 10
+    <BLANKLINE>
+    Send XTest mailing list submissions to
+        [EMAIL PROTECTED]
+    <BLANKLINE>
+    To subscribe or unsubscribe via the World Wide Web, visit
+        http://www.example.com/listinfo/[EMAIL PROTECTED]
+    or, via email, send a message with subject or body 'help' to
+        [EMAIL PROTECTED]
+    <BLANKLINE>
+    You can reach the person managing the list at
+        [EMAIL PROTECTED]
+    <BLANKLINE>
+    When replying, please edit your Subject line so it is more specific
+    than "Re: Contents of XTest digest..."
+    <BLANKLINE>
+    --...
+    Content-Type: text/plain; charset="us-ascii"
+    MIME-Version: 1.0
+    Content-Transfer-Encoding: 7bit
+    Content-Description: Today's Topics (8 messages)
+    <BLANKLINE>
+    Today's Topics:
+    <BLANKLINE>
+       1. Test message 1 ([EMAIL PROTECTED])
+       2. Test message 2 ([EMAIL PROTECTED])
+       3. Test message 3 ([EMAIL PROTECTED])
+       4. Test message 4 ([EMAIL PROTECTED])
+       5. Test message 5 ([EMAIL PROTECTED])
+       6. Test message 6 ([EMAIL PROTECTED])
+       7. Test message 7 ([EMAIL PROTECTED])
+       8. Test message 8 ([EMAIL PROTECTED])
+    <BLANKLINE>
+    --...
+    Content-Type: multipart/digest; boundary="..."
+    MIME-Version: 1.0
+    <BLANKLINE>
+    --...
+    Content-Type: message/rfc822
+    MIME-Version: 1.0
+    <BLANKLINE>
+    From: [EMAIL PROTECTED]
+    To: [EMAIL PROTECTED]
+    Subject: Test message 1
+    Message: 1
+    <BLANKLINE>
+    Here is message 1
+    <BLANKLINE>
+    <BLANKLINE>
+    --...
+    Content-Type: message/rfc822
+    MIME-Version: 1.0
+    <BLANKLINE>
+    From: [EMAIL PROTECTED]
+    To: [EMAIL PROTECTED]
+    Subject: Test message 2
+    Message: 2
+    <BLANKLINE>
+    Here is message 2
+    <BLANKLINE>
+    <BLANKLINE>
+    --...
+    Content-Type: message/rfc822
+    MIME-Version: 1.0
+    <BLANKLINE>
+    From: [EMAIL PROTECTED]
+    To: [EMAIL PROTECTED]
+    Subject: Test message 3
+    Message: 3
+    <BLANKLINE>
+    Here is message 3
+    <BLANKLINE>
+    <BLANKLINE>
+    --...
+    Content-Type: message/rfc822
+    MIME-Version: 1.0
+    <BLANKLINE>
+    From: [EMAIL PROTECTED]
+    To: [EMAIL PROTECTED]
+    Subject: Test message 4
+    Message: 4
+    <BLANKLINE>
+    Here is message 4
+    <BLANKLINE>
+    <BLANKLINE>
+    --...
+    Content-Type: message/rfc822
+    MIME-Version: 1.0
+    <BLANKLINE>
+    From: [EMAIL PROTECTED]
+    To: [EMAIL PROTECTED]
+    Subject: Test message 5
+    Message: 5
+    <BLANKLINE>
+    Here is message 5
+    <BLANKLINE>
+    <BLANKLINE>
+    --...
+    Content-Type: message/rfc822
+    MIME-Version: 1.0
+    <BLANKLINE>
+    From: [EMAIL PROTECTED]
+    To: [EMAIL PROTECTED]
+    Subject: Test message 6
+    Message: 6
+    <BLANKLINE>
+    Here is message 6
+    <BLANKLINE>
+    <BLANKLINE>
+    --...
+    Content-Type: message/rfc822
+    MIME-Version: 1.0
+    <BLANKLINE>
+    From: [EMAIL PROTECTED]
+    To: [EMAIL PROTECTED]
+    Subject: Test message 7
+    Message: 7
+    <BLANKLINE>
+    Here is message 7
+    <BLANKLINE>
+    <BLANKLINE>
+    --...
+    Content-Type: message/rfc822
+    MIME-Version: 1.0
+    <BLANKLINE>
+    From: [EMAIL PROTECTED]
+    To: [EMAIL PROTECTED]
+    Subject: Test message 8
+    Message: 8
+    <BLANKLINE>
+    Here is message 8
+    <BLANKLINE>
+    <BLANKLINE>
+    --...
+    --...
+    >>> sorted(mimedata.items())
+    [('_parsemsg', False),
+     ('isdigest', True),
+     ('listname', '[EMAIL PROTECTED]'),
+     ('received_time', ...),
+     ('recips', set([])), ('version', 3)]
+    >>> print rfc1153msg.as_string()
+    From: [EMAIL PROTECTED]
+    Subject: XTest Digest, Vol 2, Issue 10
+    To: [EMAIL PROTECTED]
+    Reply-To: [EMAIL PROTECTED]
+    Date: ...
+    Message-ID: ...
+    MIME-Version: 1.0
+    Content-Type: text/plain; charset="us-ascii"
+    Content-Transfer-Encoding: 7bit
+    <BLANKLINE>
+    Send XTest mailing list submissions to
+        [EMAIL PROTECTED]
+    <BLANKLINE>
+    To subscribe or unsubscribe via the World Wide Web, visit
+        http://www.example.com/listinfo/[EMAIL PROTECTED]
+    or, via email, send a message with subject or body 'help' to
+        [EMAIL PROTECTED]
+    <BLANKLINE>
+    You can reach the person managing the list at
+        [EMAIL PROTECTED]
+    <BLANKLINE>
+    When replying, please edit your Subject line so it is more specific
+    than "Re: Contents of XTest digest..."
+    <BLANKLINE>
+    <BLANKLINE>
+    Today's Topics:
+    <BLANKLINE>
+       1. Test message 1 ([EMAIL PROTECTED])
+       2. Test message 2 ([EMAIL PROTECTED])
+       3. Test message 3 ([EMAIL PROTECTED])
+       4. Test message 4 ([EMAIL PROTECTED])
+       5. Test message 5 ([EMAIL PROTECTED])
+       6. Test message 6 ([EMAIL PROTECTED])
+       7. Test message 7 ([EMAIL PROTECTED])
+       8. Test message 8 ([EMAIL PROTECTED])
+    <BLANKLINE>
+    <BLANKLINE>
+    ----------------------------------------------------------------------
+    <BLANKLINE>
+    Message: 1
+    From: [EMAIL PROTECTED]
+    Subject: Test message 1
+    To: [EMAIL PROTECTED]
+    Message-ID: ...
+    <BLANKLINE>
+    Here is message 1
+    <BLANKLINE>
+    <BLANKLINE>
+    ------------------------------
+    <BLANKLINE>
+    Message: 2
+    From: [EMAIL PROTECTED]
+    Subject: Test message 2
+    To: [EMAIL PROTECTED]
+    Message-ID: ...
+    <BLANKLINE>
+    Here is message 2
+    <BLANKLINE>
+    <BLANKLINE>
+    ------------------------------
+    <BLANKLINE>
+    Message: 3
+    From: [EMAIL PROTECTED]
+    Subject: Test message 3
+    To: [EMAIL PROTECTED]
+    Message-ID: ...
+    <BLANKLINE>
+    Here is message 3
+    <BLANKLINE>
+    <BLANKLINE>
+    ------------------------------
+    <BLANKLINE>
+    Message: 4
+    From: [EMAIL PROTECTED]
+    Subject: Test message 4
+    To: [EMAIL PROTECTED]
+    Message-ID: ...
+    <BLANKLINE>
+    Here is message 4
+    <BLANKLINE>
+    <BLANKLINE>
+    ------------------------------
+    <BLANKLINE>
+    Message: 5
+    From: [EMAIL PROTECTED]
+    Subject: Test message 5
+    To: [EMAIL PROTECTED]
+    Message-ID: ...
+    <BLANKLINE>
+    Here is message 5
+    <BLANKLINE>
+    <BLANKLINE>
+    ------------------------------
+    <BLANKLINE>
+    Message: 6
+    From: [EMAIL PROTECTED]
+    Subject: Test message 6
+    To: [EMAIL PROTECTED]
+    Message-ID: ...
+    <BLANKLINE>
+    Here is message 6
+    <BLANKLINE>
+    <BLANKLINE>
+    ------------------------------
+    <BLANKLINE>
+    Message: 7
+    From: [EMAIL PROTECTED]
+    Subject: Test message 7
+    To: [EMAIL PROTECTED]
+    Message-ID: ...
+    <BLANKLINE>
+    Here is message 7
+    <BLANKLINE>
+    <BLANKLINE>
+    ------------------------------
+    <BLANKLINE>
+    Message: 8
+    From: [EMAIL PROTECTED]
+    Subject: Test message 8
+    To: [EMAIL PROTECTED]
+    Message-ID: ...
+    <BLANKLINE>
+    Here is message 8
+    <BLANKLINE>
+    <BLANKLINE>
+    End of XTest Digest, Vol 2, Issue 10
+    ************************************
+    <BLANKLINE>
+    >>> sorted(rfc1153data.items())
+    [('_parsemsg', False),
+     ('isdigest', True),
+     ('listname', '[EMAIL PROTECTED]'),
+     ('received_time', ...),
+     ('recips', set([])), ('version', 3)]
+
+
+Internationalized digests
+-------------------------
+
+When messages come in with a content-type character set different than that of
+the list's preferred language, recipients wil get an internationalized digest.
+
+    >>> mlist.preferred_language = 'fr'
+    >>> msg = message_from_string("""\
+    ... From: [EMAIL PROTECTED]
+    ... To: [EMAIL PROTECTED]
+    ... Subject: =?iso-2022-jp?b?GyRCMGxIVhsoQg==?=
+    ... MIME-Version: 1.0
+    ... Content-Type: text/plain; charset=iso-2022-jp
+    ... Content-Transfer-Encoding: 7bit
+    ...
+    ... \x1b$B0lHV\x1b(B
+    ... """, Message)
+
+Set the digest threshold to zero so that the digests will be sent immediately.
+
+    >>> mlist.digest_size_threshold = 0
+    >>> flush()
+    >>> process(mlist, msg, {})
+    >>> sum(1 for mboxmsg in digest_mbox())
+    0
+    >>> len(switchboard.files)
+    2
+    >>> for filebase in switchboard.files:
+    ...     qmsg, qdata = switchboard.dequeue(filebase)
+    ...     switchboard.finish(filebase)
+    ...     if qmsg.is_multipart():
+    ...         mimemsg = qmsg
+    ...         mimedata = qdata
+    ...     else:
+    ...         rfc1153msg = qmsg
+    ...         rfc1153data = qdata
+    >>> print mimemsg.as_string()
+    Content-Type: multipart/mixed; boundary="..."
+    MIME-Version: 1.0
+    From: [EMAIL PROTECTED]
+    Subject: XTest Digest, Vol 2, Issue 11
+    To: [EMAIL PROTECTED]
+    Reply-To: [EMAIL PROTECTED]
+    Date: ...
+    Message-ID: ...
+    <BLANKLINE>
+    --...
+    Content-Type: text/plain; charset="iso-8859-1"
+    MIME-Version: 1.0
+    Content-Transfer-Encoding: quoted-printable
+    Content-Description: XTest Digest, Vol 2, Issue 11
+    <BLANKLINE>
+    Envoyez vos messages pour la liste XTest =E0
+        [EMAIL PROTECTED]
+    <BLANKLINE>
+    Pour vous (d=E9s)abonner par le web, consultez
+        http://www.example.com/listinfo/[EMAIL PROTECTED]
+    <BLANKLINE>
+    ou, par courriel, envoyez un message avec =AB=A0help=A0=BB dans le corps ou
+    dans le sujet =E0
+        [EMAIL PROTECTED]
+    <BLANKLINE>
+    Vous pouvez contacter l'administrateur de la liste =E0 l'adresse
+        [EMAIL PROTECTED]
+    <BLANKLINE>
+    Si vous r=E9pondez, n'oubliez pas de changer l'objet du message afin
+    qu'il soit plus sp=E9cifique que =AB=A0Re: Contenu du groupe de 
XTest...=A0=
+    =BB
+    <BLANKLINE>
+    --...
+    Content-Type: text/plain; charset="utf-8"
+    MIME-Version: 1.0
+    Content-Transfer-Encoding: base64
+    Content-Description: Today's Topics (1 messages)
+    <BLANKLINE>
+    VGjDqG1lcyBkdSBqb3VyIDoKCiAgIDEuIOS4gOeVqiAoYXBlcnNvbkBleGFtcGxlLm9yZykK
+    <BLANKLINE>
+    --...
+    Content-Type: multipart/digest; boundary="..."
+    MIME-Version: 1.0
+    <BLANKLINE>
+    --...
+    Content-Type: message/rfc822
+    MIME-Version: 1.0
+    <BLANKLINE>
+    Content-Transfer-Encoding: 7bit
+    From: [EMAIL PROTECTED]
+    MIME-Version: 1.0
+    To: [EMAIL PROTECTED]
+    Content-Type: text/plain; charset=iso-2022-jp
+    Subject: =?iso-2022-jp?b?GyRCMGxIVhsoQg==?=
+    Message: 1
+    <BLANKLINE>
+    一番
+    <BLANKLINE>
+    <BLANKLINE>
+    --...
+    --...
+    >>> sorted(mimedata.items())
+    [('_parsemsg', False),
+     ('isdigest', True),
+     ('listname', '[EMAIL PROTECTED]'),
+     ('received_time', ...),
+     ('recips', set([])), ('version', 3)]
+    >>> print rfc1153msg.as_string()
+    From: [EMAIL PROTECTED]
+    Subject: XTest Digest, Vol 2, Issue 11
+    To: [EMAIL PROTECTED]
+    Reply-To: [EMAIL PROTECTED]
+    Date: ...
+    Message-ID: ...
+    MIME-Version: 1.0
+    Content-Type: text/plain; charset="utf-8"
+    Content-Transfer-Encoding: base64
+    <BLANKLINE>
+    ...
+    <BLANKLINE>
+    >>> sorted(rfc1153data.items())
+    [('_parsemsg', False),
+     ('isdigest', True),
+     ('listname', '[EMAIL PROTECTED]'),
+     ('received_time', ...),
+     ('recips', set([])), ('version', 3)]

=== modified file 'Mailman/Handlers/ToDigest.py'
--- a/Mailman/Handlers/ToDigest.py      2007-03-24 05:17:00 +0000
+++ b/Mailman/Handlers/ToDigest.py      2007-07-11 02:39:57 +0000
@@ -52,6 +52,7 @@
 from Mailman.MemberAdaptor import ENABLED
 from Mailman.Queue.sbcache import get_switchboard
 from Mailman.configuration import config
+from Mailman.constants import DeliveryMode, DeliveryStatus
 
 _ = i18n._
 __i18n_templates__ = True
@@ -67,7 +68,7 @@
     # Short circuit non-digestable lists.
     if not mlist.digestable or msgdata.get('isdigest'):
         return
-    mboxfile = os.path.join(mlist.fullpath(), 'digest.mbox')
+    mboxfile = os.path.join(mlist.full_path, 'digest.mbox')
     mboxfp = open(mboxfile, 'a+')
     mbox = Mailbox(mboxfp)
     mbox.AppendMessage(msg)
@@ -77,7 +78,7 @@
     # whether the size threshold has been reached.
     mboxfp.flush()
     size = os.path.getsize(mboxfile)
-    if size / 1024.0 >= mlist.digest_size_threshhold:
+    if size / 1024.0 >= mlist.digest_size_threshold:
         # This is a bit of a kludge to get the mbox file moved to the digest
         # queue directory.
         try:
@@ -91,7 +92,7 @@
         except Exception, errmsg:
             # Bare except is generally prohibited in Mailman, but we can't
             # forecast what exceptions can occur here.
-            log.error('send_digests() failed: %s', errmsg)
+            log.exception('send_digests() failed: %s', errmsg)
     mboxfp.close()
 
 
@@ -155,19 +156,19 @@
     mimemsg = Message.Message()
     mimemsg['Content-Type'] = 'multipart/mixed'
     mimemsg['MIME-Version'] = '1.0'
-    mimemsg['From'] = mlist.GetRequestEmail()
+    mimemsg['From'] = mlist.request_address
     mimemsg['Subject'] = digestsubj
-    mimemsg['To'] = mlist.GetListEmail()
-    mimemsg['Reply-To'] = mlist.GetListEmail()
+    mimemsg['To'] = mlist.posting_address
+    mimemsg['Reply-To'] = mlist.posting_address
     mimemsg['Date'] = formatdate(localtime=1)
     mimemsg['Message-ID'] = Utils.unique_message_id(mlist)
     # Set things up for the rfc1153 digest
     plainmsg = StringIO()
     rfc1153msg = Message.Message()
-    rfc1153msg['From'] = mlist.GetRequestEmail()
+    rfc1153msg['From'] = mlist.request_address
     rfc1153msg['Subject'] = digestsubj
-    rfc1153msg['To'] = mlist.GetListEmail()
-    rfc1153msg['Reply-To'] = mlist.GetListEmail()
+    rfc1153msg['To'] = mlist.posting_address
+    rfc1153msg['Reply-To'] = mlist.posting_address
     rfc1153msg['Date'] = formatdate(localtime=1)
     rfc1153msg['Message-ID'] = Utils.unique_message_id(mlist)
     separator70 = '-' * 70
@@ -179,10 +180,10 @@
     mastheadtxt = Utils.maketext(
         'masthead.txt',
         {'real_name' :        mlist.real_name,
-         'got_list_email':    mlist.GetListEmail(),
+         'got_list_email':    mlist.posting_address,
          'got_listinfo_url':  mlist.GetScriptURL('listinfo', absolute=1),
-         'got_request_email': mlist.GetRequestEmail(),
-         'got_owner_email':   mlist.GetOwnerEmail(),
+         'got_request_email': mlist.request_address,
+         'got_owner_email':   mlist.owner_address,
          }, mlist=mlist)
     # MIME
     masthead = MIMEText(mastheadtxt.encode(lcset), _charset=lcset)
@@ -377,20 +378,31 @@
     mlist.next_digest_number += 1
     virginq = get_switchboard(config.VIRGINQUEUE_DIR)
     # Calculate the recipients lists
-    plainrecips = []
-    mimerecips = []
-    drecips = mlist.getDigestMemberKeys() + mlist.one_last_digest.keys()
-    for user in mlist.getMemberCPAddresses(drecips):
-        # user might be None if someone who toggled off digest delivery
-        # subsequently unsubscribed from the mailing list.  Also, filter out
-        # folks who have disabled delivery.
-        if user is None or mlist.getDeliveryStatus(user) <> ENABLED:
+    plainrecips = set()
+    mimerecips = set()
+    # When someone turns off digest delivery, they will get one last digest to
+    # ensure that there will be no gaps in the messages they receive.
+    # Currently, this dictionary contains the email addresses of those folks
+    # who should get one last digest.  We need to find the corresponding
+    # IMember records.
+    digest_members = set(mlist.digest_members.members)
+    for address in mlist.one_last_digest:
+        member = mlist.digest_members.get_member(address)
+        if member:
+            digest_members.add(member)
+    for member in digest_members:
+        if member.delivery_status <> DeliveryStatus.enabled:
             continue
-        # Otherwise, decide whether they get MIME or RFC 1153 digests
-        if mlist.getMemberOption(user, config.DisableMime):
-            plainrecips.append(user)
+        # Send the digest to the case-preserved address of the digest members.
+        email_address = member.address.original_address
+        if member.delivery_mode == DeliveryMode.plaintext_digests:
+            plainrecips.add(email_address)
+        elif member.delivery_mode == DeliveryMode.mime_digests:
+            mimerecips.add(email_address)
         else:
-            mimerecips.append(user)
+            raise AssertionError(
+                'Digest member "%s" unexpected delivery mode: %s' %
+                (email_address, member.delivery_mode))
     # Zap this since we're now delivering the last digest to these folks.
     mlist.one_last_digest.clear()
     # MIME

=== modified file 'Mailman/bin/testall.py'
--- a/Mailman/bin/testall.py    2007-07-02 01:49:34 +0000
+++ b/Mailman/bin/testall.py    2007-07-11 02:39:57 +0000
@@ -152,6 +152,9 @@
     if not args:
         args = ['.']
 
+    # Store the options some place that other code can get to it.
+    config.opts = opts
+
     # Turn on code coverage if selected.
     if opts.coverage:
         try:

=== modified file 'Mailman/database/model/mailinglist.py'
--- a/Mailman/database/model/mailinglist.py     2007-07-03 05:09:53 +0000
+++ b/Mailman/database/model/mailinglist.py     2007-07-11 02:39:57 +0000
@@ -91,7 +91,7 @@
     has_field('digest_header',                              Unicode),
     has_field('digest_is_default',                          Boolean),
     has_field('digest_send_periodic',                       Boolean),
-    has_field('digest_size_threshhold',                     Integer),
+    has_field('digest_size_threshold',                      Integer),
     has_field('digest_volume_frequency',                    Integer),
     has_field('digestable',                                 Boolean),
     has_field('discard_these_nonmembers',                   PickleType),

=== modified file 'Mailman/testing/test_documentation.py'
--- a/Mailman/testing/test_documentation.py     2007-07-01 15:51:09 +0000
+++ b/Mailman/testing/test_documentation.py     2007-07-11 02:39:57 +0000
@@ -60,15 +60,19 @@
 def test_suite():
     suite = unittest.TestSuite()
     docsdir = os.path.join(os.path.dirname(Mailman.__file__), 'docs')
+    # Under higher verbosity settings, report all doctest errors, not just the
+    # first one.
+    flags = (doctest.ELLIPSIS |
+             doctest.NORMALIZE_WHITESPACE |
+             doctest.REPORT_NDIFF)
+    if config.opts.verbosity <= 2:
+        flags |= doctest.REPORT_ONLY_FIRST_FAILURE
     for filename in os.listdir(docsdir):
         if os.path.splitext(filename)[1] == '.txt':
             test = doctest.DocFileSuite(
                 'docs/' + filename,
                 package=Mailman,
-                optionflags=(doctest.ELLIPSIS
-                             | doctest.NORMALIZE_WHITESPACE
-                             | doctest.REPORT_NDIFF
-                             | doctest.REPORT_ONLY_FIRST_FAILURE),
+                optionflags=flags,
                 tearDown=cleaning_teardown)
             suite.addTest(test)
     return suite

=== modified file 'Mailman/testing/test_handlers.py'
--- a/Mailman/testing/test_handlers.py  2007-07-08 11:47:03 +0000
+++ b/Mailman/testing/test_handlers.py  2007-07-11 02:39:57 +0000
@@ -43,7 +43,6 @@
 from Mailman.Handlers import Scrubber
 # Don't test handlers such as SMTPDirect and Sendmail here
 from Mailman.Handlers import ToArchive
-from Mailman.Handlers import ToDigest
 
 
 
@@ -275,124 +274,9 @@
 
 
 
-class TestToDigest(TestBase):
-    def _makemsg(self, i=0):
-        msg = email.message_from_string("""From: [EMAIL PROTECTED]
-To: [EMAIL PROTECTED]
-Subject: message number %(i)d
-
-Here is message %(i)d
-""" % {'i' : i})
-        return msg
-
-    def setUp(self):
-        TestBase.setUp(self)
-        self._path = os.path.join(self._mlist.fullpath(), 'digest.mbox')
-        fp = open(self._path, 'w')
-        g = Generator(fp)
-        for i in range(5):
-            g.flatten(self._makemsg(i), unixfrom=1)
-        fp.close()
-        self._sb = Switchboard(config.VIRGINQUEUE_DIR)
-
-    def tearDown(self):
-        try:
-            os.unlink(self._path)
-        except OSError, e:
-            if e.errno <> errno.ENOENT: raise
-        for f in os.listdir(config.VIRGINQUEUE_DIR):
-            os.unlink(os.path.join(config.VIRGINQUEUE_DIR, f))
-        TestBase.tearDown(self)
-
-    def test_short_circuit(self):
-        eq = self.assertEqual
-        mlist = self._mlist
-        mlist.digestable = 0
-        eq(ToDigest.process(mlist, None, {}), None)
-        mlist.digestable = 1
-        eq(ToDigest.process(mlist, None, {'isdigest': 1}), None)
-        eq(self._sb.files(), [])
-
-    def test_undersized(self):
-        msg = self._makemsg(99)
-        size = os.path.getsize(self._path) + len(str(msg))
-        self._mlist.digest_size_threshhold = (size + 1) * 1024
-        ToDigest.process(self._mlist, msg, {})
-        self.assertEqual(self._sb.files(), [])
-
-    def test_send_a_digest(self):
-        eq = self.assertEqual
-        mlist = self._mlist
-        msg = self._makemsg(99)
-        size = os.path.getsize(self._path) + len(str(msg))
-        mlist.digest_size_threshhold = 0
-        ToDigest.process(mlist, msg, {})
-        files = self._sb.files()
-        # There should be two files in the queue, one for the MIME digest and
-        # one for the RFC 1153 digest.
-        eq(len(files), 2)
-        # Now figure out which of the two files is the MIME digest and which
-        # is the RFC 1153 digest.
-        for filebase in files:
-            qmsg, qdata = self._sb.dequeue(filebase)
-            if qmsg.get_content_maintype() == 'multipart':
-                mimemsg = qmsg
-                mimedata = qdata
-            else:
-                rfc1153msg = qmsg
-                rfc1153data = qdata
-        eq(rfc1153msg.get_content_type(), 'text/plain')
-        eq(mimemsg.get_content_type(), 'multipart/mixed')
-        eq(mimemsg['from'], mlist.GetRequestEmail())
-        eq(mimemsg['subject'],
-           '%(realname)s Digest, Vol %(volume)d, Issue %(issue)d' % {
-            'realname': mlist.real_name,
-            'volume'  : mlist.volume,
-            'issue'   : mlist.next_digest_number - 1,
-            })
-        eq(mimemsg['to'], mlist.GetListEmail())
-        # BAW: this test is incomplete...
-
-    def test_send_i18n_digest(self):
-        eq = self.assertEqual
-        mlist = self._mlist
-        mlist.preferred_language = 'fr'
-        msg = email.message_from_string("""\
-From: [EMAIL PROTECTED]
-To: [EMAIL PROTECTED]
-Subject: =?iso-2022-jp?b?GyRCMGxIVhsoQg==?=
-MIME-Version: 1.0
-Content-Type: text/plain; charset=iso-2022-jp
-Content-Transfer-Encoding: 7bit
-
-\x1b$B0lHV\x1b(B
-""")
-        mlist.digest_size_threshhold = 0
-        ToDigest.process(mlist, msg, {})
-        files = self._sb.files()
-        eq(len(files), 2)
-        for filebase in files:
-            qmsg, qdata = self._sb.dequeue(filebase)
-            if qmsg.get_content_maintype() == 'multipart':
-                mimemsg = qmsg
-                mimedata = qdata
-            else:
-                rfc1153msg = qmsg
-                rfc1153data = qdata
-        eq(rfc1153msg.get_content_type(), 'text/plain')
-        eq(rfc1153msg.get_content_charset(), 'utf-8')
-        eq(rfc1153msg['content-transfer-encoding'], 'base64')
-        toc = mimemsg.get_payload()[1]
-        eq(toc.get_content_type(), 'text/plain')
-        eq(toc.get_content_charset(), 'utf-8')
-        eq(toc['content-transfer-encoding'], 'base64')
-
-
-
 def test_suite():
     suite = unittest.TestSuite()
     suite.addTest(unittest.makeSuite(TestApprove))
     suite.addTest(unittest.makeSuite(TestScrubber))
     suite.addTest(unittest.makeSuite(TestToArchive))
-    suite.addTest(unittest.makeSuite(TestToDigest))
     return suite



--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
_______________________________________________
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org

Reply via email to