diff options
| author | Barry Warsaw | 2007-06-09 15:20:32 -0400 |
|---|---|---|
| committer | Barry Warsaw | 2007-06-09 15:20:32 -0400 |
| commit | 3231fd628f6eea30bd6e2be56eb419ed0008d954 (patch) | |
| tree | 176f80a7b4f72c410e30ab9ba3e3fe2deb1bb1fe /Mailman/database/model/roster.py | |
| parent | e5c04e2a93a58d799dd3940a7935853eb1f2e3e4 (diff) | |
| download | mailman-3231fd628f6eea30bd6e2be56eb419ed0008d954.tar.gz mailman-3231fd628f6eea30bd6e2be56eb419ed0008d954.tar.zst mailman-3231fd628f6eea30bd6e2be56eb419ed0008d954.zip | |
Diffstat (limited to 'Mailman/database/model/roster.py')
| -rw-r--r-- | Mailman/database/model/roster.py | 177 |
1 files changed, 152 insertions, 25 deletions
diff --git a/Mailman/database/model/roster.py b/Mailman/database/model/roster.py index bf8447433..03aa9efc3 100644 --- a/Mailman/database/model/roster.py +++ b/Mailman/database/model/roster.py @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2007 by the Free Software Foundation, Inc. +# Copyright (C) 2007 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -15,37 +15,164 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, # USA. -from elixir import * +"""An implementation of an IRoster. + +These are hard-coded rosters which know how to filter a set of members to find +the ones that fit a particular role. These are used as the member, owner, +moderator, and administrator roster filters. +""" + from zope.interface import implements -from Mailman.Errors import ExistingAddressError +from Mailman.constants import DeliveryMode, MemberRole +from Mailman.database.model import Member from Mailman.interfaces import IRoster -ADDRESS_KIND = 'Mailman.database.model.address.Address' -ROSTERSET_KIND = 'Mailman.database.model.rosterset.RosterSet' + +class AbstractRoster(object): + """An abstract IRoster class. + This class takes the simple approach of implemented the 'users' and + 'addresses' properties in terms of the 'members' property. This may not + be the most efficient way, but it works. -class Roster(Entity): + This requires that subclasses implement the 'members' property. + """ implements(IRoster) - has_field('name', Unicode) - # Relationships - has_and_belongs_to_many('addresses', of_kind=ADDRESS_KIND) - has_and_belongs_to_many('roster_set', of_kind=ROSTERSET_KIND) + def __init__(self, mlist): + self._mlist = mlist + + @property + def members(self): + raise NotImplementedError + + @property + def users(self): + # Members are linked to addresses, which in turn are linked to users. + # So while the 'members' attribute does most of the work, we have to + # keep a set of unique users. It's possible for the same user to be + # subscribed to a mailing list multiple times with different + # addresses. + users = set(member.address.user for member in self.members) + for user in users: + yield user + + @property + def addresses(self): + # Every Member is linked to exactly one address so the 'members' + # attribute does most of the work. + for member in self.members: + yield member.address + + + +class MemberRoster(AbstractRoster): + """Return all the members of a list.""" + + name = 'member' + + @property + def members(self): + # Query for all the Members which have a role of MemberRole.member and + # are subscribed to this mailing list. XXX we have to use a private + # data attribute of MailList for now. + for member in Member.select_by(mailing_list=self._mlist.fqdn_listname, + role=MemberRole.member): + yield member + + + +class OwnerRoster(AbstractRoster): + """Return all the owners of a list.""" + + name = 'owner' + + @property + def members(self): + # Query for all the Members which have a role of MemberRole.member and + # are subscribed to this mailing list. XXX we have to use a private + # data attribute of MailList for now. + for member in Member.select_by(mailing_list=self._mlist.fqdn_listname, + role=MemberRole.owner): + yield member + + + +class ModeratorRoster(AbstractRoster): + """Return all the owners of a list.""" + + name = 'moderator' + + @property + def members(self): + # Query for all the Members which have a role of MemberRole.member and + # are subscribed to this mailing list. XXX we have to use a private + # data attribute of MailList for now. + for member in Member.select_by(mailing_list=self._mlist.fqdn_listname, + role=MemberRole.moderator): + yield member + + + +class AdministratorRoster(AbstractRoster): + """Return all the administrators of a list.""" + + name = 'administrator' + + @property + def members(self): + # Administrators are defined as the union of the owners and the + # moderators. Until I figure out a more efficient way of doing this, + # this will have to do. + owners = Member.select_by(mailing_list=self._mlist.fqdn_listname, + role=MemberRole.owner) + moderators = Member.select_by(mailing_list=self._mlist.fqdn_listname, + role=MemberRole.moderator) + members = set(owners) + members.update(set(moderators)) + for member in members: + yield member + + + +class RegularMemberRoster(AbstractRoster): + """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 Member.select_by(mailing_list=self._mlist.fqdn_listname, + role=MemberRole.member): + if member.preferences.delivery_mode == DeliveryMode.regular: + yield member + + + +_digest_modes = ( + DeliveryMode.mime_digests, + DeliveryMode.plaintext_digests, + DeliveryMode.summary_digests, + ) + + + +class DigestMemberRoster(AbstractRoster): + """Return all the regular delivery members of a list.""" + + name = 'regular_members' - def create(self, email_address, real_name=None): - """See IRoster""" - from Mailman.database.model.address import Address - addr = Address.get_by(address=email_address) - if addr: - raise ExistingAddressError(email_address) - addr = Address(address=email_address, real_name=real_name) - # Make sure all the expected links are made, including to the null - # (i.e. everyone) roster. - self.addresses.append(addr) - addr.rosters.append(self) - null_roster = Roster.get_by(name='') - null_roster.addresses.append(addr) - addr.rosters.append(null_roster) - return addr + @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 Member.select_by(mailing_list=self._mlist.fqdn_listname, + role=MemberRole.member): + if member.preferences.delivery_mode in _digest_modes: + yield member |
