Add downloads by package graph

This commit is contained in:
rubenwardy 2022-11-09 19:45:25 +00:00
parent f7742d47ff
commit 31aef061fb
3 changed files with 75 additions and 6 deletions

@ -1,5 +1,6 @@
import datetime
from datetime import timedelta from datetime import timedelta
from app.models import User, Package, PackageDailyStats, db from app.models import User, Package, PackageDailyStats, db, PackageState
from sqlalchemy import func from sqlalchemy import func
@ -59,4 +60,48 @@ def get_package_stats_for_user(user: User):
.group_by(PackageDailyStats.date) \ .group_by(PackageDailyStats.date) \
.all() .all()
return _flatten_data(stats) results = _flatten_data(stats)
results["package_downloads"] = get_package_overview_for_user(user, stats[0].date, stats[-1].date)
return results
def get_package_overview_for_user(user: User, start_date: datetime.date, end_date: datetime.date):
stats = db.session \
.query(PackageDailyStats.package_id, PackageDailyStats.date,
(PackageDailyStats.platform_minetest + PackageDailyStats.platform_other).label("downloads")) \
.filter(PackageDailyStats.package.has(author_id=user.id, state=PackageState.APPROVED)) \
.order_by(db.asc(PackageDailyStats.package_id), db.asc(PackageDailyStats.date)) \
.all()
stats_by_package = {}
for stat in stats:
bucket = stats_by_package.get(stat.package_id, [])
stats_by_package[stat.package_id] = bucket
bucket.append(stat)
package_title_by_id = {}
for package in user.packages.filter_by(state=PackageState.APPROVED).all():
package_title_by_id[package.id] = package.title
result = {}
for package_id, stats in stats_by_package.items():
i = 0
row = []
result[package_title_by_id[package_id]] = row
for date in daterange(start_date, end_date):
if i >= len(stats):
row.append(0)
continue
stat = stats[i]
if stat.date == date:
row.append(stat.downloads)
i += 1
else:
row.append(0)
return result

@ -78,6 +78,23 @@ async function load_data() {
return list.map((value, i) => ({ x: dates[i], y: value })); return list.map((value, i) => ({ x: dates[i], y: value }));
} }
if (json.package_downloads) {
const packageRecentDownloads = Object.fromEntries(Object.entries(json.package_downloads)
.map(([label, values]) => [label, sum(values.slice(-30))]));
console.log(packageRecentDownloads);
document.getElementById("downloads-by-package").classList.remove("d-none");
const ctx = document.getElementById("chart-packages").getContext("2d");
const data = {
datasets: Object.entries(json.package_downloads)
.sort((a, b) => packageRecentDownloads[a[0]] - packageRecentDownloads[b[0]])
.slice(0, 6)
.map(([label, values]) => ({ label, data: getData(values) })),
};
setup_chart(ctx, data);
}
{ {
const ctx = document.getElementById("chart-platform").getContext("2d"); const ctx = document.getElementById("chart-platform").getContext("2d");
const data = { const data = {
@ -148,9 +165,9 @@ function setup_chart(ctx, data) {
const colorIdx = data.datasets.length - i - 1; const colorIdx = data.datasets.length - i - 1;
return { return {
fill: true, fill: true,
backgroundColor: chartColorsBg[colorIdx], backgroundColor: chartColorsBg[colorIdx] ?? chartColorsBg[0],
borderColor: chartColors[colorIdx], borderColor: chartColors[colorIdx] ?? chartColors[0],
pointBackgroundColor: chartColors[colorIdx], pointBackgroundColor: chartColors[colorIdx] ?? chartColors[0],
...set, ...set,
}; };
}); });

@ -1,7 +1,7 @@
{% macro render_package_stats_js() %} {% macro render_package_stats_js() %}
<script src="/static/libs/chart.min.js"></script> <script src="/static/libs/chart.min.js"></script>
<script src="/static/libs/chartjs-adapter-date-fns.bundle.min.js"></script> <script src="/static/libs/chartjs-adapter-date-fns.bundle.min.js"></script>
<script src="/static/package_charts.js?v=5"></script> <script src="/static/package_charts.js?v=6"></script>
{% endmacro %} {% endmacro %}
@ -92,6 +92,13 @@
</div> </div>
<div id="stats-root" data-source="{{ source }}" style="display: none;"> <div id="stats-root" data-source="{{ source }}" style="display: none;">
<section id="downloads-by-package" class="d-none">
<h3>{{ _("Downloads by Package") }}</h3>
<p class="text-muted">
{{ _("This is a stacked area graph. For total downloads, look at the combined height.") }}
</p>
<canvas id="chart-packages" class="chart"></canvas>
</section>
<h3>{{ _("Downloads by Client") }}</h3> <h3>{{ _("Downloads by Client") }}</h3>
<p class="text-muted"> <p class="text-muted">