summaryrefslogtreecommitdiff
path: root/src/mailman/app/subscriptions.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/mailman/app/subscriptions.py')
-rw-r--r--src/mailman/app/subscriptions.py81
1 files changed, 48 insertions, 33 deletions
diff --git a/src/mailman/app/subscriptions.py b/src/mailman/app/subscriptions.py
index ab8c3d53c..f11494e75 100644
--- a/src/mailman/app/subscriptions.py
+++ b/src/mailman/app/subscriptions.py
@@ -22,6 +22,7 @@ from __future__ import absolute_import, unicode_literals
__metaclass__ = type
__all__ = [
'SubscriptionService',
+ 'handle_ListDeleteEvent',
]
@@ -34,7 +35,8 @@ from mailman.app.membership import add_member, delete_member
from mailman.config import config
from mailman.core.constants import system_preferences
from mailman.interfaces.address import InvalidEmailAddressError
-from mailman.interfaces.listmanager import IListManager, NoSuchListError
+from mailman.interfaces.listmanager import (
+ IListManager, ListDeletedEvent, NoSuchListError)
from mailman.interfaces.member import DeliveryMode
from mailman.interfaces.subscriptions import (
ISubscriptionService, MissingUserError)
@@ -93,43 +95,43 @@ class SubscriptionService:
assert members.count() == 1, 'Too many matching members'
return members[0]
- def find_members(self, subscriber, fqdn_listname=None, role=None):
+ def find_members(self, subscriber=None, fqdn_listname=None, role=None):
"""See `ISubscriptionService`."""
# If `subscriber` is a user id, then we'll search for all addresses
# which are controlled by the user, otherwise we'll just search for
# the given address.
user_manager = getUtility(IUserManager)
- query = None
- if isinstance(subscriber, basestring):
- # subscriber is an email address.
- address = user_manager.get_address(subscriber)
- user = user_manager.get_user(subscriber)
- # This probably could be made more efficient.
- if address is None or user is None:
- return []
- or_clause = Or(Member.address_id == address.id,
- Member.user_id == user.id)
- else:
- # subscriber is a user id.
- user = user_manager.get_user_by_id(unicode(subscriber))
- address_ids = list(address.id for address in user.addresses
- if address.id is not None)
- if len(address_ids) == 0 or user is None:
- return []
- or_clause = Or(Member.user_id == user.id,
- Member.address_id.is_in(address_ids))
- # The rest is the same, based on the given criteria.
- if fqdn_listname is None and role is None:
- query = or_clause
- elif fqdn_listname is None:
- query = And(Member.role == role, or_clause)
- elif role is None:
- query = And(Member.mailing_list == fqdn_listname, or_clause)
- else:
- query = And(Member.mailing_list == fqdn_listname,
- Member.role == role,
- or_clause)
- results = config.db.store.find(Member, query)
+ if subscriber is None and fqdn_listname is None and role is None:
+ return []
+ # Querying for the subscriber is the most complicated part, because
+ # the parameter can either be an email address or a user id.
+ query = []
+ if subscriber is not None:
+ if isinstance(subscriber, basestring):
+ # subscriber is an email address.
+ address = user_manager.get_address(subscriber)
+ user = user_manager.get_user(subscriber)
+ # This probably could be made more efficient.
+ if address is None or user is None:
+ return []
+ query.append(Or(Member.address_id == address.id,
+ Member.user_id == user.id))
+ else:
+ # subscriber is a user id.
+ user = user_manager.get_user_by_id(unicode(subscriber))
+ address_ids = list(address.id for address in user.addresses
+ if address.id is not None)
+ if len(address_ids) == 0 or user is None:
+ return []
+ query.append(Or(Member.user_id == user.id,
+ Member.address_id.is_in(address_ids)))
+ # Calculate the rest of the query expression, which will get And'd
+ # with the Or clause above (if there is one).
+ if fqdn_listname is not None:
+ query.append(Member.mailing_list == fqdn_listname)
+ if role is not None:
+ query.append(Member.role == role)
+ results = config.db.store.find(Member, And(*query))
return sorted(results, key=_membership_sort_key)
def __iter__(self):
@@ -177,3 +179,16 @@ class SubscriptionService:
raise NoSuchListError(fqdn_listname)
# XXX for now, no notification or user acknowledgement.
delete_member(mlist, address, False, False)
+
+
+
+def handle_ListDeletedEvent(event):
+ """Delete a mailing list's members when the list is deleted."""
+
+ if not isinstance(event, ListDeletedEvent):
+ return
+ # Find all the members still associated with the mailing list.
+ members = getUtility(ISubscriptionService).find_members(
+ fqdn_listname=event.fqdn_listname)
+ for member in members:
+ member.unsubscribe()