# $Id: History.py,v 1.3 2006/11/29 12:54:00 dieter Exp $ '''Support for access to the history of objects.''' from OFS.History import historicalRevision from Acquisition import aq_base from DateTime import DateTime from struct import unpack # code extracted from "OFS/History.py" def getHistory(obj,firstIndex=0,lastIndex=20): '''return the history records for *obj* between *firstIndex* and *lastIndex*.''' try: parent= obj.aq_inner.aq_parent except AttributeError: parent= None r= obj._p_jar.db().history(obj._p_oid,None,lastIndex) r= r[firstIndex:] for d in r: d['time']= DateTime(d['time']) d['key']= '.'.join(map(str, unpack(">HHHH", d['tid']))) h_obj= historicalRevision(obj, d['tid']) if parent is not None and hasattr(h_obj,'__of__'): h_obj= h_obj.__of__(parent) d['obj']= h_obj return r def getObjectAt(obj,time): '''return the object *obj* as it has been at *time*.''' first= 0; last= 10; tc= obj.bobobase_modification_time() if time >= tc: return obj while 1: ts= getHistory(obj,first,last) if not ts: return None for t in getHistory(obj,first,last): if t['time'] <= time: return t['obj'] first= last; last*= 2 def makeCurrent(target,version): '''make *version* current for *target*.''' # code extracted from "OFS.History.Historical.manage_historyCopy" # check, both *target* and *version* refer to the same object if target._p_oid != version._p_oid: raise ValueError, 'target and version refer to different objects' state= version.__getstate__() # Scrub the object before restoring the old state base = aq_base(target) base._p_changed=0 base._p_deactivate() base.__setstate__(state) base._p_changed=1 def getWorkflowHistoryAt(obj,time): '''auxiliary to obtain workflow history at *time* as a standard dict.''' wfh= getObjectAt(obj.workflow_history,time) if wfh is None: return {} d= {} for k,v in wfh.items(): d[k]= v return d