|
12 | 12 | from flask_login import login_required, current_user |
13 | 13 | from flask_wtf import FlaskForm |
14 | 14 | from jinja2.utils import markupsafe |
15 | | -from sqlalchemy import func, or_, and_ |
16 | | -from sqlalchemy.orm import joinedload, subqueryload |
| 15 | +from sqlalchemy import func, or_, and_, select |
| 16 | +from sqlalchemy.orm import joinedload, subqueryload, Session |
17 | 17 | from wtforms import SelectField, StringField, TextAreaField, IntegerField, SubmitField, BooleanField |
18 | 18 | from wtforms.validators import InputRequired, Length, Regexp, DataRequired, Optional, URL, NumberRange, ValidationError |
19 | 19 | from wtforms_sqlalchemy.fields import QuerySelectField, QuerySelectMultipleField |
|
31 | 31 | from app.models import Package, Tag, db, User, Tags, PackageState, Permission, PackageType, MetaPackage, ForumTopic, \ |
32 | 32 | Dependency, Thread, UserRank, PackageReview, PackageDevState, ContentWarning, License, AuditSeverity, \ |
33 | 33 | PackageScreenshot, NotificationType, AuditLogEntry, PackageAlias, PackageProvides, PackageGameSupport, \ |
34 | | - PackageDailyStats, Collection, ReleaseState, PackageAIDisclosure |
| 34 | + PackageDailyStats, Collection, ReleaseState, PackageAIDisclosure, LuantiRelease, PackageRelease |
35 | 35 | from app.utils.models import is_package_page, add_audit_log, get_package_by_info, \ |
36 | 36 | add_notification, get_system_user, get_games_from_csv, \ |
37 | 37 | post_to_approval_thread |
@@ -115,6 +115,41 @@ def user_redirect(author): |
115 | 115 | return redirect(url_for("users.profile", username=author)) |
116 | 116 |
|
117 | 117 |
|
| 118 | +def get_latest_releases_per_version(session: Session, package_id: int): |
| 119 | + ranked = ( |
| 120 | + select( |
| 121 | + LuantiRelease.id, |
| 122 | + PackageRelease.id, |
| 123 | + PackageRelease.name, |
| 124 | + PackageRelease.file_size_bytes, |
| 125 | + PackageRelease.created_at, |
| 126 | + func.row_number() |
| 127 | + .over( |
| 128 | + partition_by=LuantiRelease.id, |
| 129 | + order_by=PackageRelease.id.desc() |
| 130 | + ) |
| 131 | + .label("rn"), |
| 132 | + ) |
| 133 | + .join( |
| 134 | + PackageRelease, |
| 135 | + and_( |
| 136 | + PackageRelease.package_id == package_id, |
| 137 | + or_(PackageRelease.min_rel_id == None, PackageRelease.min_rel_id <= LuantiRelease.id), |
| 138 | + or_(PackageRelease.max_rel_id == None, PackageRelease.max_rel_id >= LuantiRelease.id), |
| 139 | + PackageRelease.state == ReleaseState.APPROVED, |
| 140 | + ) |
| 141 | + ) |
| 142 | + .subquery() |
| 143 | + ) |
| 144 | + |
| 145 | + stmt = select(ranked).where(ranked.c.rn == 1) |
| 146 | + rows = session.execute(stmt).all() |
| 147 | + return { |
| 148 | + luanti_release_id: release |
| 149 | + for luanti_release_id, *release in rows |
| 150 | + } |
| 151 | + |
| 152 | + |
118 | 153 | @bp.route("/packages/<author>/<name>/") |
119 | 154 | @is_package_page |
120 | 155 | def view(package): |
@@ -169,11 +204,19 @@ def view(package): |
169 | 204 | Collection.packages.contains(package), |
170 | 205 | Collection.name == "favorites").count() > 0 |
171 | 206 |
|
| 207 | + luanti_versions = LuantiRelease.query.filter(LuantiRelease.protocol > 0).order_by(db.asc(LuantiRelease.id)).all() |
| 208 | + import time |
| 209 | + start = time.perf_counter() |
| 210 | + latest_by_version = get_latest_releases_per_version(db.session, package.id) |
| 211 | + end = time.perf_counter() |
| 212 | + elapsed = f'Time taken: {(end - start):.6f} seconds' |
| 213 | + |
172 | 214 | return render_template("packages/view.html", |
173 | 215 | package=package, releases=releases.all(), packages_uses=packages_uses, |
174 | 216 | review_thread=review_thread, threads=threads.all(), reviews=reviews, validation=validation, |
175 | 217 | has_review=has_review, favorites_count=favorites_count, is_favorited=is_favorited, |
176 | | - public_collection_count=public_collection_count) |
| 218 | + public_collection_count=public_collection_count, luanti_versions=luanti_versions, |
| 219 | + latest_by_version=latest_by_version, elapsed=elapsed) |
177 | 220 |
|
178 | 221 |
|
179 | 222 | @bp.route("/packages/<author>/<name>/shields/<type>/") |
|
0 commit comments