diff options
| author | Barry Warsaw | 2009-02-22 21:33:17 -0500 |
|---|---|---|
| committer | Barry Warsaw | 2009-02-22 21:33:17 -0500 |
| commit | 2d2d5393acc7db23baf4f3d43a0712bfa795c03e (patch) | |
| tree | f7a41025dde055777aa1b4dd900fad4fc96c3943 /src/mailman/database | |
| parent | 8644b80168066c8fd11a7e2440ed8566453f0cd4 (diff) | |
| download | mailman-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.py | 8 | ||||
| -rw-r--r-- | src/mailman/database/digests.py | 53 | ||||
| -rw-r--r-- | src/mailman/database/mailinglist.py | 21 | ||||
| -rw-r--r-- | src/mailman/database/mailman.sql | 12 | ||||
| -rw-r--r-- | src/mailman/database/roster.py | 59 |
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 |
