diff --git a/aurweb/routers/packages.py b/aurweb/routers/packages.py index 4426d0be..f806f054 100644 --- a/aurweb/routers/packages.py +++ b/aurweb/routers/packages.py @@ -30,7 +30,7 @@ from aurweb.models.request_type import DELETION_ID, RequestType from aurweb.models.user import User from aurweb.packages.search import PackageSearch from aurweb.packages.util import get_pkg_or_base, get_pkgbase_comment, query_notified, query_voted -from aurweb.scripts import notify +from aurweb.scripts import notify, popupdate from aurweb.scripts.rendercomment import update_comment_render from aurweb.templates import make_context, render_raw_template, render_template @@ -858,6 +858,10 @@ async def pkgbase_vote(request: Request, name: str): PackageBase=pkgbase, VoteTS=now) + # Update NumVotes/Popularity. + conn = db.ConnectionExecutor(db.get_engine().raw_connection()) + popupdate.run_single(conn, pkgbase) + return RedirectResponse(f"/pkgbase/{name}", status_code=int(HTTPStatus.SEE_OTHER)) @@ -875,6 +879,10 @@ async def pkgbase_unvote(request: Request, name: str): with db.begin(): db.session.delete(vote) + # Update NumVotes/Popularity. + conn = db.ConnectionExecutor(db.get_engine().raw_connection()) + popupdate.run_single(conn, pkgbase) + return RedirectResponse(f"/pkgbase/{name}", status_code=int(HTTPStatus.SEE_OTHER)) diff --git a/aurweb/scripts/popupdate.py b/aurweb/scripts/popupdate.py index b1e70403..fa82208d 100755 --- a/aurweb/scripts/popupdate.py +++ b/aurweb/scripts/popupdate.py @@ -1,20 +1,47 @@ #!/usr/bin/env python3 -import time +from datetime import datetime import aurweb.db +def run_single(conn, pkgbase): + """ A single popupdate. The given pkgbase instance will be + refreshed after the database update is done. + + NOTE: This function is compatible only with aurweb FastAPI. + + :param conn: db.Connection[Executor] + :param pkgbase: Instance of db.PackageBase + """ + + conn.execute("UPDATE PackageBases SET NumVotes = (" + "SELECT COUNT(*) FROM PackageVotes " + "WHERE PackageVotes.PackageBaseID = PackageBases.ID) " + "WHERE PackageBases.ID = ?", [pkgbase.ID]) + + now = int(datetime.utcnow().timestamp()) + conn.execute("UPDATE PackageBases SET Popularity = (" + "SELECT COALESCE(SUM(POWER(0.98, (? - VoteTS) / 86400)), 0.0) " + "FROM PackageVotes WHERE PackageVotes.PackageBaseID = " + "PackageBases.ID AND NOT VoteTS IS NULL) WHERE " + "PackageBases.ID = ?", [now, pkgbase.ID]) + + conn.commit() + conn.close() + aurweb.db.session.refresh(pkgbase) + + def main(): conn = aurweb.db.Connection() - conn.execute("UPDATE PackageBases SET NumVotes = (" + - "SELECT COUNT(*) FROM PackageVotes " + + conn.execute("UPDATE PackageBases SET NumVotes = (" + "SELECT COUNT(*) FROM PackageVotes " "WHERE PackageVotes.PackageBaseID = PackageBases.ID)") - now = int(time.time()) - conn.execute("UPDATE PackageBases SET Popularity = (" + - "SELECT COALESCE(SUM(POWER(0.98, (? - VoteTS) / 86400)), 0.0) " + - "FROM PackageVotes WHERE PackageVotes.PackageBaseID = " + + now = int(datetime.utcnow().timestamp()) + conn.execute("UPDATE PackageBases SET Popularity = (" + "SELECT COALESCE(SUM(POWER(0.98, (? - VoteTS) / 86400)), 0.0) " + "FROM PackageVotes WHERE PackageVotes.PackageBaseID = " "PackageBases.ID AND NOT VoteTS IS NULL)", [now]) conn.commit() diff --git a/test/test_packages_routes.py b/test/test_packages_routes.py index 1f258497..7b9c520c 100644 --- a/test/test_packages_routes.py +++ b/test/test_packages_routes.py @@ -1771,6 +1771,7 @@ def test_pkgbase_vote(client: TestClient, user: User, package: Package): vote = pkgbase.package_votes.filter(PackageVote.UsersID == user.ID).first() assert vote is not None + assert pkgbase.NumVotes == 1 # Remove vote. endpoint = f"/pkgbase/{pkgbase.Name}/unvote" @@ -1780,6 +1781,7 @@ def test_pkgbase_vote(client: TestClient, user: User, package: Package): vote = pkgbase.package_votes.filter(PackageVote.UsersID == user.ID).first() assert vote is None + assert pkgbase.NumVotes == 0 def test_pkgbase_disown_as_tu(client: TestClient, tu_user: User,