------------------------------------------------------------
revno: 6583
committer: Barry Warsaw <[EMAIL PROTECTED]>
branch nick: 3.0
timestamp: Sun 2008-01-13 16:18:19 -0500
message:
  Merge from rfc5064 branch.
added:
  Mailman/interfaces/archiver.py
modified:
  Mailman/Handlers/Cleanse.py
  Mailman/Handlers/CookHeaders.py
  Mailman/Handlers/Scrubber.py
  Mailman/app/archiving.py
  Mailman/docs/cook-headers.txt
  Mailman/docs/scrubber.txt
  setup.py
    ------------------------------------------------------------
    revno: 6582.1.1
    committer: Barry Warsaw <[EMAIL PROTECTED]>
    branch nick: rfc5064
    timestamp: Sun 2008-01-13 16:17:38 -0500
    message:
      Add an interface IArchiver which is used to calculate urls and send 
messages
      to the archiver.  Also add a plugin architecture for easily overriding the
      archiver, and hook this into the setup.py script.
      
      Updated CookHeaders.py and Scrubber.py handlers to use the plugged 
archiver.
      Updated doctests as appropriate.
      
      Fix a typo in the setup.py file.
    added:
      Mailman/interfaces/archiver.py
    modified:
      Mailman/Handlers/Cleanse.py
      Mailman/Handlers/CookHeaders.py
      Mailman/Handlers/Scrubber.py
      Mailman/app/archiving.py
      Mailman/docs/cook-headers.txt
      Mailman/docs/scrubber.txt
      setup.py

=== modified file 'Mailman/Handlers/Cleanse.py'
--- a/Mailman/Handlers/Cleanse.py       2007-06-19 22:42:27 +0000
+++ b/Mailman/Handlers/Cleanse.py       2008-01-13 21:17:38 +0000
@@ -54,3 +54,5 @@
     del msg['x-confirm-reading-to']
     # Pegasus mail uses this one... sigh
     del msg['x-pmrqc']
+    # Don't let this header be spoofed.  See RFC 5064.
+    del msg['archived-at']

=== modified file 'Mailman/Handlers/CookHeaders.py'
--- a/Mailman/Handlers/CookHeaders.py   2007-10-10 04:16:12 +0000
+++ b/Mailman/Handlers/CookHeaders.py   2008-01-13 21:17:38 +0000
@@ -26,7 +26,7 @@
 
 from Mailman import Utils
 from Mailman import Version
-from Mailman.app.archiving import get_base_archive_url
+from Mailman.app.archiving import get_archiver
 from Mailman.configuration import config
 from Mailman.i18n import _
 from Mailman.interfaces import Personalization, ReplyToMunging
@@ -200,6 +200,7 @@
         'List-Unsubscribe': subfieldfmt % (listinfo, mlist.leave_address),
         'List-Subscribe'  : subfieldfmt % (listinfo, mlist.join_address),
         })
+    archiver = get_archiver()
     if msgdata.get('reduced_list_headers'):
         headers['X-List-Administrivia'] = 'yes'
     else:
@@ -208,10 +209,17 @@
             headers['List-Post'] = '<mailto:%s>' % mlist.posting_address
         # Add this header if we're archiving
         if mlist.archive:
-            archiveurl = get_base_archive_url(mlist)
-            if archiveurl.endswith('/'):
-                archiveurl = archiveurl[:-1]
+            archiveurl = archiver.get_list_url(mlist)
             headers['List-Archive'] = '<%s>' % archiveurl
+    # XXX RFC 2369 also defines a List-Owner header which we are not currently
+    # supporting, but should.
+    #
+    # Draft RFC 5064 defines an Archived-At header which contains the pointer
+    # directly to the message in the archive.  If the currently defined
+    # archiver can tell us the URL, go ahead and include this header.
+    archived_at = archiver.get_message_url(mlist, msg)
+    if archived_at is not None:
+        headers['Archived-At'] = archived_at
     # First we delete any pre-existing headers because the RFC permits only
     # one copy of each, and we want to be sure it's ours.
     for h, v in headers.items():

=== modified file 'Mailman/Handlers/Scrubber.py'
--- a/Mailman/Handlers/Scrubber.py      2007-11-18 21:38:59 +0000
+++ b/Mailman/Handlers/Scrubber.py      2008-01-13 21:17:38 +0000
@@ -35,7 +35,7 @@
 
 from Mailman import Utils
 from Mailman.Errors import DiscardMessage
