Back to index

moin  1.9.0~rc2
Functions | Variables
MoinMoin.stats.hitcounts Namespace Reference

Functions

def linkto
def get_data
def text
def draw

Variables

int _debug = 0
string DATE_FMT = '%04d-%02d-%02d'

Function Documentation

def MoinMoin.stats.hitcounts.draw (   pagename,
  request 
)

Definition at line 193 of file hitcounts.py.

00193 
00194 def draw(pagename, request):
00195     import shutil, cStringIO
00196     from MoinMoin.stats.chart import Chart, ChartData, Color
00197 
00198     _ = request.getText
00199 
00200     # check params
00201     filterpage = None
00202     if request and request.values and 'page' in request.values:
00203         filterpage = request.values['page']
00204 
00205     days, views, edits = get_data(pagename, request, filterpage)
00206 
00207     import math
00208 
00209     try:
00210         scalefactor = float(max(views))/max(edits)
00211     except (ZeroDivisionError, ValueError):
00212         scalefactor = 1.0
00213     else:
00214         scalefactor = int(10 ** math.floor(math.log10(scalefactor)))
00215 
00216     # scale edits up
00217     edits = [x * scalefactor for x in edits]
00218 
00219     # create image
00220     image = cStringIO.StringIO()
00221     c = Chart()
00222     c.addData(ChartData(views, color='green'))
00223     c.addData(ChartData(edits, color='red'))
00224     chart_title = ''
00225     if request.cfg.sitename:
00226         chart_title = "%s: " % request.cfg.sitename
00227     chart_title = chart_title + _('Page hits and edits')
00228     if filterpage:
00229         chart_title = _("%(chart_title)s for %(filterpage)s") % {
00230             'chart_title': chart_title,
00231             'filterpage': filterpage,
00232         }
00233     chart_title = "%s\n%sx%d" % (chart_title, _("green=view\nred=edit"), scalefactor)
00234     c.option(
00235         title=chart_title.encode('iso-8859-1', 'replace'), # gdchart can't do utf-8
00236         xtitle=(_('date') + ' (Server)').encode('iso-8859-1', 'replace'),
00237         ytitle=_('# of hits').encode('iso-8859-1', 'replace'),
00238         title_font=c.GDC_GIANT,
00239         #thumblabel = 'THUMB', thumbnail = 1, thumbval = 10,
00240         #ytitle_color = Color('green'),
00241         #yaxis2 = 1,
00242         #ytitle2 = '# of edits',
00243         #ytitle2_color = Color('red'),
00244         #ylabel2_color = Color('black'),
00245         #interpolations = 0,
00246         threed_depth=1.0,
00247         requested_yinterval=1.0,
00248         stack_type=c.GDC_STACK_BESIDE
00249     )
00250     c.draw(c.GDC_LINE,
00251         (request.cfg.chart_options['width'], request.cfg.chart_options['height']),
00252         image, days)
00253 
00254     request.content_type = 'image/gif'
00255     request.content_length = len(image.getvalue())
00256 
00257     # copy the image
00258     image.reset()
00259     shutil.copyfileobj(image, request, 8192)
00260 

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.stats.hitcounts.get_data (   pagename,
  request,
  filterpage = None 
)

Definition at line 54 of file hitcounts.py.

