コード例 #1
0
ファイル: audit.py プロジェクト: BenoitTalbot/bungeni-portal
def getAuditableParent(obj):
    parent = obj.__parent__
    while parent:
        if  IAuditable.providedBy(parent):
            return parent
        else:
            parent = getattr(parent, "__parent__", None)
コード例 #2
0
 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()
コード例 #3
0
def getAuditableParent(obj):
    parent = obj.__parent__
    while parent:
        if IAuditable.providedBy(parent):
            return parent
        else:
            parent = getattr(parent, "__parent__", None)
コード例 #4
0
ファイル: workflow.py プロジェクト: mohalfaki/bungeni-portal
    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()
コード例 #5
0
def _get_auditable_ancestor(obj):
    parent = obj.__parent__
    while parent:
        if  IAuditable.providedBy(parent):
            return parent
        else:
            parent = getattr(parent, "__parent__", None)
コード例 #6
0
 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)
コード例 #7
0
ファイル: workflow.py プロジェクト: mohalfaki/bungeni-portal
 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)
コード例 #8
0
ファイル: serialize.py プロジェクト: mohalfaki/bungeni-portal
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()    
コード例 #9
0
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
コード例 #10
0
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
コード例 #11
0
 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()
コード例 #12
0
ファイル: workflow.py プロジェクト: mohalfaki/bungeni-portal
 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()
コード例 #13
0
ファイル: workflow.py プロジェクト: mohalfaki/bungeni-portal
    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)
コード例 #14
0
 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)
コード例 #15
0
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()
コード例 #16
0
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()