mirror of
https://github.com/minetest/contentdb.git
synced 2025-01-09 22:47:36 +01:00
Add API to get all package stats
This commit is contained in:
parent
292b4f5483
commit
01bc519b86
@ -15,6 +15,7 @@
|
|||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import math
|
import math
|
||||||
|
from functools import wraps
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
import flask_sqlalchemy
|
import flask_sqlalchemy
|
||||||
@ -24,17 +25,16 @@ from sqlalchemy.orm import joinedload
|
|||||||
from sqlalchemy.sql.expression import func
|
from sqlalchemy.sql.expression import func
|
||||||
|
|
||||||
from app import csrf
|
from app import csrf
|
||||||
|
from app.logic.graphs import get_package_stats, get_package_stats_for_user, get_all_package_stats
|
||||||
from app.markdown import render_markdown
|
from app.markdown import render_markdown
|
||||||
from app.models import Tag, PackageState, PackageType, Package, db, PackageRelease, Permission, ForumTopic, \
|
from app.models import Tag, PackageState, PackageType, Package, db, PackageRelease, Permission, ForumTopic, \
|
||||||
MinetestRelease, APIToken, PackageScreenshot, License, ContentWarning, User, PackageReview, Thread
|
MinetestRelease, APIToken, PackageScreenshot, License, ContentWarning, User, PackageReview, Thread
|
||||||
from app.querybuilder import QueryBuilder
|
from app.querybuilder import QueryBuilder
|
||||||
from app.utils import is_package_page, get_int_or_abort, url_set_query, abs_url, isYes
|
from app.utils import is_package_page, get_int_or_abort, url_set_query, abs_url, isYes
|
||||||
from app.logic.graphs import get_package_stats, get_package_stats_for_user
|
|
||||||
from . import bp
|
from . import bp
|
||||||
from .auth import is_api_authd
|
from .auth import is_api_authd
|
||||||
from .support import error, api_create_vcs_release, api_create_zip_release, api_create_screenshot, \
|
from .support import error, api_create_vcs_release, api_create_zip_release, api_create_screenshot, \
|
||||||
api_order_screenshots, api_edit_package, api_set_cover_image
|
api_order_screenshots, api_edit_package, api_set_cover_image
|
||||||
from functools import wraps
|
|
||||||
|
|
||||||
|
|
||||||
def cors_allowed(f):
|
def cors_allowed(f):
|
||||||
@ -441,6 +441,12 @@ def package_stats(package: Package):
|
|||||||
return jsonify(get_package_stats(package))
|
return jsonify(get_package_stats(package))
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/api/package_stats/")
|
||||||
|
@cors_allowed
|
||||||
|
def all_package_stats():
|
||||||
|
return jsonify(get_all_package_stats())
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/api/scores/")
|
@bp.route("/api/scores/")
|
||||||
@cors_allowed
|
@cors_allowed
|
||||||
def package_scores():
|
def package_scores():
|
||||||
|
@ -112,14 +112,20 @@ Tokens can be attained by visiting [Settings > API Tokens](/user/tokens/).
|
|||||||
* Returns daily stats for package, or null if there is no data.
|
* Returns daily stats for package, or null if there is no data.
|
||||||
* Daily date is done based on the UTC timezone.
|
* Daily date is done based on the UTC timezone.
|
||||||
* EXPERIMENTAL. This API may change without warning.
|
* EXPERIMENTAL. This API may change without warning.
|
||||||
* A table with the following keys:
|
* An object with the following keys:
|
||||||
* `from`: start date, inclusive. Ex: 2022-10-22.
|
* `start`: start date, inclusive. Ex: 2022-10-22.
|
||||||
* `end`: end date, inclusive. Ex: 2022-11-05.
|
* `end`: end date, inclusive. Ex: 2022-11-05.
|
||||||
* `platform_minetest`: list of integers per day.
|
* `platform_minetest`: list of integers per day.
|
||||||
* `platform_other`: list of integers per day.
|
* `platform_other`: list of integers per day.
|
||||||
* `reason_new`: list of integers per day.
|
* `reason_new`: list of integers per day.
|
||||||
* `reason_dependency`: list of integers per day.
|
* `reason_dependency`: list of integers per day.
|
||||||
* `reason_update`: list of integers per day.
|
* `reason_update`: list of integers per day.
|
||||||
|
* GET `/api/package_stats/`
|
||||||
|
* Returns last 30 days of daily stats for _all_ packages.
|
||||||
|
* An object with the following keys:
|
||||||
|
* `start`: start date, inclusive. Ex: 2022-10-22.
|
||||||
|
* `end`: end date, inclusive. Ex: 2022-11-05.
|
||||||
|
* `package_downloads`: map from package key to list of download integers.
|
||||||
|
|
||||||
You can download a package by building one of the two URLs:
|
You can download a package by building one of the two URLs:
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import datetime
|
import datetime
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from app.models import User, Package, PackageDailyStats, db, PackageState
|
from app.models import User, Package, PackageDailyStats, db, PackageState
|
||||||
from sqlalchemy import func
|
from sqlalchemy import func
|
||||||
|
|
||||||
@ -68,11 +70,16 @@ def get_package_stats_for_user(user: User):
|
|||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
||||||
def get_package_overview_for_user(user: User, start_date: datetime.date, end_date: datetime.date):
|
def get_package_overview_for_user(user: Optional[User], start_date: datetime.date, end_date: datetime.date):
|
||||||
stats = db.session \
|
query = db.session \
|
||||||
.query(PackageDailyStats.package_id, PackageDailyStats.date,
|
.query(PackageDailyStats.package_id, PackageDailyStats.date,
|
||||||
(PackageDailyStats.platform_minetest + PackageDailyStats.platform_other).label("downloads")) \
|
(PackageDailyStats.platform_minetest + PackageDailyStats.platform_other).label("downloads"))
|
||||||
.filter(PackageDailyStats.package.has(author_id=user.id, state=PackageState.APPROVED)) \
|
|
||||||
|
if user:
|
||||||
|
query = query.filter(PackageDailyStats.package.has(author_id=user.id))
|
||||||
|
|
||||||
|
stats = query \
|
||||||
|
.filter(PackageDailyStats.package.has(state=PackageState.APPROVED)) \
|
||||||
.order_by(db.asc(PackageDailyStats.package_id), db.asc(PackageDailyStats.date)) \
|
.order_by(db.asc(PackageDailyStats.package_id), db.asc(PackageDailyStats.date)) \
|
||||||
.all()
|
.all()
|
||||||
|
|
||||||
@ -84,8 +91,12 @@ def get_package_overview_for_user(user: User, start_date: datetime.date, end_dat
|
|||||||
bucket.append(stat)
|
bucket.append(stat)
|
||||||
|
|
||||||
package_title_by_id = {}
|
package_title_by_id = {}
|
||||||
for package in user.packages.filter_by(state=PackageState.APPROVED).all():
|
pkg_query = user.packages if user else Package.query
|
||||||
|
for package in pkg_query.filter_by(state=PackageState.APPROVED).all():
|
||||||
|
if user:
|
||||||
package_title_by_id[package.id] = package.title
|
package_title_by_id[package.id] = package.title
|
||||||
|
else:
|
||||||
|
package_title_by_id[package.id] = package.getId()
|
||||||
|
|
||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
@ -105,5 +116,14 @@ def get_package_overview_for_user(user: User, start_date: datetime.date, end_dat
|
|||||||
else:
|
else:
|
||||||
row.append(0)
|
row.append(0)
|
||||||
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def get_all_package_stats():
|
||||||
|
end_date = datetime.datetime.utcnow().date()
|
||||||
|
start_date = (datetime.datetime.utcnow() - datetime.timedelta(days=29)).date()
|
||||||
|
return {
|
||||||
|
"start": start_date.isoformat(),
|
||||||
|
"end": end_date.isoformat(),
|
||||||
|
"package_downloads": get_package_overview_for_user(None, start_date, end_date),
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user