def __init__(self, context): request = check_request() terms = [] versions = IWorkflowVersions(context.__parent__, None) if versions is not None: # check for first version first_version_label = request.localizer.translate( VERSION_DISPLAY[DISPLAY_FIRST_VERSION]) try: first_version = versions.get_version(1) # pylint: disable=assignment-from-no-return except VersionError: pass else: info = IWorkflowPublicationInfo(first_version, None) if info is not None and info.publication_effective_date: first_version_label = '{1} (= {0})'.format( first_version_label.lower(), format_date(info.publication_effective_date, format_string=SH_DATE_FORMAT)) terms.append( SimpleTerm(DISPLAY_FIRST_VERSION, title=first_version_label)) # check for current version current_version_label = request.localizer.translate( VERSION_DISPLAY[DISPLAY_CURRENT_VERSION]) info = IWorkflowPublicationInfo(context, None) if info is not None and info.publication_effective_date: current_version_label = '{1} (= {0})'.format( current_version_label.lower(), format_date(info.publication_effective_date, format_string=SH_DATE_FORMAT)) terms.append( SimpleTerm(DISPLAY_CURRENT_VERSION, title=current_version_label)) super().__init__(terms)
def delete_action(wf, context): # pylint: disable=invalid-name,unused-argument """Delete draft version, and parent if single version""" versions = IWorkflowVersions(context) versions.remove_version(IWorkflowState(context).version_id) if not versions.get_last_versions(): document = get_parent(versions, IDocument) folder = get_parent(document, IDocumentFolder) del folder[document.__name__]
def get_file_versions(request, oid, fields=None): """Get all document versions properties""" document = get_document(request, oid) versions = IWorkflowVersions(document) result = [] for version in versions.get_versions(sort=True): result.append(version.to_json(fields)) return result
def get_last_version(content): """Helper function used to get last content version""" versions = IWorkflowVersions(content, None) if versions is None: return None result = versions.get_last_versions() if result: return result[0] return None
def _create_document(registry, folder): """Create new document and version""" document = Document() registry.notify(ObjectCreatedEvent(document)) locate(document, folder) version = DocumentVersion() registry.notify(ObjectCreatedEvent(version)) # add version to document versions = IWorkflowVersions(document) versions.add_version(version, None) IWorkflowInfo(version).fire_transition('init') return document, version
def visible_publication_date(self): """Visible publication date getter""" displayed_date = self.displayed_publication_date if displayed_date == DISPLAY_FIRST_VERSION: state = IWorkflowState(self.__parent__, None) if (state is not None) and (state.version_id > 1): versions = IWorkflowVersions(self.__parent__, None) if versions is not None: version = versions.get_version(1) # pylint: disable=assignment-from-no-return return IWorkflowPublicationInfo( version).publication_effective_date return self.publication_effective_date
def fire_transition_for_versions(self, state, transition_id, comment=None, principal=None, request=None): # pylint: disable=too-many-arguments """Fire transition for all versions in given state""" versions = IWorkflowVersions(self.parent) for version in versions.get_versions(state): IWorkflowInfo(version).fire_transition(transition_id, comment, principal=principal, request=request)
def get_document(oid, version=None, status=None): """Get existing document from it's OID""" if not oid: return None catalog = get_utility(ICatalog) params = Eq(catalog['zfile_oid'], oid) # check for version or state index = None if version: # check for version number or status try: index = int(version) # version number status = None except ValueError: # status string index = None status = version if index: params = and_(params, Eq(catalog['workflow_version'], index)) elif status: params = and_(params, Eq(catalog['workflow_state'], status)) for result in ResultSet( CatalogQuery(catalog).query(params, sort_index='workflow_version', reverse=True)): if version or status: return result return IWorkflowVersions(result).get_last_versions()[0] return None
def fire_transition(self, transition_id, comment=None, side_effect=None, check_security=True, principal=None, request=None): # pylint: disable=too-many-arguments """Fire transition with given ID""" versions = IWorkflowVersions(self.parent) state = IWorkflowState(self.context) if request is None: request = check_request() # this raises InvalidTransitionError if id is invalid for current state transition = self.wf.get_transition(state.state, transition_id) # check whether we may execute this workflow transition if check_security and transition.permission: if not request.has_permission(transition.permission, context=self.context): raise HTTPUnauthorized() # now make sure transition can still work in this context if not transition.condition(self, self.context): raise ConditionFailedError() # perform action, return any result as new version if principal is None: principal = request.principal result = transition.action(self, self.context) if result is not None: # stamp it with version versions.add_version(result, transition.destination, principal) # execute any side effect: if side_effect is not None: side_effect(result) event = WorkflowVersionTransitionEvent(result, self.wf, principal, self.context, transition.source, transition.destination, transition, comment) else: versions.set_state(state.version_id, transition.destination, principal) # execute any side effect if side_effect is not None: side_effect(self.context) event = WorkflowTransitionEvent(self.context, self.wf, principal, transition.source, transition.destination, transition, comment) # change state of context or new object registry = request.registry registry.notify(event) # send modified event for original or new object if result is None: registry.notify(ObjectModifiedEvent(self.context)) else: registry.notify(ObjectModifiedEvent(result)) return result
def _get_viewlets(self): translate = self.request.localizer.translate for version in IWorkflowVersions( self.context).get_last_versions(count=0): state = IWorkflowState(version) item = MenuItem(version, self.request, self.view, self) item.label = translate(_("Version {id} - {state}")).format( id=state.version_id, state=translate(self.workflow.get_state_label(state.state))) item.icon_class = 'fas fa-arrow-right' if version is self.context: item.css_class = 'bg-primary text-white' item.href = absolute_url(version, self.request, 'admin#{}'.format(self.request.view_name)) yield 'version_{}'.format(state.version_id), item
def is_published(self, check_parent=True): """Check if content is published""" # check is parent is also published... if check_parent: parent = get_parent(self.__parent__, IWorkflowPublicationSupport, allow_context=False) if (parent is not None ) and not IWorkflowPublicationInfo(parent).is_published(): return False # associated workflow? workflow = IWorkflow(self.__parent__, None) if (workflow is not None) and not workflow.visible_states: return False # check content versions versions = IWorkflowVersions(self.__parent__, None) if (versions is not None) and not versions.get_versions( workflow.visible_states): return False now = tztime(datetime.utcnow()) return (self.publication_effective_date is not None) and \ (self.publication_effective_date <= now) and \ ((self.publication_expiration_date is None) or (self.publication_expiration_date >= now))
def publish_action(wf, context): # pylint: disable=invalid-name,unused-argument """Publish version""" request = check_request() translate = request.localizer.translate publication_info = IWorkflowPublicationInfo(context) publication_info.publication_date = datetime.utcnow() publication_info.publisher = request.principal.id version_id = IWorkflowState(context).version_id for version in IWorkflowVersions(context).get_versions( (PUBLISHED_STATE, )): if version is not context: IWorkflowInfo(version).fire_transition_toward( ARCHIVED_STATE, comment=translate( _("Published version {0}")).format(version_id))
def update(self): self.versions = IWorkflowVersions(self.context) super().update()
def has_version(self, state): """Test for existing versions in given state""" wf_versions = IWorkflowVersions(self.parent) return wf_versions.has_version(state)
def can_create_new_version(wf, context): # pylint: disable=invalid-name,unused-argument """Check if we can create a new version""" # can't create new version when previous draft already exists versions = IWorkflowVersions(context) return not versions.has_version(DRAFT_STATE)
def sublocations(self): """Versions sub-locations getter""" return IWorkflowVersions(self.context).values()
def traverse(self, name, furtherpath=None): # pylint: disable=unused-argument """Versions traverser""" versions = IWorkflowVersions(self.context) if name: return versions[name] return versions
def workflow_version_versions_factory(context): """Workflow versions factory for version""" parent = get_parent(context, IWorkflowManagedContent) if parent is not None: return IWorkflowVersions(parent) return None