This commit is contained in:
Kovid Goyal 2009-05-10 17:54:18 -07:00
parent 3e9e6a63d7
commit a4243033e0

View File

@ -6,7 +6,7 @@ __docformat__ = 'restructuredtext en'
'''
Keep track of donations to calibre.
'''
import sys, cStringIO, textwrap, traceback, re, os, time
import sys, cStringIO, textwrap, traceback, re, os, time, calendar
from datetime import date, timedelta
from math import sqrt
os.environ['HOME'] = '/tmp'
@ -15,7 +15,6 @@ matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import cherrypy
from lxml import etree
@ -34,6 +33,12 @@ def range_for_month(year, month):
def range_for_year(year):
return date(year=year, month=1, day=1), date(year=year, month=12, day=31)
def days_in_month(year, month):
c = calendar.Calendar()
ans = 0
for x in c.itermonthdays(year, month):
if x != 0: ans += 1
return ans
def rationalize_country(country):
if re.match('(?i)(US|USA|America)', country):
@ -140,6 +145,23 @@ class Stats:
for country in self.countries.values():
country.percent = (100 * country.total/self.total) if self.total else 0.
def get_daily_averages(self):
month_buckets, month_order = {}, []
x = self.min
for t in self.daily_totals:
month = (x.year, x.month)
if month not in month_buckets:
month_buckets[month] = 0.
month_order.append(month)
month_buckets[month] += t
x += timedelta(days=1)
c = calendar.Calendar()
month_days = [days_in_month(*x) for x in month_order]
month_averages = [month_buckets[x]/float(y) for x, y in zip(month_order, month_days)]
return month_order, month_averages
def __str__(self):
buf = cStringIO.StringIO()
print >>buf, '\tTotal: %.2f'%self.total
@ -187,6 +209,7 @@ class Server(object):
TRENDS = '/tmp/donations_trend.png'
MONTH_TRENDS = '/tmp/donations_month_trend.png'
AVERAGES = '/tmp/donations_averages.png'
def __init__(self, apache=False, root='/', data_file='/tmp/donations.xml'):
self.apache = apache
@ -194,6 +217,21 @@ class Server(object):
self.data_file = data_file
self.read_records()
def calculate_daily_averages(self):
stats = self.get_slice(self.earliest, self.latest)
fig = plt.figure(2, (10, 4), 96)#, facecolor, edgecolor, frameon, FigureClass)
fig.clear()
ax = fig.add_subplot(111)
month_order, month_averages = stats.get_daily_averages()
x = [date(y, m, 1) for y, m in month_order[:-1]]
ax.plot(x, month_averages[:-1])
ax.set_xlabel('Month')
ax.set_ylabel('Daily average ($)')
ax.xaxis.set_major_locator(mdates.MonthLocator(interval=2))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%m/%y'))
fig.savefig(self.AVERAGES)
def calculate_month_trend(self, days=31):
stats = self.get_slice(date.today()-timedelta(days=days-1), date.today())
fig = plt.figure(2, (10, 4), 96)#, facecolor, edgecolor, frameon, FigureClass)
@ -269,6 +307,7 @@ Donors per day: %(dpd).2f
self.earliest, self.latest = min_date, max_date
self.calculate_trend()
self.calculate_month_trend()
self.calculate_daily_averages()
def get_slice(self, start_date, end_date):
stats = Stats([r for r in self.records if r.date >= start_date and r.date <= end_date],
@ -463,10 +502,13 @@ Donors per day: %(dpd).2f
</table>
<hr />
<div style="text-align:center">
<h3>Income trends for the last year</h3>
<img src="%(root)strend.png" alt="Income trends" />
<h3>Income trends for the last 31 days</h3>
<h3>Income trends for the last year</h3>
<img src="%(root)smonth_trend.png" alt="Month income trend" />
<h3>Income trends for the last 31 days</h3>
<img src="%(root)saverage_trend.png" alt="Daily average
income trend" />
<h3>Income trends since records started</h3>
</div>
</body>
</html>
@ -497,6 +539,11 @@ Donors per day: %(dpd).2f
cherrypy.response.headers['Content-Type'] = 'image/png'
return open(self.MONTH_TRENDS, 'rb').read()
@expose
def average_trend_png(self):
cherrypy.response.headers['Content-Type'] = 'image/png'
return open(self.AVERAGES, 'rb').read()
@expose
def show(self, period_type='month', month_month='', month_year='',
year_year='', range_left='', range_right=''):