00054 
00055 def get_data(pagename, request, filterpage=None):
00056     cache_days, cache_views, cache_edits = [], [], []
00057     cache_date = 0
00058 
00059     # Get results from cache
00060     if filterpage:
00061         arena = Page(request, pagename)
00062         cache = caching.CacheEntry(request, arena, 'hitcounts', scope='item', use_pickle=True)
00063     else:
00064         arena = 'charts'
00065         cache = caching.CacheEntry(request, arena, 'hitcounts', scope='wiki', use_pickle=True)
00066 
00067     if cache.exists():
00068         try:
00069             cache_date, cache_days, cache_views, cache_edits = cache.content()
00070         except:
00071             cache.remove() # cache gone bad
00072 
00073     # Get new results from the log
00074     log = eventlog.EventLog(request)
00075     try:
00076         new_date = log.date()
00077     except logfile.LogMissing:
00078         new_date = None
00079 
00080     # prepare data
00081     days = []
00082     views = []
00083     edits = []
00084     ratchet_day = None
00085     ratchet_time = None
00086     if new_date is not None:
00087         log.set_filter(['VIEWPAGE', 'SAVEPAGE'])
00088         latest = None
00089         for event in log.reverse():
00090             # don't use event_log.date()
00091             if latest is None:
00092                 latest = event[0]
00093             event_usecs = event[0]
00094             if event_usecs <= cache_date:
00095                 break
00096             eventpage = event[2].get('pagename', '')
00097             if filterpage and eventpage != filterpage:
00098                 continue
00099             event_secs = wikiutil.version2timestamp(event_usecs)
00100             time_tuple = time.gmtime(event_secs) # must be UTC
00101             day = tuple(time_tuple[0:3])
00102             if day != ratchet_day:
00103                 # new day
00104                 while ratchet_time:
00105                     ratchet_time -= 86400 # seconds per day
00106                     rday = tuple(time.gmtime(ratchet_time)[0:3]) # must be UTC
00107                     if rday <= day:
00108                         break
00109                     days.append(DATE_FMT % rday)
00110                     views.append(0)
00111                     edits.append(0)
00112                 days.append(DATE_FMT % day)
00113                 views.append(0)
00114                 edits.append(0)
00115                 ratchet_day = day
00116                 ratchet_time = event_secs
00117             if event[1] == 'VIEWPAGE':
00118                 views[-1] += 1
00119             elif event[1] == 'SAVEPAGE':
00120                 edits[-1] += 1
00121 
00122         days.reverse()
00123         views.reverse()
00124         edits.reverse()
00125 
00126     # merge the day on the end of the cache
00127     if cache_days and days and days[0] == cache_days[-1]:
00128         cache_edits[-1] += edits[0]
00129         cache_views[-1] += views[0]
00130         days, views, edits = days[1:], views[1:], edits[1:]
00131 
00132     # Update and save the cache
00133     cache_days.extend(days)
00134     cache_views.extend(views)
00135     cache_edits.extend(edits)
00136     if new_date is not None:
00137         cache.update((latest, cache_days, cache_views, cache_edits))
00138 
00139     return cache_days, cache_views, cache_edits
00140 

Here is the caller graph for this function:

def MoinMoin.stats.hitcounts.linkto (   pagename,
  request,
  params = '' 
)

Definition at line 28 of file hitcounts.py.

00028 
00029 def linkto(pagename, request, params=''):
00030     _ = request.getText
00031 
00032     if not request.cfg.chart_options:
00033         return text(pagename, request, params)
00034 
00035     if _debug:
00036         return draw(pagename, request)
00037 
00038     page = Page(request, pagename)
00039 
00040     # Create escaped query string from dict and params
00041     querystr = {'action': 'chart', 'type': 'hitcounts'}
00042     querystr = wikiutil.makeQueryString(querystr)
00043     querystr = wikiutil.escape(querystr)
00044     if params:
00045         querystr += '&amp;' + params
00046 
00047     data = {'url': page.url(request, querystr)}
00048     data.update(request.cfg.chart_options)
00049     result = ('<img src="%(url)s" width="%(width)d" height="%(height)d"'
00050               ' alt="hitcounts chart">') % data
00051 
00052     return result
00053 

Here is the call graph for this function:

def MoinMoin.stats.hitcounts.text (   pagename,
  request,
  params = '' 
)

Definition at line 141 of file hitcounts.py.

00141 
00142 def text(pagename, request, params=''):
00143     from MoinMoin.util.dataset import TupleDataset, Column
00144     from MoinMoin.widget.browser import DataBrowserWidget
00145     _ = request.getText
00146 
00147     # check params
00148     filterpage = None
00149     if params.startswith('page='):
00150         filterpage = wikiutil.url_unquote(params[len('page='):])
00151 
00152     if request and request.values and 'page' in request.values:
00153         filterpage = request.values['page']
00154 
00155     days, views, edits = get_data(pagename, request, filterpage)
00156 
00157     hits = TupleDataset()
00158     hits.columns = [Column('day', label=_("Date"), align='left'),
00159                     Column('views', label=_("Views/day"), align='right'),
00160                     Column('edits', label=_("Edits/day"), align='right'),
00161                     ]
00162 
00163     maxentries = 30
00164 
00165     if maxentries < len(days):
00166         step = float(len(days))/ maxentries
00167     else:
00168         step = 1
00169 
00170     sv = 0.0
00171     se = 0.0
00172     sd = 0.0
00173     cnt = 0
00174 
00175     for i in xrange(len(days)-1, -1, -1):
00176         d, v, e = days[i], views[i], edits[i]
00177         # sum up views and edits to step days
00178         sd += 1
00179         cnt += 1
00180         sv += v
00181         se += e
00182         if cnt >= step:
00183             cnt -= step
00184             hits.addRow((d, "%.1f" % (sv/sd), "%.1f" % (se/sd)))
00185             sv = 0.0
00186             se = 0.0
00187             sd = 0.0
00188 
00189     table = DataBrowserWidget(request)
00190     table.setData(hits)
00191     return table.render(method="GET")
00192 

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 16 of file hitcounts.py.

string MoinMoin.stats.hitcounts.DATE_FMT = '%04d-%02d-%02d'

Definition at line 26 of file hitcounts.py.