summaryrefslogtreecommitdiff
path: root/src/mailman/database
diff options
context:
space:
mode:
authorBarry Warsaw2009-02-22 21:33:17 -0500
committerBarry Warsaw2009-02-22 21:33:17 -0500
commit2d2d5393acc7db23baf4f3d43a0712bfa795c03e (patch)
treef7a41025dde055777aa1b4dd900fad4fc96c3943 /src/mailman/database
parent8644b80168066c8fd11a7e2440ed8566453f0cd4 (diff)
downloadmailman-2d2d5393acc7db23baf4f3d43a0712bfa795c03e.tar.gz
mailman-2d2d5393acc7db23baf4f3d43a0712bfa795c03e.tar.zst
mailman-2d2d5393acc7db23baf4f3d43a0712bfa795c03e.zip
Get rid of one_last_digest. Move this into a separate OneLastDigest table.
Make it explicit to get the last digest (I could imagine an user selecting not to). Actually add tests for this. Start to get rid of 'from storm.locals import *' in favor of more specific imports. Start to use Store.of() instead of config.db.store where we can. Rework (delivery)MemberRosters to use the Member attributes. This ensures that the layered lookup happens at the expense of query optimization. Sundry and various cleanups.
Diffstat (limited to 'src/mailman/database')
-rw-r--r--src/mailman/database/address.py8
-rw-r--r--src/mailman/database/digests.py53
-rw-r--r--src/mailman/database/mailinglist.py21
-rw-r--r--src/mailman/database/mailman.sql12
-rw-r--r--src/mailman/database/roster.py59
5 files changed, 117 insertions, 36 deletions
diff --git a/src/mailman/database/address.py b/src/mailman/database/address.py
index 528d3af51..f63f03e14 100644
--- a/src/mailman/database/address.py
+++ b/src/mailman/database/address.py
@@ -26,10 +26,9 @@ __all__ = [
from email.utils import formataddr
-from storm.locals import *
+from storm.locals import DateTime, Int, Reference, Store, Unicode
from zope.interface import implements
-from mailman.config import config
from mailman.database.member import Member
from mailman.database.model import Model
from mailman.database.preferences import Preferences
@@ -76,7 +75,8 @@ class Address(Model):
def subscribe(self, mailing_list, role):
# This member has no preferences by default.
- member = config.db.store.find(
+ store = Store.of(self)
+ member = store.find(
Member,
Member.role == role,
Member.mailing_list == mailing_list.fqdn_listname,
@@ -88,7 +88,7 @@ class Address(Model):
mailing_list=mailing_list.fqdn_listname,
address=self)
member.preferences = Preferences()
- config.db.store.add(member)
+ store.add(member)
return member
@property
diff --git a/src/mailman/database/digests.py b/src/mailman/database/digests.py
new file mode 100644
index 000000000..291dafa28
--- /dev/null
+++ b/src/mailman/database/digests.py
@@ -0,0 +1,53 @@
+# 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/>.
+
+"""One last digest."""
+
+from __future__ import absolute_import, unicode_literals
+
+__metaclass__ = type
+__all__ = [
+ 'OneLastDigest',
+ ]
+
+
+from storm.locals import Int, Reference
+from zope.interface import implements
+
+from mailman.database.model import Model
+from mailman.database.types import Enum
+from mailman.interfaces.digests import IOneLastDigest
+
+
+
+class OneLastDigest(Model):
+ implements(IOneLastDigest)
+
+ id = Int(primary=True)
+
+ mailing_list_id = Int()
+ mailing_list = Reference(mailing_list_id, 'MailingList.id')
+
+ address_id = Int()
+ address = Reference(address_id, 'Address.id')
+
+ delivery_mode = Enum()
+
+ def __init__(self, mailing_list, address, delivery_mode):
+ self.mailing_list = mailing_list
+ self.address = address
+ self.delivery_mode = delivery_mode
diff --git a/src/mailman/database/mailinglist.py b/src/mailman/database/mailinglist.py
index 9141ad64c..2956cac57 100644
--- a/src/mailman/database/mailinglist.py
+++ b/src/mailman/database/mailinglist.py
@@ -28,12 +28,14 @@ __all__ = [
import os
import string
-from storm.locals import *
+from storm.locals import (
+ Bool, DateTime, Float, Int, Pickle, Store, TimeDelta, Unicode)
from urlparse import urljoin
from zope.interface import implements
from mailman.config import config
from mailman.database import roster
+from mailman.database.digests import OneLastDigest
from mailman.database.model import Model
from mailman.database.types import Enum
from mailman.interfaces.mailinglist import IMailingList, Personalization
@@ -63,7 +65,6 @@ class MailingList(Model):
next_request_id = Int()
next_digest_number = Int()
digest_last_sent_at = DateTime()
- one_last_digest = Pickle()
volume = Int()
last_post_time = DateTime()
# Attributes which are directly modifiable via the web u/i. The more
@@ -276,3 +277,19 @@ class MailingList(Model):
self._preferred_language = language.code
except AttributeError:
self._preferred_language = language
+
+ def send_one_last_digest_to(self, address, delivery_mode):
+ """See `IMailingList`."""
+ digest = OneLastDigest(self, address, delivery_mode)
+ Store.of(self).add(digest)
+
+ @property
+ def last_digest_recipients(self):
+ """See `IMailingList`."""
+ results = Store.of(self).find(
+ OneLastDigest,
+ OneLastDigest.mailing_list == self)
+ recipients = [(digest.address, digest.delivery_mode)
+ for digest in results]
+ results.remove()
+ return recipients
diff --git a/src/mailman/database/mailman.sql b/src/mailman/database/mailman.sql
index c46fb193e..79a28574e 100644
--- a/src/mailman/database/mailman.sql
+++ b/src/mailman/database/mailman.sql
@@ -54,7 +54,6 @@ CREATE TABLE mailinglist (
next_request_id INTEGER,
next_digest_number INTEGER,
digest_last_sent_at TIMESTAMP,
- one_last_digest BLOB,
volume INTEGER,
last_post_time TIMESTAMP,
accept_these_nonmembers BLOB,
@@ -178,6 +177,17 @@ CREATE TABLE message (
message_id TEXT,
PRIMARY KEY (id)
);
+CREATE TABLE onelastdigest (
+ id INTEGER NOT NULL,
+ mailing_list_id INTEGER,
+ address_id INTEGER,
+ delivery_mode TEXT,
+ PRIMARY KEY (id),
+ CONSTRAINT onelastdigest_mailing_list_id_fk
+ FOREIGN KEY(mailing_list_id) REFERENCES mailinglist(id),
+ CONSTRAINT onelastdigest_address_id_fk
+ FOREIGN KEY(address_id) REFERENCES address(id)
+ );
CREATE TABLE pended (
id INTEGER NOT NULL,
token TEXT,
diff --git a/src/mailman/database/roster.py b/src/mailman/database/roster.py
index fc0a24c7d..3b8ba4c4c 100644
--- a/src/mailman/database/roster.py
+++ b/src/mailman/database/roster.py
@@ -37,12 +37,13 @@ __all__ = [
]
-from storm.locals import *
+from storm.expr import And, LeftJoin, Or
from zope.interface import implements
from mailman.config import config
from mailman.database.address import Address
from mailman.database.member import Member
+from mailman.database.preferences import Preferences
from mailman.interfaces.member import DeliveryMode, MemberRole
from mailman.interfaces.roster import IRoster
@@ -167,49 +168,49 @@ class AdministratorRoster(AbstractRoster):
-class RegularMemberRoster(AbstractRoster):
+class DeliveryMemberRoster(AbstractRoster):
+ """Return all the members having a particular kind of delivery."""
+
+ def _get_members(self, *delivery_modes):
+ """The set of members for a mailing list, filter by delivery mode.
+
+ :param delivery_modes: The modes to filter on.
+ :type delivery_modes: sequence of `DeliveryMode`.
+ :return: A generator of members.
+ :rtype: generator
+ """
+ results = config.db.store.find(
+ Member,
+ And(Member.mailing_list == self._mlist.fqdn_listname,
+ Member.role == MemberRole.member))
+ for member in results:
+ if member.delivery_mode in delivery_modes:
+ yield member
+
+
+class RegularMemberRoster(DeliveryMemberRoster):
"""Return all the regular delivery members of a list."""
name = 'regular_members'
@property
def members(self):
- # Query for all the Members which have a role of MemberRole.member and
- # are subscribed to this mailing list. Then return only those members
- # that have a regular delivery mode.
- for member in config.db.store.find(
- Member,
- mailing_list=self._mlist.fqdn_listname,
- role=MemberRole.member):
- if member.delivery_mode == DeliveryMode.regular:
- yield member
+ for member in self._get_members(DeliveryMode.regular):
+ yield member
-_digest_modes = (
- DeliveryMode.mime_digests,
- DeliveryMode.plaintext_digests,
- DeliveryMode.summary_digests,
- )
-
-
-
-class DigestMemberRoster(AbstractRoster):
+class DigestMemberRoster(DeliveryMemberRoster):
"""Return all the regular delivery members of a list."""
name = 'digest_members'
@property
def members(self):
- # Query for all the Members which have a role of MemberRole.member and
- # are subscribed to this mailing list. Then return only those members
- # that have one of the digest delivery modes.
- for member in config.db.store.find(
- Member,
- mailing_list=self._mlist.fqdn_listname,
- role=MemberRole.member):
- if member.delivery_mode in _digest_modes:
- yield member
+ for member in self._get_members(DeliveryMode.plaintext_digests,
+ DeliveryMode.mime_digests,
+ DeliveryMode.summary_digests):
+ yield member