-from Mailman.app.archiving import get_base_archive_url
+from Mailman.app.archiving import get_archiver
 from Mailman.configuration import config
 from Mailman.i18n import _
 
@@ -490,10 +490,9 @@
     fp = open(path, 'w')
     fp.write(decodedpayload)
     fp.close()
-    # Now calculate the url
-    baseurl = get_base_archive_url(mlist)
-    # Private archives will likely have a trailing slash.  Normalize.
-    if baseurl[-1] <> '/':
+    # Now calculate the url to the list's archive.
+    baseurl = get_archiver().get_list_url(mlist)
+    if not baseurl.endswith('/'):
         baseurl += '/'
     # Trailing space will definitely be a problem with format=flowed.
     # Bracket the URL instead.

=== modified file 'Mailman/app/archiving.py'
--- a/Mailman/app/archiving.py  2007-09-21 12:51:38 +0000
+++ b/Mailman/app/archiving.py  2008-01-13 21:17:38 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 by the Free Software Foundation, Inc.
+# Copyright (C) 2007-2008 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -17,20 +17,61 @@
 
 """Application level archiving support."""
 
+__all__ = [
+    'StockArchiver',
+    'get_archiver',
+    ]
+__metaclass__ = type
+
+
 from string import Template
+from zope.interface import implements
+from zope.interface.verify import verifyObject
 
+from Mailman.app.plugins import get_plugin
 from Mailman.configuration import config
-
-
-
-def get_base_archive_url(mlist):
-    if mlist.archive_private:
-        url = mlist.script_url('private') + '/index.html'
-    else:
-        web_host = config.domains.get(mlist.host_name, mlist.host_name)
-        url = Template(config.PUBLIC_ARCHIVE_URL).safe_substitute(
-            listname=mlist.fqdn_listname,
-            hostname=web_host,
-            fqdn_listname=mlist.fqdn_listname,
-            )
-    return url
+from Mailman.interfaces import IArchiver
+
+
+
+class StockArchiver:
+    """The stock Pipermail archiver."""
+
+    implements(IArchiver)
+
+    def get_list_url(self, mlist):
+        """See `IArchiver`."""
+        if mlist.archive_private:
+            url = mlist.script_url('private') + '/index.html'
+        else:
+            web_host = config.domains.get(mlist.host_name, mlist.host_name)
+            url = Template(config.PUBLIC_ARCHIVE_URL).safe_substitute(
+                listname=mlist.fqdn_listname,
+                hostname=web_host,
+                fqdn_listname=mlist.fqdn_listname,
+                )
+        return url
+
+    def get_message_url(self, mlist, message):
+        """See `IArchiver`."""
+        # Not currently implemented.
+        return None
+
+    def archive_message(self, mlist, message):
+        """See `IArchiver`."""
+        return None
+
+
+
+_archiver = None
+
+def get_archiver():
+    """Return the currently registered global archiver.
+
+    Uses the plugin architecture to find the IArchiver instance.
+    """
+    global _archiver
+    if _archiver is None:
+        _archiver = get_plugin('mailman.archiver')()
+        verifyObject(IArchiver, _archiver)
+    return _archiver

=== modified file 'Mailman/docs/cook-headers.txt'
--- a/Mailman/docs/cook-headers.txt     2007-11-08 05:34:49 +0000
+++ b/Mailman/docs/cook-headers.txt     2008-01-13 21:17:38 +0000
@@ -285,6 +285,19 @@
     ---end---
 
 
+Archived-At
+-----------
+
+RFC 5064 (draft) defines a new Archived-At header which contains the url to
+the individual message in the archives.  The stock Pipermail archiver doesn't
+support this because the url can't be calculated until after the message is
+archived.  Because this is done by the archive runner, this information isn't
+available to us now.
+
+    >>> print msg['archived-at']
+    None
+
+
 Personalization
 ---------------
 

