From 31aef061fb009fdcfdc477c7f501469906e31adb Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Wed, 9 Nov 2022 19:45:25 +0000 Subject: [PATCH] Add downloads by package graph --- app/logic/graphs.py | 49 +++++++++++++++++++++++++++-- app/public/static/package_charts.js | 23 ++++++++++++-- app/templates/macros/stats.html | 9 +++++- 3 files changed, 75 insertions(+), 6 deletions(-) diff --git a/app/logic/graphs.py b/app/logic/graphs.py index 99f3962f..831e9884 100644 --- a/app/logic/graphs.py +++ b/app/logic/graphs.py @@ -1,5 +1,6 @@ +import datetime 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 @@ -59,4 +60,48 @@ def get_package_stats_for_user(user: User): .group_by(PackageDailyStats.date) \ .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 diff --git a/app/public/static/package_charts.js b/app/public/static/package_charts.js index c2d3faef..862ac98f 100644 --- a/app/public/static/package_charts.js +++ b/app/public/static/package_charts.js @@ -78,6 +78,23 @@ async function load_data() { 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 data = { @@ -148,9 +165,9 @@ function setup_chart(ctx, data) { const colorIdx = data.datasets.length - i - 1; return { fill: true, - backgroundColor: chartColorsBg[colorIdx], - borderColor: chartColors[colorIdx], - pointBackgroundColor: chartColors[colorIdx], + backgroundColor: chartColorsBg[colorIdx] ?? chartColorsBg[0], + borderColor: chartColors[colorIdx] ?? chartColors[0], + pointBackgroundColor: chartColors[colorIdx] ?? chartColors[0], ...set, }; }); diff --git a/app/templates/macros/stats.html b/app/templates/macros/stats.html index b712ad92..a2aa0222 100644 --- a/app/templates/macros/stats.html +++ b/app/templates/macros/stats.html @@ -1,7 +1,7 @@ {% macro render_package_stats_js() %} - + {% endmacro %} @@ -92,6 +92,13 @@