def start(self, contributor, starttime, message, history, object_): """Parameters: object_: object to be removed. history: the workflow history of this object.""" self.contributor = contributor self.starttime = starttime self.message = message self.object_ = object_ self.history = history # assert that object is removable, i.e. implements IRemovable if not interfaces.IRemovable.providedBy(object_): raise ProcessError( _( 'iremovable-not-provided', u"Unremovable database item. (IRemovable interface not provided.)" )) if interfaces.IFixed.providedBy(object_): raise ProcessError( _('ifixed-provided', u"Database item is fixed and can't be removed.")) #TODO: add some more ways to remove the object if not (IContained.providedBy(object_) or 1 == 2): raise ProcessError( _( 'wfmc-remove-unremovable', u"Unremovable database item. (Could not determine a way who to remove item.)" )) self._appendToWorkList()
class EditMeta(form.EditForm): fields = field.Fields(IZopeDublinCore).select('title', 'description') label = _('edit-meta-label', u"Metadata") info = _('edit-meta-info', u"You can edit the descriptive metadata of the worklist.") def getContent(self): return IZopeDublinCore(self.context, None)
class RemoveRequestForm(form.Form): implements(ITabbedContentLayout) label = _('removerequestform-label', u"Remove database item") info = _( 'removerequestform-info', u"The decision if an item is removed or not will be made by the site's editors. You can ask them to remove this item with the form below. Please give a short reason, why it should be removed." ) process_id = 'quotationtool.remove' @property def action(self): """See interfaces.IInputForm""" return self.request.getURL() + u"#tabs" fields = field.Fields(comment) ignoreContext = True ignoreReadonly = True @button.buttonAndHandler(_(u"Submit"), name='remove') def handleRemove(self, action): data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return history = interfaces.IWorkflowHistory(self.context) principal = getattr(self.request, 'principal', None) pd = zope.component.getUtility(IProcessDefinition, name=self.process_id, context=self.context) proc = pd() # TODO: Note that we have to remove the security proxy! proc.start(getattr(principal, 'id', u"Unkown"), datetime.datetime.now(), data['workflow-message'], removeAllProxies(history), removeAllProxies(self.context)) history.append( UserNotation(getattr(principal, 'id', u"Unknown"), data['workflow-message'])) #self.template = ViewPageTemplateFile('remove_process_started.pt') self.request.response.redirect(self.nextURL()) @button.buttonAndHandler(_(u"Cancel"), name="cancel") def handleCancel(self, action): url = absoluteURL(self.context, self.request) self.request.response.redirect(url) def nextURL(self): return absoluteURL(self.context, self.request) + u"/@@removeProcessStarted.html#tabs"
class FixateRequestForm(form.Form): implements(ITabbedContentLayout) label = _('fixaterequestform-label', u"Fixation of Database Item") info = _( 'fixaterequestform-info', u"Using the form below you can ask the editorial staff to protect this database item against removal (or remove a protection). The site's editors will read your message and decide what to do." ) process_id = 'quotationtool.fixate' @property def action(self): """See interfaces.IInputForm""" return self.request.getURL() + u"#tabs" fields = field.Fields(message) ignoreContext = True ignoreReadonly = True @button.buttonAndHandler(_(u"Submit"), name='fixate') def handleFixate(self, action): data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return history = interfaces.IWorkflowHistory(self.context) principal = getattr(self.request, 'principal', None) pd = zope.component.getUtility(IProcessDefinition, name=self.process_id, context=self.context) proc = pd() # TODO: Note that we have to remove the security proxy! proc.start(getattr(principal, 'id', u"Unkown"), datetime.datetime.now(), data['workflow-message'], removeAllProxies(history), removeAllProxies(self.context)) history.append( UserNotation(getattr(principal, 'id', u"Unknown"), data['workflow-message'])) #self.template = ViewPageTemplateFile('fixate_process_started.pt') self.request.response.redirect(self.nextURL()) @button.buttonAndHandler(_(u"Cancel"), name="cancel") def handleCancel(self, action): url = absoluteURL(self.context, self.request) self.request.response.redirect(url) def nextURL(self): return absoluteURL(self.context, self.request) + u"/@@fixateProcessStarted.html#tabs"
class MessageEditorialReview(form.Form): implements(interfaces.IWorkItemForm) fields = field.Fields(answer) label = _('messageeditorialreview-label', u"Editorial Review of Message") info = _('messageeditorialreview-info', u"Please write an answer to the user's message about the item.") ignoreContext = True ignoreReadonly = True def _handle(self, answr): data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return history = self.context.history principal = getattr(self.request, 'principal', None) history.append( UserNotation(getattr(principal, 'id', u"Unkown"), data['workflow-message'])) #get next URL before removing work item url = self.nextURL() self.context.finish(answr, data['workflow-message']) self.request.response.redirect(url) @button.buttonAndHandler(_(u"Answer"), name="answer") def handleAnswer(self, action): self._handle('answer') @button.buttonAndHandler(_(u"Postpone"), name="postpone") def handlePostpone(self, action): self._handle('postpone') @button.buttonAndHandler(_(u"Cancel"), name="cancel") def handleCancel(self, action): self.request.response.redirect(self.nextURL()) def nextURL(self): return absoluteURL(self.context.__parent__, self.request) def contributor(self): return common.getPrincipalTitle(self.context.contributor) def message(self): return escape(self.context.message).replace('\n', '<br />')
def __repr__(self): return _('transition-notation', u"Transition from '$FROM' to '$TO'.", mapping={ 'FROM': self.from_, 'TO': self.to })
class ObjectLabelColumn(column.Column): """Column displaying the label of the object under workflow control.""" zope.interface.implements(ISortingColumn) header = _('object-column-header', u"Database item") weight = 108 def renderCell(self, item): # 1.1: try to get view named objectLabel for work item label = zope.component.queryMultiAdapter((item, self.request), name='objectLabel') if not label: # 1.2: try to get object from object_ attribute and lookup # label view obj = getattr(item, 'object_', None) if obj is None: # 1.3: return default label return _(u"Unkown") label = zope.component.getMultiAdapter((obj, self.request), name='label') # 2: translate label and return try: return translate(label(), context=self.request) except Exception: return label()
class AccountWorkListTable(table.Table, BrowserPagelet): """ The bibliography printed like a table.""" zope.interface.implements(IWorkListTable, IAccountView) render = BrowserPagelet.render cssClasses = { 'table': u'container-listing', 'thead': u"head", } cssClassEven = u"even" cssClassOdd = u"odd" @property def title(self): return _('account-worklist-title', u"Work Items ($COUNT)", mapping={'COUNT': unicode(self.getCount())}) description = _( 'account-worklist-desc', u"Items saved as 'draft' and other items on your personal to-do list.") visible = True weight = 10 def getCount(self): return len(list(self.values))
def __repr__(self): return _('user-notation', u"$MSG (by $USER)", mapping={ 'MSG': self.msg, 'USER': self.uid })
class LastActivityColumn(column.LinkColumn): """Column representing the dublincore created value. """ zope.interface.implements(ISortingColumn) header = _('last-activity-column-header', u"Last Activity") weight = 220
def finish(self, remove): self.schema['remove'].validate(remove) if remove == 'remove': # assert that the item is still not fixed. if interfaces.IFixed.providedBy(self.object_): raise ProcessError( _('ifixed-provided', u"Database item is fixed and can't be removed.")) # assert that the item asked to be removed is not under # control of other workflow processes similars = [ item for item in interfaces.ISimilarWorkItems( self).getSimilarWorkItems() ] if similars: raise ProcessError( _( 'wfmc-remove-still-similar', u"Failed to remove the object. The database item is still under control of other workflow processes. These must be finished first." )) # assert that the item asked to be removed has no # relations to other items in the database. if len(self.findRelationTokens()) > 0: raise ProcessError( _( 'wfmc-remove-still-relations', u"Failed to remove the object. The database item still has relations." )) # for contained item del it on container if IContained.providedBy(self.object_): container = self.object_.__parent__ del container[self.object_.__name__] else: pass #TODO: add some more ways to remove the object # we remove the work item on remove=='postpone', too. It gets # added by start again. self._removeFromWorkList() self.participant.activity.workItemFinished(self, remove, self.history, self.object_)
def __repr__(self): return _('process-finished-notation', u"$NAME workflow process ($ID) finished. $DESC", mapping={ 'NAME': self.name, 'ID': self.pid, 'DESC': self.description })
class ProcessStartedColumn(column.Column): implements(ISortingColumn) header = _('processstarted-column-header', u"Process Started") weight = 90 def renderCell(self, item): return getattr(item, 'starttime', _(u"Unknown"))
def __repr__(self): return _('process-started-notation', u"$ID workflow process started by $CONTRIB.", mapping={ 'NAME': self.name, 'ID': self.pid, 'DESC': self.description, 'CONTRIB': userName(self.contributor, self), })
class FixateEditorialReview(form.Form): """ Form for the the work item.""" implements(interfaces.IWorkItemForm) fields = field.Fields(answer) label = _('fixateeditorialreview-label', u"Editorial Review of Fixation Request") info = _('fixateeditorialreview-info', u"Please decide to fixate/unfixate the database item.") ignoreContext = True ignoreReadonly = True def _handle(self, fixate): data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return history = self.context.history principal = getattr(self.request, 'principal', None) history.append( UserNotation(getattr(principal, 'id', u"Unkown"), data['workflow-message'])) #get next URL before removing work item url = self.nextURL() self.context.finish(fixate, data['workflow-message']) self.request.response.redirect(url) @button.buttonAndHandler(_(u"Fixate"), name="fixate") def handleFixate(self, action): self._handle('fixate') @button.buttonAndHandler(_(u"Unfixate"), name="unfixate") def handleUnfixate(self, action): self._handle('unfixate') @button.buttonAndHandler(_(u"Reject"), name="reject") def handleReject(self, action): self._handle('reject') @button.buttonAndHandler(_(u"Postpone"), name="postpone") def handlePostpone(self, action): self._handle('postpone') @button.buttonAndHandler(_(u"Cancel"), name="cancel") def handleCancel(self, action): self.request.response.redirect(self.nextURL()) def nextURL(self): return absoluteURL(self.context.__parent__, self.request) def contributor(self): return common.getPrincipalTitle(self.context.contributor) def message(self): return escape(self.context.message).replace('\n', '<br />')
def finish(self, fixate, message): self.schema['fixate'].validate(fixate) if fixate == 'postpone': message = self.message if fixate == 'fixate': if interfaces.IFixed.providedBy(self.object_): raise ProcessError( _('fixate-ifixed-already-provided', u"Database item is already fixed.")) directlyProvides(self.object_, interfaces.IFixed) if fixate == 'unfixate': if not interfaces.IFixed.providedBy(self.object_): raise ProcessError( _('unfix-failed-not-fixed', u"Database item is not fixated. Failed to unfix it.")) noLongerProvides(self.object_, interfaces.IFixed) self._removeFromWorkList() self.participant.activity.workItemFinished(self, fixate, message, self.history, self.object_)
def start(self, contributor, starttime, message, history, object_): self.contributor = contributor self.starttime = starttime self.message = message self.history = history self.object_ = object_ if not interfaces.IRemovable.providedBy(object_): raise ProcessError( _( 'fixate-iremovable-not-provided', u"Database item can't be fixated. (IRemovable not provided.)" )) self._appendToWorkList()
class ProcessColumn(column.Column): """ Tries to lookup a view called 'processName' for the item.""" implements(ISortingColumn) header = _('process-column-header', u"Process") weight = 100 def renderCell(self, item): view = zope.component.queryMultiAdapter((item, self.request), name='processName') if view: return view() else: return interfaces.IWorkflowInfo(item).process_name
class ContributorColumn(column.Column): implements(ISortingColumn) header = _('contributor-column-header', u"Started By") weight = 105 def renderCell(self, item): contributor = getattr(item, 'contributor', u'Unkown') pau = zope.component.queryUtility(IAuthentication, context=self.context) try: contributor = pau.getPrincipal(contributor).title except Exception: pass return contributor
class WorkItemColumn(column.Column): implements(ISortingColumn) header = _('workitem-column-header', u"Work Item") weight = 110 def renderCell(self, item): # makes sense to use label view because we need it in other # contexts view = zope.component.getMultiAdapter((item, self.request), name='label') rc = view() try: rc = translate(rc, context=self.request) except Exception: pass return rc
def renderCell(self, item): # 1.1: try to get view named objectLabel for work item label = zope.component.queryMultiAdapter((item, self.request), name='objectLabel') if not label: # 1.2: try to get object from object_ attribute and lookup # label view obj = getattr(item, 'object_', None) if obj is None: # 1.3: return default label return _(u"Unkown") label = zope.component.getMultiAdapter((obj, self.request), name='label') # 2: translate label and return try: return translate(label(), context=self.request) except Exception: return label()
class LastActivityByColumn(column.Column): """ The dc creator of a work item is the one who performed the last activity in the workflow.""" zope.interface.implements(ISortingColumn) header = _('last-activity-by-column-header', u"Last Activity By") weight = 210 def renderCell(self, item): creator = u"Unkown" dc = IZopeDublinCore(item, None) if dc is None: return creator pau = zope.component.queryUtility(IAuthentication, context=self.context) if pau is not None: try: creator = pau.getPrincipal(dc.creators[0]).title except Exception: pass return creator
def __call__(self): return _(u"Workflow")
from zope.proxy import removeAllProxies from zope.publisher.browser import BrowserView from z3c.ptcompat import ViewPageTemplateFile from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile as ViewletPageTemplateFile from zope.viewlet.viewlet import ViewletBase from cgi import escape from quotationtool.skin.interfaces import ITabbedContentLayout from quotationtool.workflow import interfaces from quotationtool.workflow.interfaces import _ from quotationtool.workflow.history import UserNotation from quotationtool.workflow.browser import common message = zope.schema.Text( title=_('fixate-message-title', u"Message"), description=_( 'fixate-message-desc', u"Please enter the message you want to send to the editorial staff."), required=True, ) message.__name__ = 'workflow-message' answer = zope.schema.Text( title=_('fixate-comment-title', u"Comment"), description=_( 'fixate-comment-desc', u"Please give a (short) comment about the request, especially if you reject it." ), required=False, )
def process_name(self): return getattr(self.process_definition, '__name__', _(u"Unkown"))
def renderCell(self, item): return getattr(item, 'starttime', _(u"Unknown"))
from zope.proxy import removeAllProxies from zope.publisher.browser import BrowserView from z3c.ptcompat import ViewPageTemplateFile from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile as ViewletPageTemplateFile from zope.viewlet.viewlet import ViewletBase from cgi import escape from quotationtool.skin.interfaces import ITabbedContentLayout from quotationtool.workflow import interfaces from quotationtool.workflow.interfaces import _ from quotationtool.workflow.history import UserNotation from quotationtool.workflow.browser import common message = zope.schema.Text( title=_('message-message-title', u"Message"), description=_( 'message-message-desc', u"Please enter the message you want to send to the editorial staff."), required=True, ) message.__name__ = 'workflow-message' answer = zope.schema.Text( title=_('message-answer-title', u"Answer"), description=_('message-answer-desc', u"Please give a (short) answer to the message."), required=True, ) answer.__name__ = 'workflow-message'
from zope.proxy import removeAllProxies from zope.publisher.browser import BrowserView from z3c.ptcompat import ViewPageTemplateFile from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile as ViewletPageTemplateFile from zope.viewlet.viewlet import ViewletBase from cgi import escape from quotationtool.skin.interfaces import ITabbedContentLayout from quotationtool.workflow import interfaces from quotationtool.workflow.interfaces import _ from quotationtool.workflow.history import UserNotation from quotationtool.workflow.browser import common comment = zope.schema.Text( title=_('remove-comment-title', u"Message"), description=_( 'remove-comment-desc', u"Why you want the item to be deleted? Please provide a short message to the editorial staff." ), required=True, ) comment.__name__ = 'workflow-message' review_comment = zope.schema.Text( title=_('removereview-comment-title', u"Comment"), description=_( 'removereview-comment-desc', u"Please give a short comment on your decision, especially if you reject the remove request." ), required=False,
def __call__(self): return _('workflow-process-error-label', u"Error in Workflow Process")
def __call__(self): return getattr(IZopeDublinCore(self.context, None), 'title', _(u"Work list"))