mirror of
https://github.com/minetest/contentdb.git
synced 2024-12-22 22:12:24 +01:00
Homepage: Improve performance by adjusting loading options
This commit is contained in:
parent
96c86cf070
commit
8619433b66
@ -18,11 +18,11 @@ from flask import Blueprint, render_template, redirect
|
|||||||
from sqlalchemy import and_
|
from sqlalchemy import and_
|
||||||
|
|
||||||
from app.models import Package, PackageReview, Thread, User, PackageState, db, PackageType, PackageRelease, Tags, Tag, \
|
from app.models import Package, PackageReview, Thread, User, PackageState, db, PackageType, PackageRelease, Tags, Tag, \
|
||||||
Collection
|
Collection, License
|
||||||
|
|
||||||
bp = Blueprint("homepage", __name__)
|
bp = Blueprint("homepage", __name__)
|
||||||
|
|
||||||
from sqlalchemy.orm import joinedload, subqueryload
|
from sqlalchemy.orm import joinedload, subqueryload, load_only, noload
|
||||||
from sqlalchemy.sql.expression import func
|
from sqlalchemy.sql.expression import func
|
||||||
|
|
||||||
|
|
||||||
@ -38,32 +38,47 @@ def gamejam():
|
|||||||
def home():
|
def home():
|
||||||
def package_load(query):
|
def package_load(query):
|
||||||
return query.options(
|
return query.options(
|
||||||
joinedload(Package.author),
|
load_only(Package.name, Package.title, Package.short_desc, Package.state, raiseload=True),
|
||||||
subqueryload(Package.main_screenshot),
|
subqueryload(Package.main_screenshot),
|
||||||
|
joinedload(Package.author).load_only(User.username, User.display_name, raiseload=True),
|
||||||
|
joinedload(Package.license).load_only(License.name, License.is_foss, raiseload=True),
|
||||||
|
joinedload(Package.media_license).load_only(License.name, License.is_foss, raiseload=True))
|
||||||
|
|
||||||
|
def package_spotlight_load(query):
|
||||||
|
return query.options(
|
||||||
|
load_only(Package.name, Package.title, Package.type, Package.short_desc, Package.state, Package.cover_image_id, raiseload=True),
|
||||||
|
subqueryload(Package.main_screenshot),
|
||||||
|
joinedload(Package.tags),
|
||||||
|
joinedload(Package.content_warnings),
|
||||||
|
joinedload(Package.author).load_only(User.username, User.display_name, raiseload=True),
|
||||||
subqueryload(Package.cover_image),
|
subqueryload(Package.cover_image),
|
||||||
joinedload(Package.license),
|
joinedload(Package.license).load_only(License.name, License.is_foss, raiseload=True),
|
||||||
joinedload(Package.media_license))
|
joinedload(Package.media_license).load_only(License.name, License.is_foss, raiseload=True))
|
||||||
|
|
||||||
def review_load(query):
|
def review_load(query):
|
||||||
return query.options(
|
return query.options(
|
||||||
joinedload(PackageReview.author),
|
load_only(PackageReview.id, PackageReview.rating, PackageReview.created_at, raiseload=True),
|
||||||
joinedload(PackageReview.thread).subqueryload(Thread.first_reply),
|
joinedload(PackageReview.author).load_only(User.username, User.rank, User.email, User.display_name, User.profile_pic, User.is_active, raiseload=True),
|
||||||
joinedload(PackageReview.package).joinedload(Package.author).load_only(User.username, User.display_name),
|
joinedload(PackageReview.votes),
|
||||||
joinedload(PackageReview.package).load_only(Package.title, Package.name).subqueryload(Package.main_screenshot))
|
joinedload(PackageReview.thread).load_only(Thread.title, Thread.replies_count, raiseload=True).subqueryload(Thread.first_reply),
|
||||||
|
joinedload(PackageReview.package)
|
||||||
|
.load_only(Package.title, Package.name, raiseload=True)
|
||||||
|
.joinedload(Package.author).load_only(User.username, User.display_name, raiseload=True))
|
||||||
|
|
||||||
query = Package.query.filter_by(state=PackageState.APPROVED)
|
query = Package.query.filter_by(state=PackageState.APPROVED)
|
||||||
count = query.count()
|
count = db.session.query(Package.id).filter(Package.state == PackageState.APPROVED).count()
|
||||||
|
|
||||||
spotlight_pkgs = query.filter(
|
spotlight_pkgs = package_spotlight_load(query.filter(
|
||||||
Package.collections.any(and_(Collection.name == "spotlight", Collection.author.has(username="ContentDB")))) \
|
Package.collections.any(and_(Collection.name == "spotlight", Collection.author.has(username="ContentDB"))))
|
||||||
.order_by(func.random()).limit(6).all()
|
.order_by(func.random())).limit(6).all()
|
||||||
|
|
||||||
new = package_load(query.order_by(db.desc(Package.approved_at))).limit(PKGS_PER_ROW).all()
|
new = package_load(query).order_by(db.desc(Package.approved_at)).limit(PKGS_PER_ROW).all() # 0.06
|
||||||
pop_mod = package_load(query.filter_by(type=PackageType.MOD).order_by(db.desc(Package.score))).limit(2*PKGS_PER_ROW).all()
|
pop_mod = package_load(query).filter_by(type=PackageType.MOD).order_by(db.desc(Package.score)).limit(2*PKGS_PER_ROW).all()
|
||||||
pop_gam = package_load(query.filter_by(type=PackageType.GAME).order_by(db.desc(Package.score))).limit(2*PKGS_PER_ROW).all()
|
pop_gam = package_load(query).filter_by(type=PackageType.GAME).order_by(db.desc(Package.score)).limit(2*PKGS_PER_ROW).all()
|
||||||
pop_txp = package_load(query.filter_by(type=PackageType.TXP).order_by(db.desc(Package.score))).limit(2*PKGS_PER_ROW).all()
|
pop_txp = package_load(query).filter_by(type=PackageType.TXP).order_by(db.desc(Package.score)).limit(2*PKGS_PER_ROW).all()
|
||||||
high_reviewed = package_load(query.order_by(db.desc(Package.score - Package.score_downloads))) \
|
|
||||||
.filter(Package.reviews.any()).limit(PKGS_PER_ROW).all()
|
high_reviewed = package_load(query.order_by(db.desc(Package.score - Package.score_downloads))
|
||||||
|
.filter(Package.reviews.any()).limit(PKGS_PER_ROW)).all()
|
||||||
|
|
||||||
recent_releases_query = (
|
recent_releases_query = (
|
||||||
db.session.query(
|
db.session.query(
|
||||||
|
@ -21,14 +21,14 @@ import enum
|
|||||||
from flask import url_for
|
from flask import url_for
|
||||||
from flask_babel import lazy_gettext
|
from flask_babel import lazy_gettext
|
||||||
from flask_sqlalchemy import BaseQuery
|
from flask_sqlalchemy import BaseQuery
|
||||||
from sqlalchemy import or_
|
from sqlalchemy import or_, func
|
||||||
|
from sqlalchemy.dialects.postgresql import insert
|
||||||
from sqlalchemy_searchable import SearchQueryMixin
|
from sqlalchemy_searchable import SearchQueryMixin
|
||||||
from sqlalchemy_utils.types import TSVectorType
|
from sqlalchemy_utils.types import TSVectorType
|
||||||
from sqlalchemy.dialects.postgresql import insert
|
|
||||||
|
|
||||||
|
from app import app
|
||||||
from . import db
|
from . import db
|
||||||
from .users import Permission, UserRank, User
|
from .users import Permission, UserRank, User
|
||||||
from app import app
|
|
||||||
|
|
||||||
|
|
||||||
class PackageQuery(BaseQuery, SearchQueryMixin):
|
class PackageQuery(BaseQuery, SearchQueryMixin):
|
||||||
@ -438,8 +438,8 @@ class Package(db.Model):
|
|||||||
threads = db.relationship("Thread", back_populates="package", order_by=db.desc("thread_created_at"),
|
threads = db.relationship("Thread", back_populates="package", order_by=db.desc("thread_created_at"),
|
||||||
foreign_keys="Thread.package_id", cascade="all, delete, delete-orphan", lazy="dynamic")
|
foreign_keys="Thread.package_id", cascade="all, delete, delete-orphan", lazy="dynamic")
|
||||||
|
|
||||||
reviews = db.relationship("PackageReview", back_populates="package",
|
reviews = db.relationship("PackageReview", back_populates="package", lazy="dynamic",
|
||||||
order_by=[db.desc("package_review_score"),db.desc("package_review_created_at")],
|
order_by=[db.desc("package_review_score"), db.desc("package_review_created_at")],
|
||||||
cascade="all, delete, delete-orphan")
|
cascade="all, delete, delete-orphan")
|
||||||
|
|
||||||
audit_log_entries = db.relationship("AuditLogEntry", foreign_keys="AuditLogEntry.package_id",
|
audit_log_entries = db.relationship("AuditLogEntry", foreign_keys="AuditLogEntry.package_id",
|
||||||
@ -785,6 +785,27 @@ class Package(db.Model):
|
|||||||
elif self.type == PackageType.GAME:
|
elif self.type == PackageType.GAME:
|
||||||
return "game.conf"
|
return "game.conf"
|
||||||
|
|
||||||
|
def get_review_summary(self):
|
||||||
|
from app.models import PackageReview
|
||||||
|
rows = (db.session.query(PackageReview.rating, func.count(PackageReview.id))
|
||||||
|
.select_from(PackageReview)
|
||||||
|
.where(PackageReview.package_id == self.id)
|
||||||
|
.group_by(PackageReview.rating)
|
||||||
|
.all())
|
||||||
|
|
||||||
|
negative = 0
|
||||||
|
neutral = 0
|
||||||
|
positive = 0
|
||||||
|
for rating, count in rows:
|
||||||
|
if rating > 3:
|
||||||
|
positive += count
|
||||||
|
elif rating == 3:
|
||||||
|
neutral += count
|
||||||
|
else:
|
||||||
|
negative += count
|
||||||
|
|
||||||
|
return [positive, neutral, negative]
|
||||||
|
|
||||||
|
|
||||||
class MetaPackage(db.Model):
|
class MetaPackage(db.Model):
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
|
@ -18,6 +18,8 @@ import datetime
|
|||||||
from typing import Tuple, List
|
from typing import Tuple, List
|
||||||
|
|
||||||
from flask import url_for
|
from flask import url_for
|
||||||
|
from sqlalchemy import select, func, text
|
||||||
|
from sqlalchemy.orm import column_property
|
||||||
|
|
||||||
from . import db
|
from . import db
|
||||||
from .users import Permission, UserRank, User
|
from .users import Permission, UserRank, User
|
||||||
@ -59,6 +61,11 @@ class Thread(db.Model):
|
|||||||
lazy=True, order_by=db.asc("id"), viewonly=True,
|
lazy=True, order_by=db.asc("id"), viewonly=True,
|
||||||
primaryjoin="Thread.id==ThreadReply.thread_id")
|
primaryjoin="Thread.id==ThreadReply.thread_id")
|
||||||
|
|
||||||
|
replies_count = column_property(select(func.count(text("thread_reply.id")))
|
||||||
|
.select_from(text("thread_reply"))
|
||||||
|
.where(text("thread_reply.thread_id") == id)
|
||||||
|
.as_scalar())
|
||||||
|
|
||||||
def get_description(self):
|
def get_description(self):
|
||||||
comment = self.first_reply.comment.replace("\r\n", " ").replace("\n", " ").replace(" ", " ")
|
comment = self.first_reply.comment.replace("\r\n", " ").replace("\n", " ").replace(" ", " ")
|
||||||
if len(comment) > 100:
|
if len(comment) > 100:
|
||||||
|
@ -79,10 +79,10 @@
|
|||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<a class="btn {% if review.thread.replies.count() > 1 %} btn-primary {% else %} btn-secondary {% endif %} me-1"
|
<a class="btn {% if review.thread.replies_count > 1 %} btn-primary {% else %} btn-secondary {% endif %} me-1"
|
||||||
href="{{ url_for('threads.view', id=review.thread.id) }}">
|
href="{{ url_for('threads.view', id=review.thread.id) }}">
|
||||||
<i class="fas fa-comments me-2"></i>
|
<i class="fas fa-comments me-2"></i>
|
||||||
{{ _("%(num)d comments", num=review.thread.replies.count() - 1) }}
|
{{ _("%(num)d comments", num=review.thread.replies_count - 1) }}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{{ render_review_vote(review, current_user, url_set_anchor(review_anchor)) }}
|
{{ render_review_vote(review, current_user, url_set_anchor(review_anchor)) }}
|
||||||
|
@ -216,7 +216,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% for t in threads %}
|
{% for t in threads %}
|
||||||
{% set replies = t.replies.count() - 1 %}
|
{% set replies = t.replies_count - 1 %}
|
||||||
|
|
||||||
<a class="list-group-item list-group-item-action"
|
<a class="list-group-item list-group-item-action"
|
||||||
href="{{ url_for('threads.view', id=t.id) }}">
|
href="{{ url_for('threads.view', id=t.id) }}">
|
||||||
|
Loading…
Reference in New Issue
Block a user