diff --git a/app/blueprints/admin/admin.py b/app/blueprints/admin/admin.py index fb59fbd3..6b81b949 100644 --- a/app/blueprints/admin/admin.py +++ b/app/blueprints/admin/admin.py @@ -19,10 +19,12 @@ from flask_login import current_user, login_user from flask_wtf import FlaskForm from wtforms import StringField, SubmitField, BooleanField from wtforms.validators import InputRequired, Length, Optional -from app.utils import rank_required, add_audit_log, add_notification, get_system_user, nonempty_or_none +from app.utils import rank_required, add_audit_log, add_notification, get_system_user, nonempty_or_none, \ + get_int_or_abort from . import bp from .actions import actions from app.models import UserRank, Package, db, PackageState, User, AuditSeverity, NotificationType, PackageAlias +from ...querybuilder import QueryBuilder @bp.route("/admin/", methods=["GET", "POST"]) @@ -179,3 +181,27 @@ def transfer(): # Process GET or invalid POST return render_template("admin/transfer.html", form=form) + + +@bp.route("/admin/storage/") +@rank_required(UserRank.EDITOR) +def storage(): + qb = QueryBuilder(request.args, cookies=True) + qb.only_approved = False + packages = qb.build_package_query().all() + + show_all = len(packages) < 100 + min_size = get_int_or_abort(request.args.get("min_size"), 0 if show_all else 50) + + data = [] + for package in packages: + size_releases = sum([x.file_size_bytes for x in package.releases]) + size_screenshots = sum([x.file_size_bytes for x in package.screenshots]) + latest_release = package.releases.first() + size_latest = latest_release.file_size_bytes if latest_release else 0 + size_total = size_releases + size_screenshots + if size_total > min_size*10024*1024: + data.append([package, size_total, size_releases, size_screenshots, size_latest]) + + data.sort(key=lambda x: x[1], reverse=True) + return render_template("admin/storage.html", data=data) diff --git a/app/querybuilder.py b/app/querybuilder.py index 50357cc5..66f27690 100644 --- a/app/querybuilder.py +++ b/app/querybuilder.py @@ -29,6 +29,7 @@ from .utils import is_yes, get_int_or_abort class QueryBuilder: types = None search = None + only_approved = True @property def title(self): @@ -155,10 +156,12 @@ class QueryBuilder: def build_package_query(self): if self.order_by == "last_release": - query = db.session.query(Package).select_from(PackageRelease).join(Package) \ - .filter_by(state=PackageState.APPROVED) + query = db.session.query(Package).select_from(PackageRelease).join(Package) else: - query = Package.query.filter_by(state=PackageState.APPROVED) + query = Package.query + + if self.only_approved: + query = query.filter(Package.state == PackageState.APPROVED) query = query.options(subqueryload(Package.main_screenshot), subqueryload(Package.aliases)) diff --git a/app/templates/admin/list.html b/app/templates/admin/list.html index c3371490..565a4e3e 100644 --- a/app/templates/admin/list.html +++ b/app/templates/admin/list.html @@ -17,6 +17,7 @@ Warning Editor Send bulk email Send bulk notification + Storage usage Sign in as another user diff --git a/app/templates/admin/storage.html b/app/templates/admin/storage.html new file mode 100644 index 00000000..b2a4a34a --- /dev/null +++ b/app/templates/admin/storage.html @@ -0,0 +1,66 @@ +{% extends "base.html" %} + +{% block title %} + Storage +{% endblock %} + +{% block content %} +
+ Shows storage use by package. Supports Package Queries, but always + sorts by total storage usage. +
+ +