def getAuditableParent(obj): parent = obj.__parent__ while parent: if IAuditable.providedBy(parent): return parent else: parent = getattr(parent, "__parent__", None)
def update(self, transition_id=None): if IWorkspaceContainer.providedBy(self.context.__parent__): self._old_url = WorkspaceAbsoluteURLView( self.context, self.request)() workflow = interfaces.IWorkflow(self.context) if transition_id: transition = workflow.get_transition(transition_id) title = translate(_(transition.title), context=self.request) self.status = translate( _(u"Confirmation required for workflow transition: '${title}'", mapping={"title": title} ), context=self.request) self.setupActions(transition_id) if (IBungeniParliamentaryContent.providedBy(self.context) and get_mask(self.context) == "manual" and not self.context.registry_number ): self.form_fields = self.form_fields.omit("note", "date_active") else: self.form_fields = self.form_fields.omit("registry_number") if not self.actions: self.form_fields = self.form_fields.omit("note", "date_active") elif not IAuditable.providedBy(self.context): self.form_fields = self.form_fields.omit("note", "date_active") # !+SUPERFLUOUS_ObejctModifiedEvent(mr, nov-2011) the following update() # is causing a ModifiedEvent to be fired, causing a modify change to be # logged (while this workflow change should be just that). super(WorkflowActionViewlet, self).update()
def update(self, transition_id=None): if IWorkspaceContainer.providedBy(self.context.__parent__): self._old_url = WorkspaceAbsoluteURLView(self.context, self.request)() workflow = interfaces.IWorkflow(self.context) if transition_id: transition = workflow.get_transition(transition_id) title = translate(_(transition.title), context=self.request) self.status = translate(_( u"Confirmation required for workflow transition: '${title}'", mapping={"title": title}), context=self.request) self.setupActions(transition_id) if (IBungeniParliamentaryContent.providedBy(self.context) and get_mask(self.context) == "manual" and not self.context.registry_number): self.form_fields = self.form_fields.omit("note", "date_active") else: self.form_fields = self.form_fields.omit("registry_number") if not self.actions: self.form_fields = self.form_fields.omit("note", "date_active") elif not IAuditable.providedBy(self.context): self.form_fields = self.form_fields.omit("note", "date_active") # !+SUPERFLUOUS_ObejctModifiedEvent(mr, nov-2011) the following update() # is causing a ModifiedEvent to be fired, causing a modify change to be # logged (while this workflow change should be just that). super(WorkflowActionViewlet, self).update()
def _get_auditable_ancestor(obj): parent = obj.__parent__ while parent: if IAuditable.providedBy(parent): return parent else: parent = getattr(parent, "__parent__", None)
def update(self, transition_id=None): # set up viewlets; the view is rendered from viewlets for # historic reasons; this may be refactored anytime. if IAuditable.providedBy(self.context): self.history_viewlet = WorkflowHistoryViewlet( self.context, self.request, self, None) self.history_viewlet.update() self.action_viewlet = WorkflowActionViewlet( self.context, self.request, self, None) self.action_viewlet.update(transition_id=transition_id)
def update(self, transition_id=None): # set up viewlets; the view is rendered from viewlets for # historic reasons; this may be refactored anytime. if IAuditable.providedBy(self.context): self.history_viewlet = WorkflowHistoryViewlet( self.context, self.request, self, None) self.history_viewlet.update() self.action_viewlet = WorkflowActionViewlet(self.context, self.request, self, None) self.action_viewlet.update(transition_id=transition_id)
def publish_to_xml(context, type="", include=None): """ Generates XML for object and saves it to the file. If object contains attachments - XML is saved in zip archive with all attached files. """ if include is None: include = [] context = removeSecurityProxy(context) if IVersionable.implementedBy(context.__class__): include.append("versions") if IAuditable.implementedBy(context.__class__): include.append("event") data = obj2dict(context,1,parent=None,include=include, exclude=["file_data", "image", "logo_data","event_item"]) if type=="": type = getattr(context,"type", None) data["permissions"]= [] permissions = get_object_state_rpm(context).permissions for x in permissions: data["permissions"].append({"role":x[2], "permission":x[1], "setting":x[0] and "Allow" or "Deny"}) assert type, "%s has no 'type' field. Use 'type' function parameter." % context.__class__ files = [] path = os.path.join(setupStorageDirectory(), type) if not os.path.exists(path): os.makedirs(path) file_path = os.path.join(path,stringKey(context)) files.append(file_path+".xml") with open(file_path+".xml","w") as file: file.write(serialize(data, name=type)) if IAttachmentable.implementedBy(context.__class__): attached_files = getattr(context, "attached_files", None) if attached_files: for attachment in attached_files: attachment_path = os.path.join(path, attachment.file_name) files.append(attachment_path) with open(os.path.join(path, attachment.file_name), "wb") as file: file.write(attachment.file_data) zip = ZipFile(file_path+".zip", "w") for file in files: zip.write(file, os.path.split(file)[-1]) os.remove(file) zip.close()
def user_is_state_creator(context): """Did the current user create current state - based on workflow log? """ is_state_creator = False if IAuditable.providedBy(context): current_user = model_utils.get_db_user() if current_user: for _object_change in reversed(context.changes): if _object_change.action == "workflow": extras = _object_change.extras if extras and (extras.get("destination") == context.status): if _object_change.user.login == current_user.login: is_state_creator = True break return is_state_creator
def user_is_state_creator(context): """Did the current user create current state - based on workflow log? """ is_state_creator = False if IAuditable.providedBy(context): current_user = model_utils.get_db_user() if current_user: for _object_change in reversed( domain.get_changes(context.changes, "workflow")): extras = _object_change.extras if extras and (extras.get("destination") == context.status): if _object_change.user.login == current_user.login: is_state_creator = True break return is_state_creator
def update(self, transition=None): # !+RENAME(mr, apr-2011) should be transition_id workflow = interfaces.IWorkflow(self.context) if transition is not None: state_transition = workflow.get_transition(transition) state_title = translate(_bc(state_transition.title), context=self.request) self.status = translate(_( u"Confirmation required for workflow transition: '${title}'", mapping={"title": state_title}), context = self.request) self.setupActions(transition) if not self.actions: self.form_fields = self.form_fields.omit("note", "date_active") elif not IAuditable.providedBy(self.context): self.form_fields = self.form_fields.omit("note", "date_active") super(WorkflowActionViewlet, self).update()
def update(self, transition_id=None): workflow = interfaces.IWorkflow(self.context) if transition_id: transition = workflow.get_transition(transition_id) title = translate(_(transition.title), context=self.request) self.status = translate( _(u"Confirmation required for workflow transition: '${title}'", mapping={"title": title} ), context=self.request) self.setupActions(transition_id) if get_mask(self.context) == 'manual' and not self.context.registry_number: self.form_fields = self.form_fields.omit("note", "date_active") else: self.form_fields = self.form_fields.omit("registry_number") if not self.actions: self.form_fields = self.form_fields.omit("note", "date_active") elif not IAuditable.providedBy(self.context): self.form_fields = self.form_fields.omit("note", "date_active") super(WorkflowActionViewlet, self).update()
def get_min_date_active(self): """Determine the min_date_active to validate against. """ def is_workflowed_and_draft(instance): """is item workflowed, and is so is it in a logical draft state? """ if IWorkflowed.providedBy(instance): tagged_key = instance.__class__.__name__.lower() draft_states = get_states(tagged_key, tagged=["draft"]) return instance.status in draft_states return False min_date_active = None if IAuditable.providedBy(self.context): instance = removeSecurityProxy(self.context) # !+PASTDATAENTRY(mr, jun-2011) offers a way to enter past data # for workflowed items via the UI -- note, ideally we should be # able to also control the item's creation active_date. # # If a workflowed item is in draft state, we do NOT take the # date_active of its last change as the min_date_active, but # let that min fallback to parliament's creation date... if not is_workflowed_and_draft(instance): changes = [ change for change in instance.changes if change.action == "workflow" ] if changes: # then use the "date_active" of the most recent entry min_date_active = changes[-1].date_active if not min_date_active: # fallback to current parliament's start_date (cast to a datetime) min_date_active = datetime.datetime.combine( globalsettings.get_current_parliament().start_date, datetime.time()) # As the precision of the UI-submitted datetime is only to the minute, # we adjust min_date_active by a margin of 59 secs earlier to avoid # issues of doing 2 transitions in quick succession (within same minute) # the 2nd of which could be taken to be too old... return min_date_active - datetime.timedelta(seconds=59)
def get_min_date_active(self): """Determine the min_date_active to validate against. """ def is_workflowed_and_draft(instance): """is item workflowed, and if so is it in a logical draft state? """ if interfaces.IWorkflowed.providedBy(instance): wf = interfaces.IWorkflow(instance) return instance.status in wf.get_state_ids(tagged=["draft"], restrict=False) return False min_date_active = None if IAuditable.providedBy(self.context): instance = removeSecurityProxy(self.context) # !+PASTDATAENTRY(mr, jun-2011) offers a way to enter past data # for workflowed items via the UI -- note, ideally we should be # able to also control the item's creation active_date. # # If a workflowed item is in draft state, we do NOT take the # date_active of its last change as the min_date_active, but # let that min fallback to parliament's creation date... if not is_workflowed_and_draft(instance): changes = get_changes(instance, "workflow") if changes: # then use the "date_active" of the most recent entry min_date_active = changes[-1].date_active if not min_date_active: # fallback to current parliament's start_date (cast to a datetime) min_date_active = datetime.datetime.combine( globalsettings.get_current_parliament().start_date, datetime.time()) # As the precision of the UI-submitted datetime is only to the minute, # we adjust min_date_active by a margin of 59 secs earlier to avoid # issues of doing 2 transitions in quick succession (within same minute) # the 2nd of which could be taken to be too old... return min_date_active - datetime.timedelta(seconds=59)
def publish_to_xml(context): """Generates XML for object and saves it to the file. If object contains attachments - XML is saved in zip archive with all attached files. """ include = [] context = removeSecurityProxy(context) if IVersionable.implementedBy(context.__class__): include.append("versions") if IAuditable.implementedBy(context.__class__): include.append("event") data = obj2dict(context, 1, parent=None, include=include, exclude=[ "file_data", "image", "logo_data", "event", "attached_files", "changes" ]) type = IWorkflow(context).name tags = IStateController(context).get_state().tags if tags: data["tags"] = tags permissions = get_object_state_rpm(context).permissions data["permissions"] = get_permissions_dict(permissions) data["changes"] = [] for change in getattr(context, "changes", []): change_dict = obj2dict(change, 0, parent=context) change_permissions = get_head_object_state_rpm(change).permissions change_dict["permissions"] = get_permissions_dict(change_permissions) data["changes"].append(change_dict) # list of files to zip files = [] # setup path to save serialized data path = os.path.join(setupStorageDirectory(), type) if not os.path.exists(path): os.makedirs(path) # xml file path file_path = os.path.join(path, stringKey(context)) has_attachments = False if IAttachmentable.implementedBy(context.__class__): attached_files = getattr(context, "attached_files", None) if attached_files: has_attachments = True # add xml file to list of files to zip files.append("%s.xml" % (file_path)) data["attached_files"] = [] for attachment in attached_files: # serializing attachment attachment_dict = obj2dict( attachment, 1, parent=context, exclude=["file_data", "event", "versions", "changes"]) permissions = get_object_state_rpm(attachment).permissions attachment_dict["permissions"] = \ get_permissions_dict(permissions) # saving attachment to tmp with tmp(delete=False) as f: f.write(attachment.file_data) files.append(f.name) attachment_dict["saved_file"] = \ os.path.split(f.name)[-1] data["attached_files"].append(attachment_dict) # saving xml file with open("%s.xml" % (file_path), "w") as file: file.write(serialize(data, name=type)) # zipping xml and attached files # unzipped files are removed if has_attachments: zip = ZipFile("%s.zip" % (file_path), "w") for f in files: zip.write(f, os.path.split(f)[-1]) os.remove(f) zip.close()
def publish_to_xml(context): """Generates XML for object and saves it to the file. If object contains attachments - XML is saved in zip archive with all attached files. """ include = [] context = removeSecurityProxy(context) if IVersionable.implementedBy(context.__class__): include.append("versions") if IAuditable.implementedBy(context.__class__): include.append("event") data = obj2dict(context, 1, parent=None, include=include, exclude=["file_data", "image", "logo_data", "event", "attached_files","changes"] ) type = IWorkflow(context).name tags = IStateController(context).get_state().tags if tags: data["tags"] = tags permissions = get_object_state_rpm(context).permissions data["permissions"]= get_permissions_dict(permissions) data["changes"] = [] for change in getattr(context, "changes", []): change_dict = obj2dict(change, 0, parent=context) change_permissions = get_head_object_state_rpm(change).permissions change_dict["permissions"] = get_permissions_dict(change_permissions) data["changes"].append(change_dict) # list of files to zip files = [] # setup path to save serialized data path = os.path.join(setupStorageDirectory(), type) if not os.path.exists(path): os.makedirs(path) # xml file path file_path = os.path.join(path, stringKey(context)) has_attachments = False if IAttachmentable.implementedBy(context.__class__): attached_files = getattr(context, "attached_files", None) if attached_files: has_attachments = True # add xml file to list of files to zip files.append("%s.xml" % (file_path)) data["attached_files"] = [] for attachment in attached_files: # serializing attachment attachment_dict = obj2dict(attachment, 1, parent=context, exclude=["file_data", "event", "versions", "changes"]) permissions = get_object_state_rpm(attachment).permissions attachment_dict["permissions"] = \ get_permissions_dict(permissions) # saving attachment to tmp with tmp(delete=False) as f: f.write(attachment.file_data) files.append(f.name) attachment_dict["saved_file"] = \ os.path.split(f.name)[-1] data["attached_files"].append(attachment_dict) # saving xml file with open("%s.xml" % (file_path), "w") as file: file.write(serialize(data, name=type)) # zipping xml and attached files # unzipped files are removed if has_attachments: zip = ZipFile("%s.zip" % (file_path), "w") for f in files: zip.write(f, os.path.split(f)[-1]) os.remove(f) zip.close()