예제 #1
0
 def process(self, mlist, msg, msgdata):
     """See `IHandler`."""
     # Short circuit for non-digestable messages.
     if not mlist.digestable or msgdata.get('isdigest'):
         return
     # Open the mailbox that will be used to collect the current digest.
     mailbox_path = os.path.join(mlist.data_path, 'digest.mmdf')
     # Lock the mailbox and append the message.
     with Mailbox(mailbox_path, create=True) as mbox:
         mbox.add(msg)
     # Calculate the current size of the mailbox file.  This will not tell
     # 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)
     if size >= mlist.digest_size_threshold * 1024.0:
         # The digest is ready to send.  Because we don't want to hold up
         # this process with crafting the digest, we're going to move the
         # digest file to a safe place, then craft a fake message for the
         # DigestRunner as a trigger for it to build and send the digest.
         mailbox_dest = os.path.join(
             mlist.data_path,
             'digest.{0.volume}.{0.next_digest_number}.mmdf'.format(mlist))
         volume = mlist.volume
         digest_number = mlist.next_digest_number
         bump_digest_number_and_volume(mlist)
         os.rename(mailbox_path, mailbox_dest)
         config.switchboards['digest'].enqueue(Message(),
                                               listid=mlist.list_id,
                                               digest_path=mailbox_dest,
                                               volume=volume,
                                               digest_number=digest_number)
예제 #2
0
def digest_mbox(mlist):
    """The mailing list's pending digest as a mailbox.

    :param mlist: The mailing list.
    :return: The mailing list's pending digest as a mailbox.
    """
    path = os.path.join(mlist.data_path, 'digest.mmdf')
    return Mailbox(path)
예제 #3
0
 def process(self, mlist, msg, msgdata):
     """See `IHandler`."""
     # Short-circuit if digests are not enabled or if this message already
     # is a digest.
     if not mlist.digests_enabled or msgdata.get('isdigest'):
         return
     # Open the mailbox that will be used to collect the current digest.
     mailbox_path = os.path.join(mlist.data_path, 'digest.mmdf')
     # Lock the mailbox and append the message.
     with Mailbox(mailbox_path, create=True) as mbox:
         mbox.add(msg)
     maybe_send_digest_now(mlist)
예제 #4
0
파일: digest.py 프로젝트: inonit/mailman
 def _dispose(self, mlist, msg, msgdata):
     """See `IRunner`."""
     volume = msgdata['volume']
     digest_number = msgdata['digest_number']
     # Backslashes make me cry.
     code = mlist.preferred_language.code
     with Mailbox(msgdata['digest_path']) as mailbox, _.using(code):
         # Create the digesters.
         mime_digest = MIMEDigester(mlist, volume, digest_number)
         rfc1153_digest = RFC1153Digester(mlist, volume, digest_number)
         # Cruise through all the messages in the mailbox, first building
         # the table of contents and accumulating Subject: headers and
         # authors.  The question really is whether it's better from a1
         # performance and memory footprint to go through the mailbox once
         # and cache the messages in a list, or to cruise through the
         # mailbox twice.  We'll do the latter, but it's a complete guess.
         count = None
         for count, (key, message) in enumerate(mailbox.iteritems(), 1):
             mime_digest.add_to_toc(message, count)
             rfc1153_digest.add_to_toc(message, count)
         assert count is not None, 'No digest messages?'
         # Add the table of contents.
         mime_digest.add_toc(count)
         rfc1153_digest.add_toc(count)
         # Cruise through the set of messages a second time, adding them to
         # the actual digest.
         for count, (key, message) in enumerate(mailbox.iteritems(), 1):
             mime_digest.add_message(message, count)
             rfc1153_digest.add_message(message, count)
         # Finish up the digests.
         mime = mime_digest.finish()
         rfc1153 = rfc1153_digest.finish()
     # Calculate the recipients lists
     mime_recipients = set()
     rfc1153_recipients = 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.
     digest_members = set(mlist.digest_members.members)
     for member in digest_members:
         if member.delivery_status is not DeliveryStatus.enabled:
             continue
         # Send the digest to the case-preserved address of the digest
         # members.
         email_address = member.address.original_email
         if member.delivery_mode == DeliveryMode.plaintext_digests:
             rfc1153_recipients.add(email_address)
         # We currently treat summary_digests the same as mime_digests.
         elif member.delivery_mode in (DeliveryMode.mime_digests,
                                       DeliveryMode.summary_digests):
             mime_recipients.add(email_address)
         else:
             raise AssertionError(
                 'Digest member "{}" unexpected delivery mode: {}'.format(
                     email_address, member.delivery_mode))
     # Add also the folks who are receiving one last digest.
     for address, delivery_mode in mlist.last_digest_recipients:
         if delivery_mode == DeliveryMode.plaintext_digests:
             rfc1153_recipients.add(address.original_email)
         # We currently treat summary_digests the same as mime_digests.
         elif delivery_mode in (DeliveryMode.mime_digests,
                                DeliveryMode.summary_digests):
             mime_recipients.add(address.original_email)
         else:
             raise AssertionError(
                 'OLD recipient "{}" unexpected delivery mode: {}'.format(
                     address, delivery_mode))
     # Send the digests to the virgin queue for final delivery.
     queue = config.switchboards['virgin']
     if len(mime_recipients) > 0:
         queue.enqueue(mime,
                       recipients=mime_recipients,
                       listid=mlist.list_id,
                       isdigest=True)
     if len(rfc1153_recipients) > 0:
         queue.enqueue(rfc1153,
                       recipients=rfc1153_recipients,
                       listid=mlist.list_id,
                       isdigest=True)
     # Remove the digest mbox. (GL #259)
     os.remove(msgdata['digest_path'])