On Fri, 2012-06-01 at 21:33 -0400, Barry Warsaw wrote:
> * Look at the IMessageStore API.  Is this complete?  IOW, could you
> build a purely Python-level archiver like HyperKitty on top of this
> API?  Here's where proper attachment handling would probably be
> necessary.

With the help of wacky on #mailman this week-end we came up with this
"patch".
Attached is both the diff and the file itself.

This way we can start discussing :)

Pierre
=== modified file 'src/mailman/interfaces/messages.py'
--- src/mailman/interfaces/messages.py	2012-01-01 19:14:46 +0000
+++ src/mailman/interfaces/messages.py	2012-06-03 16:23:46 +0000
@@ -65,35 +65,125 @@
     def add(message):
         """Add the message to the store.
 
-        :param message: An email.message.Message instance containing at least
-            a unique Message-ID header.  The message will be given an
-            X-Message-ID-Hash header, overriding any existing such header.
-        :returns: The calculated X-Message-ID-Hash header.
-        :raises ValueError: if the message is missing a Message-ID header.
-            The storage service is also allowed to raise this exception if it
-            find, but disallows collisions.
-        """
-
-    def get_message_by_id(message_id):
-        """Return the message with a matching Message-ID.
-
-        :param message_id: The Message-ID header contents to search for.
-        :returns: The message, or None if no matching message was found.
-        """
-
-    def get_message_by_hash(message_id_hash):
-        """Return the message with the matching X-Message-ID-Hash.
-        
-        :param message_id_hash: The X-Message-ID-Hash header contents to
-            search for.
-        :returns: The message, or None if no matching message was found.
+        :param message: An email.message.Message instance containing at
+            least a unique Message-ID header.  The message will be given
+            an X-Message-ID-Hash header, overriding any existing such
+            header.
+        :returns: The calculated X-Message-ID-Hash header.
+        :raises ValueError: if the message is missing a Message-ID 
+            header.
+            The storage service is also allowed to raise this exception
+            if it find, but disallows collisions.
+        """
+
+    def add_to_list(list_name, message):
+        """Add the message to a specific list of the store.
+
+        :param list_name: The fully qualified list name to which the
+            message should be added.
+        :param message: An email.message.Message instance containing at
+            least a unique Message-ID header.  The message will be given
+            an X-Message-ID-Hash header, overriding any existing such
+            header.
+        :returns: The calculated X-Message-ID-Hash header.
+        :raises ValueError: if the message is missing a Message-ID 
+            header.
+            The storage service is also allowed to raise this exception
+            if it find, but disallows collisions.
         """
 
     def delete_message(message_id):
         """Remove the given message from the store.
 
-        :param message: The Message-ID of the mesage to delete from the store.
-        :raises LookupError: if there is no such message.
+        :param message: The Message-ID of the mesage to delete from the
+            store.
+        :raises LookupError: if there is no such message.
+        """
+
+    def delete_message_from_list(list_name, message_id):
+        """Remove the given message for a specific list from the store.
+
+        :param list_name: The fully qualified list name to which the
+            message should be added.
+        :param message: The Message-ID of the mesage to delete from the
+            store.
+        :raises LookupError: if there is no such message.
+        """
+
+    def get_list_size(list_name):
+        """ Return the number of emails stored for a given mailing list.
+
+        :arg list_name, name of the mailing list in which this email
+        should be searched.
+        """
+
+    def get_message_by_hash(message_id_hash):
+        """Return the message with the matching X-Message-ID-Hash.
+
+        :param message_id_hash: The X-Message-ID-Hash header contents to
+            search for.
+        :returns: The message, or None if no matching message was found.
+        """
+
+    def get_message_by_hash_from_list(list_name, message_id_hash):
+        """Return the message with the matching X-Message-ID-Hash.
+
+        :param message_id_hash: The X-Message-ID-Hash header contents to
+            search for.
+        :returns: The message, or None if no matching message was found.
+        """
+
+    def get_message_by_id(message_id):
+        """Return the message with a matching Message-ID.
+
+        :param message_id: The Message-ID header contents to search for.
+        :returns: The message, or None if no matching message was found.
+        """
+
+    def get_message_by_id_from_list(list_name, message_id):
+        """Return the message with a matching Message-ID.
+
+        :param list_name: The fully qualified list name to which the
+            message should be added.
+        :param message_id: The Message-ID header contents to search for.
+        :returns: The message, or None if no matching message was found.
+        """
+
+    def search_list_for_content(list_name, keyword):
+        """ Returns a list of email containing the specified keyword in
+        their content.
+
+        :param list_name: name of the mailing list in which this email
+        should be searched.
+        :param keyword: keyword to search in the content of the emails.
+        """
+    
+    def search_list_for_content_subject(list_name, keyword):
+        """ Returns a list of email containing the specified keyword in
+        their content or their subject.
+
+        :param list_name: name of the mailing list in which this email
+            should be searched.
+        :param keyword: keyword to search in the content or subject of
+            the emails.
+        """
+
+    def search_list_for_sender(list_name, keyword):
+        """ Returns a list of email containing the specified keyword in
+        the name or email address of the sender of the email.
+
+        :param list_name: name of the mailing list in which this email
+            should be searched.
+        :param keyword: keyword to search in the database.
+        """
+
+    def search_list_for_subject(list_name, keyword):
+        """ Returns a list of email containing the specified keyword in
+        their subject.
+
+        :param list_name: name of the mailing list in which this email
+            should be searched.
+        :param keyword: keyword to search in the subject of the emails.
         """
 
     messages = Attribute(

# Copyright (C) 2007-2012 by the Free Software Foundation, Inc.
#
# This file is part of GNU Mailman.
#
# GNU Mailman 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 3 of the License, or (at your option)
# any later version.
#
# GNU Mailman 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
# GNU Mailman.  If not, see <http://www.gnu.org/licenses/>.

"""The message storage service."""

from __future__ import absolute_import, unicode_literals

__metaclass__ = type
__all__ = [
    'IMessage',
    'IMessageStore',
    ]


from zope.interface import Interface, Attribute



class IMessageStore(Interface):
    """The interface of the global message storage service.

    All messages that are stored in the system live in the message storage
    service.  A message stored in this service must have a Message-ID header.
    The store writes an X-Message-ID-Hash header which contains the Base32
    encoded SHA1 hash of the message's Message-ID header.  Any existing
    X-Message-ID-Hash header is overwritten.

    Either the Message-ID or the X-Message-ID-Hash header can be used to
    uniquely identify this message in the storage service.  While it is
    possible to see duplicate Message-IDs, this is never correct and the
    service is allowed to drop any subsequent colliding messages, or overwrite
    earlier messages with later ones.

    The combination of the List-Archive header and either the Message-ID or
    X-Message-ID-Hash header can be used to retrieve the message from the
    internet facing interface for the message store.  This can be considered a
    globally unique URI to the message.

    For example, a message with the following headers:

    Message-ID: <87myycy5eh....@uwakimon.sk.tsukuba.ac.jp>
    Date: Wed, 04 Jul 2007 16:49:58 +0900
    List-Archive: http://archive.example.com/
    X-Message-ID-Hash: RXTJ357KFOTJP3NFJA6KMO65X7VQOHJI

    the globally unique URI would be:

    http://archive.example.com/RXTJ357KFOTJP3NFJA6KMO65X7VQOHJI
    """

    def add(message):
        """Add the message to the store.

        :param message: An email.message.Message instance containing at
            least a unique Message-ID header.  The message will be given
            an X-Message-ID-Hash header, overriding any existing such
            header.
        :returns: The calculated X-Message-ID-Hash header.
        :raises ValueError: if the message is missing a Message-ID 
            header.
            The storage service is also allowed to raise this exception
            if it find, but disallows collisions.
        """

    def add_to_list(list_name, message):
        """Add the message to a specific list of the store.

        :param list_name: The fully qualified list name to which the
            message should be added.
        :param message: An email.message.Message instance containing at
            least a unique Message-ID header.  The message will be given
            an X-Message-ID-Hash header, overriding any existing such
            header.
        :returns: The calculated X-Message-ID-Hash header.
        :raises ValueError: if the message is missing a Message-ID 
            header.
            The storage service is also allowed to raise this exception
            if it find, but disallows collisions.
        """

    def delete_message(message_id):
        """Remove the given message from the store.

        :param message: The Message-ID of the mesage to delete from the
            store.
        :raises LookupError: if there is no such message.
        """

    def delete_message_from_list(list_name, message_id):
        """Remove the given message for a specific list from the store.

        :param list_name: The fully qualified list name to which the
            message should be added.
        :param message: The Message-ID of the mesage to delete from the
            store.
        :raises LookupError: if there is no such message.
        """

    def get_list_size(list_name):
        """ Return the number of emails stored for a given mailing list.

        :arg list_name, name of the mailing list in which this email
        should be searched.
        """

    def get_message_by_hash(message_id_hash):
        """Return the message with the matching X-Message-ID-Hash.

        :param message_id_hash: The X-Message-ID-Hash header contents to
            search for.
        :returns: The message, or None if no matching message was found.
        """

    def get_message_by_hash_from_list(list_name, message_id_hash):
        """Return the message with the matching X-Message-ID-Hash.

        :param message_id_hash: The X-Message-ID-Hash header contents to
            search for.
        :returns: The message, or None if no matching message was found.
        """

    def get_message_by_id(message_id):
        """Return the message with a matching Message-ID.

        :param message_id: The Message-ID header contents to search for.
        :returns: The message, or None if no matching message was found.
        """

    def get_message_by_id_from_list(list_name, message_id):
        """Return the message with a matching Message-ID.

        :param list_name: The fully qualified list name to which the
            message should be added.
        :param message_id: The Message-ID header contents to search for.
        :returns: The message, or None if no matching message was found.
        """

    def search_list_for_content(list_name, keyword):
        """ Returns a list of email containing the specified keyword in
        their content.

        :param list_name: name of the mailing list in which this email
        should be searched.
        :param keyword: keyword to search in the content of the emails.
        """
    
    def search_list_for_content_subject(list_name, keyword):
        """ Returns a list of email containing the specified keyword in
        their content or their subject.

        :param list_name: name of the mailing list in which this email
            should be searched.
        :param keyword: keyword to search in the content or subject of
            the emails.
        """

    def search_list_for_sender(list_name, keyword):
        """ Returns a list of email containing the specified keyword in
        the name or email address of the sender of the email.

        :param list_name: name of the mailing list in which this email
            should be searched.
        :param keyword: keyword to search in the database.
        """

    def search_list_for_subject(list_name, keyword):
        """ Returns a list of email containing the specified keyword in
        their subject.

        :param list_name: name of the mailing list in which this email
            should be searched.
        :param keyword: keyword to search in the subject of the emails.
        """

    messages = Attribute(
        """An iterator over all messages in this message store.""")



class IMessage(Interface):
    """The representation of an email message."""

    message_id = Attribute("""The message's Message-ID header.""")

    message_id_hash = Attribute("""The unique SHA1 hash of the message.""")

    path = Attribute("""The filesystem path to the message object.""")
_______________________________________________
Mailman-Developers mailing list
Mailman-Developers@python.org
http://mail.python.org/mailman/listinfo/mailman-developers
Mailman FAQ: http://wiki.list.org/x/AgA3
Searchable Archives: 
http://www.mail-archive.com/mailman-developers%40python.org/
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-developers/archive%40jab.org

Security Policy: http://wiki.list.org/x/QIA9

Reply via email to