From b2f2c5c64c088e99d5d62d778142ba48986c8530 Mon Sep 17 00:00:00 2001 From: helmutm Date: Mon, 27 Nov 2006 12:49:24 +0000 Subject: [PATCH] bug fixes and extensions for cybertools.tracking git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1525 fd906abe-77d9-0310-91a1-e0d9ade77398 --- tracking/README.txt | 21 +++++++++++++++++++++ tracking/btree.py | 24 +++++++++++++++++++----- tracking/interfaces.py | 6 ++++++ 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/tracking/README.txt b/tracking/README.txt index 893980d..10147bb 100644 --- a/tracking/README.txt +++ b/tracking/README.txt @@ -38,6 +38,27 @@ What happens if we store more than on record for one set of keys? >>> [t.data for t in t2] [{'somekey': 'somevalue'}, {'somekey': 'newvalue'}] +It is also possible to retrieve the last entry for a set of keys directliy: + + >>> tracks.getLastUserTrack('a001', 0, 'u1') + + +Instead of creating a new track object for each call one can also replace +an existing one (if present). The replace entry is always the last one +for a given set of keys: + + >>> tracks.saveUserTrack('a001', 0, 'u1', {'somekey': 'newvalue2'}, replace=True) + '0000003' + >>> t3 = tracks.getUserTracks('a001', 0, 'u1') + >>> [t.data for t in t3] + [{'somekey': 'somevalue'}, {'somekey': 'newvalue2'}] + + >>> tracks.saveUserTrack('a001', 0, 'u2', {'somekey': 'user2'}, replace=True) + '0000004' + >>> t4 = tracks.getUserTracks('a001', 0, 'u2') + >>> [t.data for t in t4] + [{'somekey': 'user2'}] + The tracks of a tracking store may be reindexed: >>> tracks.reindexTracks() diff --git a/tracking/btree.py b/tracking/btree.py index 9b6ebd2..ffea4c4 100644 --- a/tracking/btree.py +++ b/tracking/btree.py @@ -63,12 +63,20 @@ class TrackingStorage(BTreeContainer): if taskId in self.currentRuns: del self.currentRuns[taskId] - def saveUserTrack(self, taskId, runId, userName, data): + def saveUserTrack(self, taskId, runId, userName, data, replace=False): if not runId: runId = self.currentRuns.get(taskId) or self.startRun(taskId) - self.trackNum += 1 - trackNum = self.trackNum - trackId = self.idFromNum(trackNum) + trackNum = 0 + if replace: + track = self.getLastUserTrack(taskId, runId, userName) + if track: + trackId = str(track.__name__) + trackNum = int(trackId) + del self[trackId] + if not trackNum: + self.trackNum += 1 + trackNum = self.trackNum + trackId = self.idFromNum(trackNum) timeStamp = int(time.time()) track = Track(taskId, runId, userName, timeStamp, data) self[trackId] = track @@ -95,6 +103,12 @@ class TrackingStorage(BTreeContainer): runId = self.currentRuns.get(taskId) return self.query(taskId=taskId, runId=runId, userName=userName) + def getLastUserTrack(self, taskId, runId, userName): + tracks = self.getUserTracks(taskId, runId, userName) + if tracks: + return sorted(tracks, key=lambda x: x.timeStamp)[-1] + else: return None + def query(self, **kw): result = None for idx in kw: @@ -110,7 +124,7 @@ class TrackingStorage(BTreeContainer): return result and [self[self.idFromNum(r)] for r in result] or set() def intersect(self, r1, r2): - return r1 and intersection(r1, r2) or r2 + return r1 is None and r2 or intersection(r1, r2) def getUserNames(self, taskId): return sorted(self.taskUsers.get(taskId, [])) diff --git a/tracking/interfaces.py b/tracking/interfaces.py index 26548cb..0ca4c99 100644 --- a/tracking/interfaces.py +++ b/tracking/interfaces.py @@ -63,6 +63,12 @@ class ITrackingStorage(Interface): task id given. If a 0 run id is given use the current one. """ + def getLastUserTrack(taskId, runId, userName): + """ Return the last user track (that with the highest timestamp value) + corresponding to the user name and task id given. + If a 0 run id is given use the current one. + """ + def getUserNames(taskId): """ Return all user names (user ids) that have tracks for the task given.