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__':