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:
		
							parent
							
								
									88dea1544d
								
							
						
					
					
						commit
						3cc50cccff
					
				
					 3 changed files with 91 additions and 20 deletions
				
			
		| 
						 | 
				
			
			@ -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
 | 
			
		||||
--------------
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue