bitvend/bitvend/graphs.py

73 lines
2.1 KiB
Python

from datetime import date, datetime, timedelta
from sqlalchemy import func
import itertools
from bitvend.models import db, Transaction
def daterange(start_date, end_date):
for n in range(int((end_date - start_date).days) + 1):
yield (start_date + timedelta(n)).date()
def gen_graph_dataset(resultset, date_from=None, date_to=None, default=0):
date_hash = {
datetime.strptime(xdate, "%Y-%m-%d").date(): count for xdate, count in resultset
}
if not date_from:
date_from = min(date_hash.keys())
if not date_to:
date_to = datetime.utcnow().date()
return [
type(default)(date_hash[d]) if d in date_hash else default
for d in daterange(date_from, date_to)
]
def gen_database_graph(title, query, date_from, date_to, default=0):
date_column = query.column_descriptions[0]["expr"]
resultset = (
query.group_by(date_column)
.filter(date_column >= date_from, date_column <= date_to)
.all()
)
return [title] + gen_graph_dataset(resultset, date_from, date_to, default)
def zip_graph(dataset):
keys = [n[0] for n in dataset]
i = zip(*dataset)
next(i)
return [dict(zip(keys, values), values=None) for values in i]
def gen_main_graph(date_from=None, date_to=None):
if date_from is None:
date_from = date.today() - timedelta(days=30)
if date_to is None:
date_to = date.today()
date_from = datetime.combine(date_from, datetime.min.time())
date_to = datetime.combine(date_to, datetime.max.time())
return zip_graph(
[
["date"] + [n.strftime("%Y-%m-%d") for n in daterange(date_from, date_to)],
gen_database_graph(
"purchases",
db.session.query(
# func.date_trunc('day', Transaction.created),
func.strftime("%Y-%m-%d", Transaction.created),
func.count(Transaction.created),
).filter(Transaction.type == "purchase"),
date_from,
date_to,
),
]
)