------------------------------------------------------------
revno: 6690
committer: Barry Warsaw <[email protected]>
branch nick: nopickles
timestamp: Mon 2009-02-16 23:57:30 -0500
message:
  Checkpointing the conversion of automatic responses away from pickles.
added:
  src/mailman/database/autorespond.py
  src/mailman/docs/autorespond.txt
  src/mailman/interfaces/autorespond.py
modified:
  setup.py
  src/mailman/core/initialize.py
  src/mailman/database/mailman.sql

=== modified file 'setup.py'
--- setup.py    2009-01-25 18:01:41 +0000
+++ setup.py    2009-02-17 04:57:30 +0000
@@ -101,6 +101,7 @@
         },
     install_requires = [
         'lazr.config',
+        'lazr.delegates',
         'locknix',
         'munepy',
         'storm',

=== modified file 'src/mailman/core/initialize.py'
--- src/mailman/core/initialize.py      2009-01-17 02:04:21 +0000
+++ src/mailman/core/initialize.py      2009-02-17 04:57:30 +0000
@@ -116,6 +116,8 @@
     """
     from mailman.app.registrar import adapt_domain_to_registrar
     adapter_hooks.append(adapt_domain_to_registrar)
+    from mailman.database.autorespond import adapt_mailing_list_to_response_set
+    adapter_hooks.append(adapt_mailing_list_to_response_set)
 
 
 

=== added file 'src/mailman/database/autorespond.py'
--- src/mailman/database/autorespond.py 1970-01-01 00:00:00 +0000
+++ src/mailman/database/autorespond.py 2009-02-17 04:57:30 +0000
@@ -0,0 +1,100 @@
+# Copyright (C) 2009 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/>.
+
+"""Module stuff."""
+
+from __future__ import absolute_import, unicode_literals
+
+__metaclass__ = type
+__all__ = [
+    'AutoResponseRecord',
+    'AutoResponseSet',
+    'adapt_mailing_list_to_response_set',
+    ]
+
+
+from datetime import date
+from storm.locals import And, Date, Int, Reference
+from zope.interface import implements
+
+from mailman.config import config
+from mailman.database.model import Model
+from mailman.database.types import Enum
+from mailman.interfaces.autorespond import (
+    IAutoResponseRecord, IAutoResponseSet, Response)
+from mailman.interfaces.mailinglist import IMailingList
+
+
+
+class AutoResponseRecord(Model):
+    implements(IAutoResponseRecord)
+
+    id = Int(primary=True)
+
+    address_id = Int()
+    address = Reference(address_id, 'Address.id')
+
+    mailing_list_id = Int()
+    mailing_list = Reference(mailing_list_id, 'MailingList.id')
+
+    response_type = Enum()
+    date_sent = Date()
+
+    def __init__(self, mailing_list, address, response_type):
+        self.mailing_list = mailing_list
+        self.address = address
+        self.response_type = response_type
+        self.date_sent = date.today()
+
+
+
+class AutoResponseSet:
+    implements(IAutoResponseSet)
+
+    def __init__(self, mailing_list):
+        self._mailing_list = mailing_list
+
+    def todays_count(self, address, response_type):
+        """See `IAutoResponseSet`."""
+        return config.db.store.find(
+            AutoResponseRecord,
+            And(AutoResponseRecord.address == address,
+                AutoResponseRecord.mailing_list == self._mailing_list,
+                AutoResponseRecord.response_type == response_type,
+                AutoResponseRecord.date_sent == date.today())).count()
+
+    def response_sent(self, address, response_type):
+        """See `IAutoResponseSet`."""
+        response = AutoResponseRecord(
+            self._mailing_list, address, response_type)
+        config.db.store.add(response)
+
+
+
+def adapt_mailing_list_to_response_set(iface, obj):
+    """Adapt an `IMailingList` to an `IAutoResponseSet`.
+
+    :param iface: The interface to adapt to.
+    :type iface: `zope.interface.Interface`
+    :param obj: The object being adapted.
+    :type obj: `IMailingList`
+    :return: An `IAutoResponseSet` instance if adaptation succeeded or None if
+        it didn't.
+    """
+    return (AutoResponseSet(obj)
+            if IMailingList.providedBy(obj) and iface is IAutoResponseSet
+            else None)

=== modified file 'src/mailman/database/mailman.sql'
--- src/mailman/database/mailman.sql    2009-02-04 12:00:56 +0000
+++ src/mailman/database/mailman.sql    2009-02-17 04:57:30 +0000
@@ -20,6 +20,26 @@
          CONSTRAINT address_user_id_fk FOREIGN KEY(user_id) REFERENCES user 
(id),
          CONSTRAINT address_preferences_id_fk FOREIGN KEY(preferences_id) 
REFERENCES preferences (id)
 );
+
+CREATE TABLE autoresponserecord (
+        id INTEGER NOT NULL,
+        address_id INTEGER,
+        mailing_list_id INTEGER,
+        response_type INTEGER,
+        date_sent TIMESTAMP,
+        PRIMARY KEY (id),
+        CONSTRAINT autoresponserecord_address_id_fk
+            FOREIGN KEY (address_id)
+            REFERENCES address (id),
+        CONSTRAINT autoresponserecord_mailing_list_id
+            FOREIGN KEY (mailing_list_id)
+            REFERENCES mailinglist (id)
+        );
+CREATE INDEX ix_autoresponserecord_address_id
+    ON autoresponserecord (address_id);
+CREATE INDEX ix_autoresponserecord_mailing_list_id
+    ON autoresponserecord (mailing_list_id);
+
 CREATE TABLE language (
         id INTEGER NOT NULL,
         code TEXT,

=== added file 'src/mailman/docs/autorespond.txt'
--- src/mailman/docs/autorespond.txt    1970-01-01 00:00:00 +0000
+++ src/mailman/docs/autorespond.txt    2009-02-17 04:57:30 +0000
@@ -0,0 +1,62 @@
+Automatic responder
+===================
+
+In various situations, Mailman will send an automatic response to the author
+of an email message.  For example, if someone sends a command to the -request
+address, Mailman will send a response, but to cut down on third party spam,
+the sender will only get a certain number of responses per day.
+
+First, given a mailing list you need to adapt it to an IAutoResponseSet.
+
+    >>> mlist = create_list('[email protected]')
+    >>> from mailman.interfaces.autorespond import IAutoResponseSet
+    >>> response_set = IAutoResponseSet(mlist)
+
+    >>> from zope.interface.verify import verifyObject
+    >>> verifyObject(IAutoResponseSet, response_set)
+    True
+
+You can't adapt other objects to an IAutoResponseSet.
+
+    >>> IAutoResponseSet(object())
+    Traceback (most recent call last):
+    ...
+    TypeError: ('Could not adapt', ...
+
+There are various kinds of response types.  For example, Mailman will send an
+automatic response when messages are held for approval, or when it receives an
+email command.  You can find out how many responses for a particular address
+have already been sent today.
+
+    >>> address = config.db.user_manager.create_address(
+    ...     u'[email protected]')
+    >>> from mailman.interfaces.autorespond import Response
+    >>> response_set.todays_count(address, Response.hold)
+    0
+    >>> response_set.todays_count(address, Response.command)
+    0
+
+Using the response set, we can record that a hold response is sent to the
+address.
+
+    >>> response_set.response_sent(address, Response.hold)
+    >>> response_set.todays_count(address, Response.hold)
+    1
+    >>> response_set.todays_count(address, Response.command)
+    0
+
+We can also record that a command response was sent.
+
+    >>> response_set.response_sent(address, Response.command)
+    >>> response_set.todays_count(address, Response.hold)
+    1
+    >>> response_set.todays_count(address, Response.command)
+    1
+
+Let's send one more.
+
+    >>> response_set.response_sent(address, Response.command)
+    >>> response_set.todays_count(address, Response.hold)
+    1
+    >>> response_set.todays_count(address, Response.command)
+    2

=== added file 'src/mailman/interfaces/autorespond.py'
--- src/mailman/interfaces/autorespond.py       1970-01-01 00:00:00 +0000
+++ src/mailman/interfaces/autorespond.py       2009-02-17 04:57:30 +0000
@@ -0,0 +1,87 @@
+# Copyright (C) 2009 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/>.
+
+"""Autoresponder."""
+
+from __future__ import absolute_import, unicode_literals
+
+__metaclass__ = type
+__all__ = [
+    'IAutoResponseRecord',
+    'IAutoResponseSet',
+    'Response',
+    ]
+
+
+from munepy import Enum
+from zope.interface import Interface, Attribute
+
+
+
+class Response(Enum):
+    # Your message was held for approval.
+    hold = 1
+    # Email commands, i.e. -request messages.
+    command = 2
+
+
+
+class IAutoResponseRecord(Interface):
+    """An auto-response record.
+
+    Every time Mailman sends an automatic response to an address, on a
+    specific mailing list for a specific purpose, it records the response.  To
+    limit the effects of blow back and other third party spam, Mailman will
+    only send a certain number of such automatic response per day.  After the
+    maximum is reached, it will not send another such response to the same
+    address until the next day.
+    """
+    address = Attribute("""The email address being sent the auto-response.""")
+
+    mailing_list = Attribute(
+        """The mailing list sending the auto-response.""")
+
+    response_type = Attribute("""The type of response sent.""")
+
+
+
+class IAutoResponseSet(Interface):
+    """Matching and setting auto-responses.
+
+    The `IAutoResponseSet` is contexted to a particular mailing list.
+    """
+
+    def todays_count(address, response_type):
+        """The number of responses sent to an address today.
+
+        :param address: The address who is the recipient of the auto-response.
+        :type address: `IAddress`
+        :param response_type: The response type being sent.
+        :type response_type: `Response`
+        :return: The number of auto-responses already received by the user
+            today, of this type, from this mailing list.
+        :rtype: int
+        """
+
+    def response_sent(address, response_type):
+        """Record the fact that another response is being sent to the address.
+
+        :param address: The address who is the recipient of the auto-response.
+        :type address: `IAddress`
+        :param response_type: The response type being sent.
+        :type response_type: `Response`
+        """



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

Your team Mailman Checkins is subscribed to branch lp:mailman.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+edit-subscription.
_______________________________________________
Mailman-checkins mailing list
[email protected]
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org

Reply via email to