src/pyams_workflow/versions.py
changeset 11 f25326715002
parent 5 43c135a76ab2
child 16 ceca681f8c3a
equal deleted inserted replaced
10:41ac20351fe2 11:f25326715002
    16 # import standard library
    16 # import standard library
    17 from datetime import datetime
    17 from datetime import datetime
    18 
    18 
    19 # import interfaces
    19 # import interfaces
    20 from pyams_workflow.interfaces import IWorkflowVersions, IWorkflowManagedContent, VersionError, IWorkflowState, \
    20 from pyams_workflow.interfaces import IWorkflowVersions, IWorkflowManagedContent, VersionError, IWorkflowState, \
    21     IWorkflowVersion, IWorkflowStateHistoryItem, IWorkflowTransitionEvent, IWorkflowVersionTransitionEvent
    21     IWorkflowVersion, IWorkflowStateHistoryItem, IWorkflowTransitionEvent, IWorkflowVersionTransitionEvent, IWorkflow
    22 from zope.annotation.interfaces import IAnnotations
    22 from zope.annotation.interfaces import IAnnotations
       
    23 from zope.location.interfaces import ISublocations
    23 from zope.traversing.interfaces import ITraversable
    24 from zope.traversing.interfaces import ITraversable
    24 
    25 
    25 # import packages
    26 # import packages
    26 from persistent import Persistent
    27 from persistent import Persistent
    27 from persistent.list import PersistentList
    28 from persistent.list import PersistentList
    28 from persistent.mapping import PersistentMapping
    29 from persistent.mapping import PersistentMapping
    29 from pyams_utils.adapter import adapter_config, ContextAdapter
    30 from pyams_utils.adapter import adapter_config, ContextAdapter
    30 from pyams_utils.request import check_request
    31 from pyams_utils.registry import get_utility
       
    32 from pyams_utils.request import check_request, query_request
    31 from pyams_utils.traversing import get_parent
    33 from pyams_utils.traversing import get_parent
    32 from pyramid.events import subscriber
    34 from pyramid.events import subscriber
    33 from pyramid.threadlocal import get_current_registry
    35 from pyramid.threadlocal import get_current_registry
    34 from zope.container.folder import Folder
    36 from zope.container.folder import Folder
    35 from zope.interface import implementer, alsoProvides
    37 from zope.interface import implementer, alsoProvides
    58 @implementer(IWorkflowState)
    60 @implementer(IWorkflowState)
    59 class WorkflowVersionState(Persistent):
    61 class WorkflowVersionState(Persistent):
    60     """Workflow managed content version object"""
    62     """Workflow managed content version object"""
    61 
    63 
    62     version_id = None
    64     version_id = None
    63     state = None
    65     _state = None
       
    66     _state_date = FieldProperty(IWorkflowState['state_date'])
       
    67     _state_principal = FieldProperty(IWorkflowState['state_principal'])
    64 
    68 
    65     def __init__(self):
    69     def __init__(self):
    66         self.history = PersistentList()
    70         self.history = PersistentList()
       
    71 
       
    72     @property
       
    73     def state(self):
       
    74         return self._state
       
    75 
       
    76     @state.setter
       
    77     def state(self, value):
       
    78         self._state = value
       
    79         self._state_date = datetime.utcnow()
       
    80         request = query_request()
       
    81         if request is not None:
       
    82             self._state_principal = request.principal.id
       
    83 
       
    84     @property
       
    85     def state_date(self):
       
    86         return self._state_date
       
    87 
       
    88     @property
       
    89     def state_principal(self):
       
    90         return self._state_principal
    67 
    91 
    68 
    92 
    69 @subscriber(IWorkflowTransitionEvent)
    93 @subscriber(IWorkflowTransitionEvent)
    70 def handle_workflow_transition(event):
    94 def handle_workflow_transition(event):
    71     """Handle workflow transition"""
    95     """Handle workflow transition"""
    72     if IWorkflowVersionTransitionEvent.providedBy(event):
    96     if IWorkflowVersionTransitionEvent.providedBy(event):
    73         return
    97         return
       
    98     workflow = event.workflow
    74     request = check_request()
    99     request = check_request()
       
   100     translate = request.localizer.translate
    75     item = WorkflowHistoryItem(date=datetime.utcnow(),
   101     item = WorkflowHistoryItem(date=datetime.utcnow(),
    76                                source_state=event.source,
   102                                source_state=translate(workflow.states.getTerm(event.source).title)
    77                                target_state=event.destination,
   103                                             if event.source else None,
    78                                transition=event.transition.title,
   104                                target_state=translate(workflow.states.getTerm(event.destination).title),
       
   105                                transition=translate(event.transition.title),
    79                                principal=request.principal.id,
   106                                principal=request.principal.id,
    80                                comment=event.comment)
   107                                comment=event.comment)
    81     IWorkflowState(event.object).history.append(item)
   108     IWorkflowState(event.object).history.append(item)
    82 
   109 
    83 
   110 
    84 @subscriber(IWorkflowVersionTransitionEvent)
   111 @subscriber(IWorkflowVersionTransitionEvent)
    85 def handle_workflow_version_transition(event):
   112 def handle_workflow_version_transition(event):
    86     """Handle workflow version transition"""
   113     """Handle workflow version transition"""
       
   114     workflow = event.workflow
    87     request = check_request()
   115     request = check_request()
       
   116     translate = request.localizer.translate
    88     item = WorkflowHistoryItem(date=datetime.utcnow(),
   117     item = WorkflowHistoryItem(date=datetime.utcnow(),
    89                                source_version=IWorkflowState(event.old_object).version_id,
   118                                source_version=IWorkflowState(event.old_object).version_id,
    90                                source_state=event.source,
   119                                source_state=translate(workflow.states.getTerm(event.source).title),
    91                                target_state=event.destination,
   120                                target_state=translate(workflow.states.getTerm(event.destination).title),
    92                                transition=event.transition.title,
   121                                transition=translate(event.transition.title),
    93                                principal=request.principal.id,
   122                                principal=request.principal.id,
    94                                comment=event.comment)
   123                                comment=event.comment)
    95     IWorkflowState(event.object).history.append(item)
   124     IWorkflowState(event.object).history.append(item)
    96 
   125 
    97 
   126 
   191     def has_version(self, state):
   220     def has_version(self, state):
   192         if state is None:
   221         if state is None:
   193             state = '__none__'
   222             state = '__none__'
   194         return bool(self.versions_by_state.get(state, ()))
   223         return bool(self.versions_by_state.get(state, ()))
   195 
   224 
   196     def remove_version(self, version_id):
   225     def remove_version(self, version_id, state='deleted', comment=None):
   197         if str(version_id) not in self:
   226         if str(version_id) not in self:
   198             pass
   227             return
       
   228         # update version state
       
   229         version = self[str(version_id)]
       
   230         wf_state = IWorkflowState(version)
       
   231         if comment:
       
   232             request = check_request()
       
   233             translate = request.localizer.translate
       
   234             workflow = get_utility(IWorkflow, name=get_parent(self, IWorkflowManagedContent).workflow_name)
       
   235             item = WorkflowHistoryItem(date=datetime.utcnow(),
       
   236                                        source_version=wf_state.version_id,
       
   237                                        source_state=translate(workflow.states.getTerm(wf_state.state).title),
       
   238                                        target_state=translate(workflow.states.getTerm(state).title),
       
   239                                        principal=request.principal.id,
       
   240                                        comment=comment)
       
   241             wf_state.history.append(item)
       
   242         wf_state.state = state
       
   243         # remove given version
   199         state = self.state_by_version[version_id]
   244         state = self.state_by_version[version_id]
   200         versions = self.versions_by_state[state]
   245         versions = self.versions_by_state[state]
   201         versions.remove(version_id)
   246         versions.remove(version_id)
   202         if versions:
   247         if versions:
   203             self.versions_by_state[state] = versions
   248             self.versions_by_state[state] = versions
   240         versions = IWorkflowVersions(self.context)
   285         versions = IWorkflowVersions(self.context)
   241         if name:
   286         if name:
   242             return versions[name]
   287             return versions[name]
   243         else:
   288         else:
   244             return versions
   289             return versions
       
   290 
       
   291 
       
   292 @adapter_config(name='versions', context=IWorkflowManagedContent, provides=ISublocations)
       
   293 class WorkflowVersionsSublocations(ContextAdapter):
       
   294     """Workflow versions sub-locations"""
       
   295 
       
   296     def sublocations(self):
       
   297         return IWorkflowVersions(self.context).values()