mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 18:24:30 -04:00
IGN:...
This commit is contained in:
parent
3e9e6a63d7
commit
a4243033e0
@ -6,7 +6,7 @@ __docformat__ = 'restructuredtext en'
|
|||||||
'''
|
'''
|
||||||
Keep track of donations to calibre.
|
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 datetime import date, timedelta
|
||||||
from math import sqrt
|
from math import sqrt
|
||||||
os.environ['HOME'] = '/tmp'
|
os.environ['HOME'] = '/tmp'
|
||||||
@ -15,7 +15,6 @@ matplotlib.use('Agg')
|
|||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
import matplotlib.dates as mdates
|
import matplotlib.dates as mdates
|
||||||
|
|
||||||
|
|
||||||
import cherrypy
|
import cherrypy
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
|
||||||
@ -34,6 +33,12 @@ def range_for_month(year, month):
|
|||||||
def range_for_year(year):
|
def range_for_year(year):
|
||||||
return date(year=year, month=1, day=1), date(year=year, month=12, day=31)
|
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):
|
def rationalize_country(country):
|
||||||
if re.match('(?i)(US|USA|America)', country):
|
if re.match('(?i)(US|USA|America)', country):
|
||||||
@ -140,6 +145,23 @@ class Stats:
|
|||||||
for country in self.countries.values():
|
for country in self.countries.values():
|
||||||
country.percent = (100 * country.total/self.total) if self.total else 0.
|
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):
|
def __str__(self):
|
||||||
buf = cStringIO.StringIO()
|
buf = cStringIO.StringIO()
|
||||||
print >>buf, '\tTotal: %.2f'%self.total
|
print >>buf, '\tTotal: %.2f'%self.total
|
||||||
@ -187,6 +209,7 @@ class Server(object):
|
|||||||
|
|
||||||
TRENDS = '/tmp/donations_trend.png'
|
TRENDS = '/tmp/donations_trend.png'
|
||||||
MONTH_TRENDS = '/tmp/donations_month_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'):
|
def __init__(self, apache=False, root='/', data_file='/tmp/donations.xml'):
|
||||||
self.apache = apache
|
self.apache = apache
|
||||||
@ -194,6 +217,21 @@ class Server(object):
|
|||||||
self.data_file = data_file
|
self.data_file = data_file
|
||||||
self.read_records()
|
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):
|
def calculate_month_trend(self, days=31):
|
||||||
stats = self.get_slice(date.today()-timedelta(days=days-1), date.today())
|
stats = self.get_slice(date.today()-timedelta(days=days-1), date.today())
|
||||||
fig = plt.figure(2, (10, 4), 96)#, facecolor, edgecolor, frameon, FigureClass)
|
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.earliest, self.latest = min_date, max_date
|
||||||
self.calculate_trend()
|
self.calculate_trend()
|
||||||
self.calculate_month_trend()
|
self.calculate_month_trend()
|
||||||
|
self.calculate_daily_averages()
|
||||||
|
|
||||||
def get_slice(self, start_date, end_date):
|
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],
|
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>
|
</table>
|
||||||
<hr />
|
<hr />
|
||||||
<div style="text-align:center">
|
<div style="text-align:center">
|
||||||
<h3>Income trends for the last year</h3>
|
|
||||||
<img src="%(root)strend.png" alt="Income trends" />
|
<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" />
|
<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>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@ -497,6 +539,11 @@ Donors per day: %(dpd).2f
|
|||||||
cherrypy.response.headers['Content-Type'] = 'image/png'
|
cherrypy.response.headers['Content-Type'] = 'image/png'
|
||||||
return open(self.MONTH_TRENDS, 'rb').read()
|
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
|
@expose
|
||||||
def show(self, period_type='month', month_month='', month_year='',
|
def show(self, period_type='month', month_month='', month_year='',
|
||||||
year_year='', range_left='', range_right=''):
|
year_year='', range_left='', range_right=''):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user