summaryrefslogtreecommitdiff
path: root/Mailman/database/model/roster.py
diff options
context:
space:
mode:
authorBarry Warsaw2007-06-09 15:20:32 -0400
committerBarry Warsaw2007-06-09 15:20:32 -0400
commit3231fd628f6eea30bd6e2be56eb419ed0008d954 (patch)
tree176f80a7b4f72c410e30ab9ba3e3fe2deb1bb1fe /Mailman/database/model/roster.py
parente5c04e2a93a58d799dd3940a7935853eb1f2e3e4 (diff)
downloadmailman-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.py177
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