tracking stats: period details

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@3123 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2009-01-07 09:28:13 +00:00
parent 88dea1544d
commit 3cc50cccff
3 changed files with 91 additions and 20 deletions

View file

@ -151,6 +151,16 @@ Overview (cumulative) statistics
>>> result['data']
[{'access': 2, 'new': 0, 'changed': 1, 'period': '...', 'count': 3}]
Changes for a certain period (month)
------------------------------------
>>> input = dict(period='2009-01', select='access')
>>> view = TrackingStats(statQuery, TestRequest(form=input))
>>> result = view.getData()
>>> result['data']
[...]
Recent changes
--------------

View file

@ -21,12 +21,18 @@
<tr tal:repeat="row info/data"
tal:attributes="class python: repeat['row'].odd() and 'even' or 'odd'">
<td tal:content="row/period"></td>
<td class="number"
tal:content="row/access"></td>
<td class="number"
tal:content="row/changed"></td>
<td class="number"
tal:content="row/new"></td>
<td class="number">
<a tal:omit-tag="python: row['access'] == 0"
tal:attributes="href string:?period=${row/period}&select=access"
tal:content="row/access" /></td>
<td class="number">
<a tal:omit-tag="python: row['changed'] == 0"
tal:attributes="href string:?period=${row/period}&select=changes"
tal:content="row/changed" /></td>
<td class="number">
<a tal:omit-tag="python: row['new'] == 0"
tal:attributes="href string:?period=${row/period}&select=new"
tal:content="row/new" /></td>
<td class="number"
tal:content="row/count"></td>
</tr>
@ -34,7 +40,22 @@
</metal:overview>
<metal:recent define-macro="period">
<h2 i18n:translate="">
Period <span i18n:name="period" tal:content="request/period" />,
<span i18n:name="select" tal:content="request/select" /></h2>
<p><a tal:attributes="href python: request.URL[-1]">
Back to overview</a></p>
<metal:listing use-macro="item/macros/listing" />
</metal:recent>
<metal:recent define-macro="recent_changes">
<metal:listing use-macro="item/macros/listing" />
</metal:recent>
<metal:recent define-macro="listing">
<table class="listing">
<tr>
<th i18n:translate="">Title</th>
@ -43,7 +64,8 @@
tal:condition="view/useVersioning">V</th>
<th i18n:translate="">User</th>
<th i18n:translate="">Date/Time</th>
<th i18n:translate="">New</th>
<th i18n:translate=""
tal:condition="info/showNewColumn">New</th>
</tr>
<tr tal:repeat="row info/data"
tal:attributes="class python: repeat['row'].odd() and 'even' or 'odd'">
@ -68,6 +90,7 @@
tal:content="row/user/title" /></td>
<td tal:content="row/timeStamp"></td>
<td class="center"
tal:condition="info/showNewColumn"
tal:content="row/markNew"></td>
</tal:row>
</tr>

View file

@ -23,6 +23,7 @@ $Id$
"""
from datetime import date, datetime
import time
from zope import component
from zope.app.pagetemplate import ViewPageTemplateFile
from zope.app.security.interfaces import IAuthentication, PrincipalLookupError
@ -65,13 +66,21 @@ class TrackingStats(BaseView):
def typeNames(self):
return self.options('types') or ['resource:*']
@Lazy
def accessContainer(self):
return self.loopsRoot.getRecordManager()['access']
@Lazy
def changesContainer(self):
return self.loopsRoot.getRecordManager()['changes']
@Lazy
def accessRecords(self):
return self.filter(reversed(self.loopsRoot.getRecordManager()['access'].values()))
return self.filter(reversed(self.accessContainer.values()))
@Lazy
def changeRecords(self):
return self.filter(reversed(self.loopsRoot.getRecordManager()['changes'].values()))
return self.filter(reversed(self.changesContainer.values()))
def filter(self, tracks):
for tr in tracks:
@ -109,17 +118,19 @@ class TrackingStats(BaseView):
form = self.request.form
period = form.get('period')
uid = form.get('id')
if period is not None:
result = self.getPeriodDetails(period)
macroName = 'period'
elif uid is not None:
result = self.getObjectDetails(uid)
select = form.get('select') or 'changes'
if uid is not None:
result = self.getObjectDetails(uid, period, select)
macroName = 'object'
elif period is not None:
result = self.getPeriodDetails(period, select)
macroName = 'period'
else:
result = self.getOverview()
macroName = 'overview'
macro = self.macros[macroName]
return dict(data=result, macro=macro)
return dict(data=result, macro=macro,
showNewColumn=(select in ('changes', 'new')))
def getOverview(self):
""" Period-based (monthly) listing of the numbers of object accesses, new,
@ -148,12 +159,30 @@ class TrackingStats(BaseView):
num = num - data['new']
return result
def getPeriodDetails(period):
def getPeriodDetails(self, period, select='changes'):
""" Listing of accessed, new, changed, [deleted] objects during
the period given.
"""
parts = [int(x) for x in period.split('-')]
parts.append(1)
start = date(*parts)
if parts[1] == 12:
end = date(parts[0] + 1, 1, 1)
else:
end = date(parts[0], parts[1] + 1, 1)
start = int(time.mktime(start.timetuple()))
end = int(time.mktime(end.timetuple()))
if select in ('changes', 'new'):
data = reversed(list(self.filter(
self.changesContainer.query(timeFromTo=(start, end)))))
if select == 'new':
data = [tr for tr in data if tr.data['action'] == 'add']
if select == 'access':
data = reversed(list(self.filter(
self.accessContainer.query(timeFromTo=(start, end)))))
return [TrackDetails(self, tr) for tr in data]
def getObjectDetails(uid, period=None):
def getObjectDetails(self, uid, period=None, select='changes'):
""" Listing of (last n?) accesses and changes of the object specified by
the uid given, optionally limited to the period (month) given.
"""
@ -185,7 +214,8 @@ class RecentChanges(TrackingStats):
result.append(track)
continue
return dict(data=[TrackDetails(self, tr) for tr in result],
macro=self.macros['recent_changes'])
macro=self.macros['recent_changes'],
showNewColumn=True)
class TrackDetails(BaseView):
@ -207,6 +237,14 @@ class TrackDetails(BaseView):
self.view.lastMonth = self.month
return result
@Lazy
def day(self):
value = self.formatTimeStamp(self.track.timeStamp, 'date')
if value == self.view.lastDay:
return u''
self.view.lastDay = value
return value
@Lazy
def authentication(self):
return component.getUtility(IAuthentication)
@ -258,11 +296,11 @@ class TrackDetails(BaseView):
#return format.formatDate(value, 'dateTime', self.timeStampFormat,
# self.view.languageInfo.language)
def formatTimeStamp(self, ts):
def formatTimeStamp(self, ts, f='dateTime'):
if not ts:
return u''
value = datetime.fromtimestamp(ts)
return format.formatDate(value, 'dateTime', self.timeStampFormat,
return format.formatDate(value, f, self.timeStampFormat,
self.view.languageInfo.language)
def __repr__(self):