diff options
| author | Aurélien Bompard | 2015-03-25 19:21:38 +0100 |
|---|---|---|
| committer | Aurélien Bompard | 2015-03-25 19:21:38 +0100 |
| commit | 035d023662e1347e7dc3a5347d17932bfbe8c7e3 (patch) | |
| tree | 492ed913e0dd5df2c819261d358c73c4ea989873 /src | |
| parent | 990f3c63814bcfddef2e661248c44e67e945de04 (diff) | |
| download | mailman-035d023662e1347e7dc3a5347d17932bfbe8c7e3.tar.gz mailman-035d023662e1347e7dc3a5347d17932bfbe8c7e3.tar.zst mailman-035d023662e1347e7dc3a5347d17932bfbe8c7e3.zip | |
Diffstat (limited to 'src')
| -rw-r--r-- | src/mailman/app/subscriptions.py | 16 | ||||
| -rw-r--r-- | src/mailman/app/tests/test_subscriptions.py | 15 | ||||
| -rw-r--r-- | src/mailman/config/configure.zcml | 4 | ||||
| -rw-r--r-- | src/mailman/interfaces/workflowstate.py | 30 | ||||
| -rw-r--r-- | src/mailman/model/workflowstate.py | 27 |
5 files changed, 88 insertions, 4 deletions
diff --git a/src/mailman/app/subscriptions.py b/src/mailman/app/subscriptions.py index ca84e091f..04e0955cb 100644 --- a/src/mailman/app/subscriptions.py +++ b/src/mailman/app/subscriptions.py @@ -44,6 +44,7 @@ from mailman.interfaces.subscriptions import ( ISubscriptionService, MissingUserError, RequestRecord) from mailman.interfaces.user import IUser from mailman.interfaces.usermanager import IUserManager +from mailman.interfaces.workflowstate import IWorkflowStateManager from mailman.model.member import Member from mailman.utilities.datetime import now @@ -74,6 +75,7 @@ class SubscriptionWorkflow: self.pre_verified = pre_verified self.pre_confirmed = pre_confirmed self.pre_approved = pre_approved + self._save_key = "{}:{}".format(self.mlist.list_id, self.address.email) # Prepare the state machine. self._next = deque() self._next.append("verification_check") @@ -95,6 +97,20 @@ class SubscriptionWorkflow: except: raise + def save_state(self): + manager = getUtility(IWorkflowStateManager) + # Note: only the next step is saved, not the whole stack. Not an issue + # since there's never more than a single step in the queue anyway. + # Also: we don't save & restore the self.pre_* variables, but we could, + # using the data argument. + manager.save(self.__class__.__name__, self._save_key, self._next[0]) + + def restore_state(self): + manager = getUtility(IWorkflowStateManager) + state = manager.restore(self.__class__.__name__, self._save_key) + if state is not None: + self._next[0] = state.step + def _maybe_set_preferred_address(self): if self.user is None: # The address has no linked user so create one, link it, and set diff --git a/src/mailman/app/tests/test_subscriptions.py b/src/mailman/app/tests/test_subscriptions.py index 7bb59bb45..97dbd8382 100644 --- a/src/mailman/app/tests/test_subscriptions.py +++ b/src/mailman/app/tests/test_subscriptions.py @@ -82,6 +82,21 @@ class TestSubscriptionWorkflow(unittest.TestCase): self._anne = 'anne@example.com' self._user_manager = getUtility(IUserManager) + def test_save_restore(self): + anne = self._user_manager.create_address(self._anne, 'Anne Person') + workflow = SubscriptionWorkflow( + self._mlist, anne, + pre_verified=True, pre_confirmed=False, pre_approved=False) + next(workflow) + next_step = workflow._next[0] + workflow.save_state() + # Now create a new instance and restore + workflow = SubscriptionWorkflow( + self._mlist, anne, + pre_verified=True, pre_confirmed=False, pre_approved=False) + workflow.restore_state() + self.assertEqual(next_step, workflow._next[0]) + def test_preverified_address_joins_open_list(self): # The mailing list has an open subscription policy, so the subscriber # becomes a member with no human intervention. diff --git a/src/mailman/config/configure.zcml b/src/mailman/config/configure.zcml index 6f5876aa8..f6cb6dac1 100644 --- a/src/mailman/config/configure.zcml +++ b/src/mailman/config/configure.zcml @@ -118,8 +118,8 @@ /> <utility - provides="mailman.interfaces.workflowstate.IWorkflowState" - factory="mailman.model.workflowstate.WorkflowState" + provides="mailman.interfaces.workflowstate.IWorkflowStateManager" + factory="mailman.model.workflowstate.WorkflowStateManager" /> </configure> diff --git a/src/mailman/interfaces/workflowstate.py b/src/mailman/interfaces/workflowstate.py index bb08fef2d..186386170 100644 --- a/src/mailman/interfaces/workflowstate.py +++ b/src/mailman/interfaces/workflowstate.py @@ -19,6 +19,7 @@ __all__ = [ 'IWorkflowState', + 'IWorkflowStateManager', ] @@ -27,7 +28,7 @@ from zope.interface import Interface, Attribute class IWorkflowState(Interface): - """A basic user.""" + """The state of a workflow.""" name = Attribute( """The name of the workflow.""") @@ -40,3 +41,30 @@ class IWorkflowState(Interface): data = Attribute( """Additional data (may be JSON-encodedeJSON .""") + + + +class IWorkflowStateManager(Interface): + """The workflow states manager.""" + + def save(name, key, step, data=None): + """Save the state of a workflow + + :param name: The name of the workflow. + :type name: str + :param key: A unique key identifying this workflow instance. + :type key: str + :param step: The next step for this workflow. + :type step: str + :param data: Additional data (workflow-specific). + :type data: str + """ + + def restore(name, key): + """Get the saved state for a workflow or None if nothing was saved. + + :param name: The name of the workflow. + :type name: str + :param key: A unique key identifying this workflow instance. + :type key: str + """ diff --git a/src/mailman/model/workflowstate.py b/src/mailman/model/workflowstate.py index 5e3301dcf..ee0226d61 100644 --- a/src/mailman/model/workflowstate.py +++ b/src/mailman/model/workflowstate.py @@ -19,11 +19,14 @@ __all__ = [ 'WorkflowState', + 'WorkflowStateManager', ] from mailman.database.model import Model -from mailman.interfaces.workflowstate import IWorkflowState +from mailman.database.transaction import dbconnection +from mailman.interfaces.workflowstate import ( + IWorkflowState, IWorkflowStateManager) from sqlalchemy import Column, Unicode from zope.interface import implementer @@ -39,3 +42,25 @@ class WorkflowState(Model): key = Column(Unicode, primary_key=True) step = Column(Unicode, nullable=False) data = Column(Unicode) + + + +@implementer(IWorkflowStateManager) +class WorkflowStateManager: + """See `IWorkflowStateManager`.""" + + @dbconnection + def save(self, store, name, key, step, data=None): + """See `IWorkflowStateManager`.""" + state = store.query(WorkflowState).get((name, key)) + if state is None: + state = store.add(WorkflowState( + name=name, key=key, step=step, data=data)) + else: + state.step = step + state.data = data + + @dbconnection + def restore(self, store, name, key): + """See `IWorkflowStateManager`.""" + return store.query(WorkflowState).get((name, key)) |
