Added statistics

This commit is contained in:
Ed 2023-01-19 17:02:57 +01:00
parent 3b8898491e
commit 6d247462bd
3 changed files with 106 additions and 22 deletions

24
app.py
View File

@ -20,8 +20,9 @@ app.ext.add_dependency(Quotas, get_quotas)
from room import bp as room_bp from room import bp as room_bp
from propic import bp as propic_bp from propic import bp as propic_bp
from export import bp as export_bp from export import bp as export_bp
from stats import bp as stats_bp
app.blueprint([room_bp,propic_bp,export_bp]) app.blueprint([room_bp,propic_bp,export_bp,stats_bp])
@app.exception(exceptions.SanicException) @app.exception(exceptions.SanicException)
async def clear_session(request, exception): async def clear_session(request, exception):
@ -51,27 +52,6 @@ async def gen_barcode(request, code):
return raw(img.getvalue(), content_type="image/png") return raw(img.getvalue(), content_type="image/png")
@app.route("/manage/cache")
async def cache_status(request):
return
@app.route("/manage/stats")
async def stats(request, order: Order):
with open('res/stats.json') as f:
stats = json.load(f)
tpl = app.ctx.tpl.get_template('stats.html')
return html(tpl.render(order=order, stats=stats))
@app.route("/manage/nosecount")
async def nose_count(request, order: Order):
orders = {key:value for key,value in sorted(app.ctx.om.cache.items(), key=lambda x: len(x[1].room_members), reverse=True) if value.status not in ['c', 'e']}
tpl = app.ctx.tpl.get_template('nosecount.html')
return html(tpl.render(orders=orders, order=order))
@app.route("/furizon/beyond/order/<code>/<secret>/open/<secret2>") @app.route("/furizon/beyond/order/<code>/<secret>/open/<secret2>")
async def redirect_explore(request, code, secret, order: Order, secret2=None): async def redirect_explore(request, code, secret, order: Order, secret2=None):

50
stats.py Normal file
View File

@ -0,0 +1,50 @@
from sanic.response import html
from sanic import Blueprint, exceptions
from ext import *
from config import headers
from time import time
import asyncio
bp = Blueprint("stats", url_prefix="/manage")
def by_count(d):
return {k:v for k,v in sorted(d.items(), key=lambda x: x[1], reverse=True)}
async def gen_stats(app):
orders = app.ctx.om.cache.values()
countries = {}
sponsors = {}
for o in orders:
countries[o.country] = countries.get(o.country, 0) +1
sponsors[o.sponsorship or 'no'] = sponsors.get(o.sponsorship or 'no', 0) +1
app.ctx.stats = {
'countries': by_count(countries),
'sponsors': by_count(sponsors),
'time': time()
}
return app.ctx.stats
@bp.route("/stats")
async def stats(request, order: Order):
stats = getattr(request.app.ctx, 'stats', None)
'''if not stats:
await gen_stats(request.app)
elif time() - stats['time'] > 1800:
asyncio.create_task(gen_stats(request.app))'''
request.app.ctx.stats = await gen_stats(request.app)
tpl = request.app.ctx.tpl.get_template('stats.html')
return html(tpl.render(order=order, stats=request.app.ctx.stats))
@bp.route("/nosecount")
async def nose_count(request, order: Order):
orders = {key:value for key,value in sorted(request.app.ctx.om.cache.items(), key=lambda x: len(x[1].room_members), reverse=True) if value.status not in ['c', 'e']}
tpl = request.app.ctx.tpl.get_template('nosecount.html')
return html(tpl.render(orders=orders, order=order))

54
tpl/stats.html Normal file
View File

@ -0,0 +1,54 @@
{% extends "base.html" %}
{% block title %}Furizon 2023 Stats{% endblock %}
{% block main %}
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<main class="container">
<header>
<picture>
<source srcset="/res/furizon.png" media="(prefers-color-scheme:dark)">
<img src="/res/furizon-light.png" style="height:4rem;text-align:center;">
</picture>
</header>
<h2>Countries</h2>
<div style="margin: 0 auto;">
<canvas id="countries"></canvas>
</div>
<script>
const ctx = document.getElementById('countries');
new Chart(ctx, {
type: 'bar',
data: {
labels: {{stats['countries'].keys()|list|safe}},
datasets: [{
label: '# of Attendees',
data: {{stats['countries'].values()|list|safe}},
borderWidth: 0
}]
},
options: {
scales: {
y: {beginAtZero: true}
}
}
});
</script>
<h2>Sponsors</h2>
<div style="max-width:20em;margin: 0 auto;">
<canvas id="sponsors"></canvas>
</div>
<script>
const ctx2 = document.getElementById('sponsors');
new Chart(ctx2, {
type: 'pie',
data: {
labels: {{stats['sponsors'].keys()|list|safe}},
datasets: [{
label: '# of Attendees',
data: {{stats['sponsors'].values()|list|safe}},
borderWidth: 0
}]
}
});
</script>
</main>
{% endblock %}