Exemplo n.º 1
0
    def get_history_diffs(self, obj, history_id1, history_id2=None, after_earlier_event=True):
        """ Given a content object and the _ids of one or two history records, return a dictionary 
        of the schema values that changed between history_id1 and history_id2.
        If history_id2 is None, use the current/latest version of the content object.
        Note that if two history ids are specified, 1 need not be chronologically before 2.
        Note also that in general the schema values considered are those just after each
        history event occurred.  The parameter after_earlier_event can be set to False if instead you
        want to consider the values just before the earlier of the two history events.
        (This is particularly handy when the same history ID is passed for both history_id1 and history_id2;
        in such a case, you would get the changes made for that single edit event.)

        The keys are schema names.  The values are dictionaries with the keys: "before" and "after".
        If the values are strings, there's also a key "diff" which contains an html fragment
        highlighting the diffs with <ins> and <del> tags.

#        Further, if at least one of the strings appears to contain html, there's also a key "htmldiff"
#        which contains another html fragment highlighting the diffs with <ins> and <del> tags, only this 
#        time a special differ was used that ignores html markup.
#
#        Practically speaking, if there's an "htmldiff" key in the result, it means that the before
#        and after values contain HTML; the "htmldiff" shows differences in the rendered html,
#        while "diff" shows differences in the source html.
        """
        if (history_id1 == history_id2) and after_earlier_event: return {}  # Nothing could have changed in this case.
        after = before = None
        history_ids = [history_id1]
        if history_id2:
            history_ids.append(history_id2)
        else:
            after = obj.get_schema_values()
        patches = []
        for history in self.get_history_for_id(obj._id)['items']:
            if history['_id'] in history_ids:
                if after:
                    if after_earlier_event:
                        before = diffutil.patch_dictionary_multi(after, patches)
                        return diff_dictionaries(before, after)
                else:
                    after = diffutil.patch_dictionary_multi(obj.get_schema_values(), patches)
                    patches = []

            if history['action'] in ('edit', 'revert'):
                patch = history['changes']
                if patch: patches.append(patch)

            if history['_id'] in history_ids:
                if after and not after_earlier_event:
                    before = diffutil.patch_dictionary_multi(after, patches)
                    return diff_dictionaries(before, after)

        raise ValueError("Didn't find specified history record.")
Exemplo n.º 2
0
 def apply_history(self, obj, history_id):
     """ Given a content object and the _id of a history record, apply
     changes from the edit history such that the object has the schema
     values it had just after the specified history event.
     Note that this method modifies the content object in place.
     """
     patches = []
     for history in self.get_history_for_id(obj._id)['items']:
         if history['_id'] == history_id:
             data = diffutil.patch_dictionary_multi(obj.get_schema_values(), patches)
             obj.update(**data)
             return
         if history['action'] not in ('edit', 'revert'): continue
         patch = history['changes']
         if patch: patches.append(patch)
     raise ValueError("Didn't find specified history record.")