mirror of
https://gitlab.archlinux.org/archlinux/aurweb.git
synced 2025-02-03 10:43:03 +01:00
change(popupdate): converted to use aurweb.db ORM
Signed-off-by: Kevin Morris <kevr@0cost.org>
This commit is contained in:
parent
3a65e33abe
commit
3efb9a57b5
3 changed files with 57 additions and 41 deletions
|
@ -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}"
|
||||
|
|
|
@ -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__':
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue