Skip to content

Commit

Permalink
Add admin page to see package storage usage
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenwardy committed Jan 18, 2024
1 parent acaf674 commit 406eb5d
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 4 deletions.
28 changes: 27 additions & 1 deletion app/blueprints/admin/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@
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"])
Expand Down Expand Up @@ -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)
9 changes: 6 additions & 3 deletions app/querybuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
class QueryBuilder:
types = None
search = None
only_approved = True

@property
def title(self):
Expand Down Expand Up @@ -155,10 +156,12 @@ def to_json(package: Package):

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))

Expand Down
1 change: 1 addition & 0 deletions app/templates/admin/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<a class="list-group-item list-group-item-action" href="{{ url_for('admin.warning_list') }}">Warning Editor</a>
<a class="list-group-item list-group-item-action" href="{{ url_for('admin.send_bulk_email') }}">Send bulk email</a>
<a class="list-group-item list-group-item-action" href="{{ url_for('admin.send_bulk_notification') }}">Send bulk notification</a>
<a class="list-group-item list-group-item-action" href="{{ url_for('admin.storage') }}">Storage usage</a>
<a class="list-group-item list-group-item-action" href="{{ url_for('admin.switch_user') }}">Sign in as another user</a>
</div>
</div>
Expand Down
66 changes: 66 additions & 0 deletions app/templates/admin/storage.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{% extends "base.html" %}

{% block title %}
Storage
{% endblock %}

{% block content %}
<h1>Storage</h1>
<p class="text-muted">
Shows storage use by package. Supports <a href="/help/api/#package-queries">Package Queries</a>, but always
sorts by total storage usage.
</p>

<div class="list-group">
<div class="list-group-item">
<div class="row text-muted">
<div class="col">
{{ _("Package") }}
</div>
<div class="col-2 text-center">
Latest release / MB
</div>
<div class="col-2 text-center">
Releases / MB
</div>
<div class="col-2 text-center">
Screenshots / MB
</div>
<div class="col-2 text-center">
Total / MB
</div>
</div>
</div>
{% for row in data %}
{% set package = row[0] %}
<a class="list-group-item list-group-item-action" href="{{ package.get_url('packages.list_releases') }}">
<div class="row">
<div class="col">
{{ _("%(title)s by %(author)s", title=package.title, author=package.author.display_name) }}
{% if package.state.name != "APPROVED" %}
<span class="badge bg-warning">
{{ package.state.value }}
</span>
{% endif %}
</div>
<div class="col-2 text-center">
{{ (row[4] / 1048576) | round | int }}
</div>
<div class="col-2 text-center">
{{ (row[2] / 1048576) | round | int }}
</div>
<div class="col-2 text-center">
{{ (row[3] / 1048576) | round | int }}
</div>
<div class="col-2 text-center">
{{ (row[1] / 1048576) | round | int }}
</div>
</div>
</a>
{% else %}
<div class="list-group-item text-muted">
<i>{{ _("No results") }}</i>
</div>
{% endfor %}
</div>
{% endblock %}

0 comments on commit 406eb5d

Please sign in to comment.