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: <[email protected]>
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
[email protected]
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