From e1f4787fb95c32cdbf6f9286b94ebb49e7a50889 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sun, 6 Nov 2022 10:32:46 +0000 Subject: [PATCH] Add package stats endpoint --- app/blueprints/api/endpoints.py | 9 +++++++++ app/flatpages/help/api.md | 10 ++++++++++ app/logic/graphs.py | 17 +++++++++++++++++ app/models/packages.py | 5 ++++- 4 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 app/logic/graphs.py diff --git a/app/blueprints/api/endpoints.py b/app/blueprints/api/endpoints.py index 083b2f7a..98822390 100644 --- a/app/blueprints/api/endpoints.py +++ b/app/blueprints/api/endpoints.py @@ -35,6 +35,8 @@ from .support import error, api_create_vcs_release, api_create_zip_release, api_ api_order_screenshots, api_edit_package, api_set_cover_image from functools import wraps +from ...logic.graphs import flatten_data + def cors_allowed(f): @wraps(f) @@ -433,6 +435,13 @@ def list_all_reviews(): }) +@bp.route("/api/packages///stats/") +@is_package_page +@cors_allowed +def package_stats(package: Package): + return jsonify(flatten_data(package)) + + @bp.route("/api/scores/") @cors_allowed def package_scores(): diff --git a/app/flatpages/help/api.md b/app/flatpages/help/api.md index 7b510d17..c804840d 100644 --- a/app/flatpages/help/api.md +++ b/app/flatpages/help/api.md @@ -108,6 +108,16 @@ Tokens can be attained by visiting [Settings > API Tokens](/user/tokens/). package dependency (`author/name`). * `optional_depends`: list of optional dependencies * Same as above. +* GET `/api/packages///stats/` + * Returns daily stats for package, or null if there is no data. + * EXPERIMENTAL. This API may change without warning. + * A table with the following keys: + * `dates`: list of dates in isoformat + * `platform_minetest`: list of integers per date + * `platform_other`: list of integers per date + * `reason_new`: list of integers per date + * `reason_dependency`: list of integers per date + * `reason_update`: list of integers per date You can download a package by building one of the two URLs: diff --git a/app/logic/graphs.py b/app/logic/graphs.py new file mode 100644 index 00000000..96af1ce1 --- /dev/null +++ b/app/logic/graphs.py @@ -0,0 +1,17 @@ +from app.models import Package, PackageDailyStats, db + + +def flatten_data(package: Package): + stats = package.daily_stats.order_by(db.asc(PackageDailyStats.date)).all() + if len(stats) == 0: + return None + + result = { + "dates": [stat.date.isoformat() for stat in stats], + } + + for key in ["platform_minetest", "platform_other", "reason_new", + "reason_dependency", "reason_update"]: + result[key] = [getattr(stat, key) for stat in stats] + + return result diff --git a/app/models/packages.py b/app/models/packages.py index 536b6f5c..f7614a43 100644 --- a/app/models/packages.py +++ b/app/models/packages.py @@ -468,6 +468,9 @@ class Package(db.Model): aliases = db.relationship("PackageAlias", foreign_keys="PackageAlias.package_id", back_populates="package", cascade="all, delete, delete-orphan") + daily_stats = db.relationship("PackageDailyStats", foreign_keys="PackageDailyStats.package_id", + back_populates="package", cascade="all, delete, delete-orphan", lazy="dynamic") + def __init__(self, package=None): if package is None: return @@ -1205,7 +1208,7 @@ class PackageAlias(db.Model): class PackageDailyStats(db.Model): package_id = db.Column(db.Integer, db.ForeignKey("package.id"), primary_key=True) - package = db.relationship("Package", foreign_keys=[package_id]) + package = db.relationship("Package", back_populates="daily_stats", foreign_keys=[package_id]) date = db.Column(db.Date, primary_key=True) platform_minetest = db.Column(db.Integer, nullable=False, default=0)