Back to index

moin  1.9.0~rc2
PageHits.py
Go to the documentation of this file.
00001 # -*- coding: iso-8859-1 -*-
00002 """
00003     MoinMoin - per page hit statistics
00004 
00005     @copyright: 2004-2005 MoinMoin:ThomasWaldmann
00006     @license: GNU GPL, see COPYING for details
00007 
00008 """
00009 
00010 from MoinMoin import caching, logfile
00011 from MoinMoin.Page import Page
00012 from MoinMoin.logfile import eventlog
00013 
00014 
00015 class PageHits:
00016 
00017     def __init__(self, macro):
00018         self.macro = macro
00019         self.request = macro.request
00020         self.cache = caching.CacheEntry(self.request, 'charts', 'pagehits', scope='wiki', use_pickle=True)
00021 
00022     def execute(self):
00023         """ Execute the macro and return output """
00024         if self.request.isSpiderAgent: # reduce bot cpu usage
00025             return ''
00026         cacheDate, hits = self.cachedHits()
00027         self.addHitsFromLog(hits, cacheDate)
00028         self.filterReadableHits(hits)
00029         hits = [(hits[pagename], pagename) for pagename in hits]
00030         hits.sort()
00031         hits.reverse()
00032         return self.format(hits)
00033 
00034     def cachedHits(self):
00035         """ Return tuple (cache date, cached hits) for all pages """
00036         date, hits = 0, {}
00037         if self.cache.exists():
00038             try:
00039                 date, hits = self.cache.content()
00040             except caching.CacheError:
00041                 self.cache.remove()
00042         return date, hits
00043 
00044     def addHitsFromLog(self, hits, cacheDate):
00045         """ Parse the log, add hits after cacheDate and update the cache """
00046         event_log = eventlog.EventLog(self.request)
00047         event_log.set_filter(['VIEWPAGE'])
00048 
00049         changed = False
00050         # don't use event_log.date()
00051         latest = None
00052         for event in event_log.reverse():
00053             if latest is None:
00054                 latest = event[0]
00055             if event[0] <= cacheDate:
00056                 break
00057             page = event[2].get('pagename', None)
00058             if page:
00059                 hits[page] = hits.get(page, 0) + 1
00060                 changed = True
00061 
00062         if changed:
00063             self.updateCache(latest, hits)
00064 
00065     def updateCache(self, date, hits):
00066         try:
00067             self.cache.update((date, hits))
00068         except caching.CacheError:
00069             pass
00070 
00071     def filterReadableHits(self, hits):
00072         """ Filter out hits the user many not see """
00073         userMayRead = self.request.user.may.read
00074         for pagename in hits.keys(): # we need .keys() because we modify the dict
00075             page = Page(self.request, pagename)
00076             if page.exists() and userMayRead(pagename):
00077                 continue
00078             del hits[pagename]
00079 
00080     def format(self, hits):
00081         """ Return formated output """
00082         result = []
00083         formatter = self.macro.formatter
00084         result.append(formatter.number_list(1))
00085         for hit, pagename in hits:
00086             result.extend([
00087                 formatter.listitem(1),
00088                 formatter.code(1),
00089                 ("%6d" % hit).replace(" ", "&nbsp;"), " ",
00090                 formatter.code(0),
00091                 formatter.pagelink(1, pagename, generated=1),
00092                 formatter.text(pagename),
00093                 formatter.pagelink(0, pagename),
00094                 formatter.listitem(0),
00095             ])
00096         result.append(formatter.number_list(0))
00097         return ''.join(result)
00098 
00099 
00100 def macro_PageHits(macro):
00101     return PageHits(macro).execute()
00102