# Copyright (C) 2009-2017 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 . """Handle subscriptions.""" from mailman.config import config from mailman.database.transaction import flush from mailman.interfaces.listmanager import ListDeletingEvent from mailman.interfaces.pending import IPendings from mailman.interfaces.subscriptions import ( ISubscriptionManager, ISubscriptionService) from mailman.interfaces.workflows import IWorkflowStateManager from mailman.workflows.common import (PendableSubscription, PendableUnsubscription) from public import public from zope.component import getUtility from zope.interface import implementer @public @implementer(ISubscriptionManager) class SubscriptionManager: def __init__(self, mlist): self._mlist = mlist def register(self, subscriber=None, **kwargs): """See `ISubscriptionManager`.""" workflow = self._mlist.subscription_policy(self._mlist, subscriber, **kwargs) list(workflow) return workflow.token, workflow.token_owner, workflow.member def unregister(self, subscriber=None, **kwargs): workflow = self._mlist.unsubscription_policy(self._mlist, subscriber, **kwargs) list(workflow) return workflow.token, workflow.token_owner, workflow.member def confirm(self, token): if token is None: raise LookupError pendable = getUtility(IPendings).confirm(token, expunge=False) if pendable is None: raise LookupError workflow_type = pendable.get('type') if workflow_type in {PendableSubscription.PEND_TYPE, PendableUnsubscription.PEND_TYPE}: workflow = (self._mlist.subscription_policy # pragma: nocover if workflow_type == PendableSubscription.PEND_TYPE else self._mlist.unsubscription_policy)(self._mlist) else: workflow = config.workflows[workflow_type](self._mlist) workflow.token = token workflow.restore() # In order to just run the whole workflow, all we need to do # is iterate over the workflow object. On calling the __next__ # over the workflow iterator it automatically executes the steps # that needs to be done. list(workflow) return workflow.token, workflow.token_owner, workflow.member def discard(self, token): with flush(): getUtility(IPendings).confirm(token) getUtility(IWorkflowStateManager).discard(token) @public def handle_ListDeletingEvent(event): """Delete a mailing list's members when the list is being deleted.""" if not isinstance(event, ListDeletingEvent): return # Find all the members still associated with the mailing list. members = getUtility(ISubscriptionService).find_members( list_id=event.mailing_list.list_id) for member in members: member.unsubscribe()