=== modified file 'Mailman/docs/scrubber.txt'
--- a/Mailman/docs/scrubber.txt 2007-11-08 16:54:25 +0000
+++ b/Mailman/docs/scrubber.txt 2008-01-13 21:17:38 +0000
@@ -59,9 +59,9 @@
     ... 
     ... R0lGODdhAQABAIAAAAAAAAAAACwAAAAAAQABAAACAQUAOw==
     ... """)
-    >>> save_attachment(mlist, msg, '')
-    u'<http://www.example.com/pipermail/[EMAIL PROTECTED]//xtest.gif>'
-    >>> data = read_attachment('xtest.gif')
+    >>> save_attachment(mlist, msg, 'dir')
+    u'<http://www.example.com/pipermail/[EMAIL PROTECTED]/dir/xtest.gif>'
+    >>> data = read_attachment('dir/xtest.gif')
     >>> data[:6]
     'GIF87a'
     >>> len(data)
@@ -88,13 +88,13 @@
     ... 
     ... R0lGODdhAQABAIAAAAAAAAAAACwAAAAAAQABAAACAQUAOw==
     ... """)
-    >>> save_attachment(mlist, msg, '')
-    u'<http://www.example.com/pipermail/[EMAIL PROTECTED]/.../attachment.gif>'
-    >>> data = read_attachment('xtest.gif')
+    >>> save_attachment(mlist, msg, 'dir')
+    u'<http://www.example.com/pipermail/[EMAIL PROTECTED]/dir/attachment.gif>'
+    >>> data = read_attachment('dir/xtest.gif')
     Traceback (most recent call last):
     IOError: [Errno ...] No such file or directory:
-        u'.../archives/private/[EMAIL PROTECTED]/xtest.gif'
-    >>> data = read_attachment('attachment.gif')
+        u'.../archives/private/[EMAIL PROTECTED]/dir/xtest.gif'
+    >>> data = read_attachment('dir/attachment.gif')
     >>> data[:6]
     'GIF87a'
     >>> len(data)

=== added file 'Mailman/interfaces/archiver.py'
--- a/Mailman/interfaces/archiver.py    1970-01-01 00:00:00 +0000
+++ b/Mailman/interfaces/archiver.py    2008-01-13 21:17:38 +0000
@@ -0,0 +1,58 @@
+# Copyright (C) 2008 by the Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+# USA.
+
+"""Interface for archiving schemes."""
+
+from zope.interface import Interface, Attribute
+
+
+
+class IArchiver(Interface):
+    """An interface to the archiver."""
+
+    def get_list_url(mlist):
+        """Return the url to the top of the list's archive.
+
+        :param mlist: The IMailingList object.
+        :returns: The url string.
+        """
+
+    def get_message_url(mlist, message):
+        """Return the url to the message in the archive.
+
+        This url points directly to the message in the archive.  This method
+        only calculates the url, it does not actually archive the message.
+
+        :param mlist: The IMailingList object.
+        :param message: The message object.
+        :returns: The url string or None if the message's archive url cannot
+            be calculated.
+        """
+
+    def archive_message(mlist, message):
+        """Send the message to the archiver.
+
+        This uses `get_message_url()` to calculate and return the url to the
+        message in the archives.
+
+        :param mlist: The IMailingList object.
+        :param message: The message object.
+        :returns: The url string or None if the message's archive url cannot
+            be calculated.
+        """
+
+    # XXX How to handle attachments?

=== modified file 'setup.py'
--- a/setup.py  2008-01-13 19:35:31 +0000
+++ b/setup.py  2008-01-13 21:17:38 +0000
@@ -82,11 +82,12 @@
     include_package_data = True,
     entry_points    = {
         'console_scripts': list(scripts),
-        'setuptools.file_finders': 'bzr = setuptoolsbzr:find_files_for_bzr',
+        'setuptools.file_finders': 'bzr = setuptools_bzr:find_files_for_bzr',
         # Entry point for plugging in different database backends.
+        'mailman.archiver'  : 'stock = Mailman.app.archiving:StockArchiver',
         'mailman.database'  : 'stock = Mailman.database:StockDatabase',
+        'mailman.mta'       : 'stock = Mailman.MTA:Manual',
         'mailman.styles'    : 'default = Mailman.app.styles:DefaultStyle',
-        'mailman.mta'       : 'stock = Mailman.MTA:Manual',
         },
     # Third-party requirements.
     install_requires = [



--
Primary development focus
https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
_______________________________________________
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org

Reply via email to