change(popupdate): converted to use aurweb.db ORM

Signed-off-by: Kevin Morris <kevr@0cost.org>
This commit is contained in:
Kevin Morris 2021-11-17 07:54:52 -08:00
parent 3a65e33abe
commit 3efb9a57b5
No known key found for this signature in database
GPG key ID: F7E46DED420788F3
3 changed files with 57 additions and 41 deletions

View file

@ -908,8 +908,7 @@ async def pkgbase_vote(request: Request, name: str):
VoteTS=now)
# Update NumVotes/Popularity.
conn = db.ConnectionExecutor(db.get_engine().raw_connection())
popupdate.run_single(conn, pkgbase)
popupdate.run_single(pkgbase)
return RedirectResponse(f"/pkgbase/{name}",
status_code=HTTPStatus.SEE_OTHER)
@ -929,8 +928,7 @@ async def pkgbase_unvote(request: Request, name: str):
db.delete(vote)
# Update NumVotes/Popularity.
conn = db.ConnectionExecutor(db.get_engine().raw_connection())
popupdate.run_single(conn, pkgbase)
popupdate.run_single(pkgbase)
return RedirectResponse(f"/pkgbase/{name}",
status_code=HTTPStatus.SEE_OTHER)
@ -1473,8 +1471,7 @@ async def pkgbase_merge_post(request: Request, name: str,
pkgbase_merge_instance(request, pkgbase, target)
# Run popupdate on the target.
conn = db.ConnectionExecutor(db.get_engine().raw_connection())
popupdate.run_single(conn, target)
popupdate.run_single(target)
if not next:
next = f"/pkgbase/{target.Name}"

View file

@ -1,51 +1,71 @@
#!/usr/bin/env python3
from datetime import datetime
from typing import List
import aurweb.db
from sqlalchemy import and_, func
from sqlalchemy.sql.functions import coalesce
from sqlalchemy.sql.functions import sum as _sum
from aurweb import db
from aurweb.models import PackageBase, PackageVote
def run_single(conn, pkgbase):
def run_variable(pkgbases: List[PackageBase] = []) -> None:
"""
Update popularity on a list of PackageBases.
If no PackageBase is included, we update the popularity
of every PackageBase in the database.
:param pkgbases: List of PackageBase instances
"""
now = int(datetime.utcnow().timestamp())
# NumVotes subquery.
votes_subq = db.get_session().query(
func.count("*")
).select_from(PackageVote).filter(
PackageVote.PackageBaseID == PackageBase.ID
)
# Popularity subquery.
pop_subq = db.get_session().query(
coalesce(_sum(func.pow(0.98, (now - PackageVote.VoteTS) / 86400)), 0.0),
).select_from(PackageVote).filter(
and_(PackageVote.PackageBaseID == PackageBase.ID,
PackageVote.VoteTS.isnot(None))
)
with db.begin():
query = db.query(PackageBase)
ids = set()
if pkgbases:
ids = {pkgbase.ID for pkgbase in pkgbases}
query = query.filter(PackageBase.ID.in_(ids))
query.update({
"NumVotes": votes_subq.scalar_subquery(),
"Popularity": pop_subq.scalar_subquery()
})
def run_single(pkgbase: PackageBase) -> None:
""" 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.refresh(pkgbase)
run_variable([pkgbase])
db.refresh(pkgbase)
def main():
conn = aurweb.db.Connection()
conn.execute("UPDATE PackageBases SET NumVotes = ("
"SELECT COUNT(*) FROM PackageVotes "
"WHERE PackageVotes.PackageBaseID = PackageBases.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)", [now])
conn.commit()
conn.close()
db.get_engine()
run_variable()
if __name__ == '__main__':

View file

@ -9,7 +9,7 @@ import pytest
from fastapi.testclient import TestClient
from redis.client import Pipeline
from aurweb import asgi, config, db, scripts
from aurweb import asgi, config, scripts
from aurweb.db import begin, create, query
from aurweb.models.account_type import AccountType
from aurweb.models.dependency_type import DependencyType
@ -187,8 +187,7 @@ def setup(db_test):
PackageBase=pkgbase1,
VoteTS=5000)
conn = db.ConnectionExecutor(db.get_engine().raw_connection())
scripts.popupdate.run_single(conn, pkgbase1)
scripts.popupdate.run_single(pkgbase1)
@pytest.fixture