leaderboards: annotate the db param, fix posts and comments, and move const to const file, etc

master
justcool393 2022-10-28 04:19:07 -05:00
parent d6f1f3c070
commit cfeafea0d4
3 changed files with 25 additions and 20 deletions

View File

@ -1,5 +1,8 @@
from typing import Any, Callable, Optional, Tuple from typing import Any, Callable, Optional, Tuple
from sqlalchemy import func from sqlalchemy import func
from sqlalchemy.orm import scoped_session
from files.helpers.const import LEADERBOARD_LIMIT
from .badges import Badge from .badges import Badge
from .marsey import Marsey from .marsey import Marsey
@ -7,7 +10,8 @@ from .user import User
from .userblock import UserBlock from .userblock import UserBlock
class Leaderboard: class Leaderboard:
"""Represents an request-context leaderboard. None of this is persisted yet, """
Represents an request-context leaderboard. None of this is persisted yet,
although this is probably a good idea to do at some point. although this is probably a good idea to do at some point.
""" """
all_users = None all_users = None
@ -17,7 +21,7 @@ class Leaderboard:
def __init__(self, header_name:str, table_header_name:str, html_id:str, table_column_name:str, def __init__(self, header_name:str, table_header_name:str, html_id:str, table_column_name:str,
user_relative_url:Optional[str], query_function:Callable[..., Tuple[Any, Any, Any]], user_relative_url:Optional[str], query_function:Callable[..., Tuple[Any, Any, Any]],
criteria, v:User, value_func:Optional[Callable[[User], int]], db, users, limit=25): criteria, v:User, value_func:Optional[Callable[[User], int]], db:scoped_session, users, limit=LEADERBOARD_LIMIT):
self.header_name = header_name self.header_name = header_name
self.table_header_name = table_header_name self.table_header_name = table_header_name
self.html_id = html_id self.html_id = html_id
@ -36,7 +40,7 @@ class Leaderboard:
self.value_func = lambda u: u[1] self.value_func = lambda u: u[1]
@classmethod @classmethod
def get_simple_lb(cls, order_by, v:User, db, users, limit): def get_simple_lb(cls, order_by, v:User, db:scoped_session, users, limit:int):
leaderboard = users.order_by(order_by.desc()).limit(limit).all() leaderboard = users.order_by(order_by.desc()).limit(limit).all()
position = None position = None
if v not in leaderboard: if v not in leaderboard:
@ -53,7 +57,7 @@ class Leaderboard:
return func.rank().over(order_by=func.count(criteria).desc()).label("rank") return func.rank().over(order_by=func.count(criteria).desc()).label("rank")
@classmethod @classmethod
def get_badge_marsey_lb(cls, lb_criteria, v:User, db, users:Any, limit): def get_badge_marsey_lb(cls, lb_criteria, v:User, db:scoped_session, users:Any, limit):
sq = db.query(lb_criteria, cls.count_and_label(lb_criteria), cls.rank_filtered_rank_label_by_desc(lb_criteria)).group_by(lb_criteria).subquery() sq = db.query(lb_criteria, cls.count_and_label(lb_criteria), cls.rank_filtered_rank_label_by_desc(lb_criteria)).group_by(lb_criteria).subquery()
sq_criteria = None sq_criteria = None
if lb_criteria == Badge.user_id: if lb_criteria == Badge.user_id:
@ -71,7 +75,7 @@ class Leaderboard:
return (leaderboard, position[0], position[1]) return (leaderboard, position[0], position[1])
@classmethod @classmethod
def get_blockers_lb(cls, lb_criteria, v:User, db, users:Any, limit): def get_blockers_lb(cls, lb_criteria, v:User, db:scoped_session, users:Any, limit):
if lb_criteria != UserBlock.target_id: if lb_criteria != UserBlock.target_id:
raise ValueError("This leaderboard function only supports UserBlock.target_id") raise ValueError("This leaderboard function only supports UserBlock.target_id")
sq = db.query(lb_criteria, cls.count_and_label(lb_criteria)).group_by(lb_criteria).subquery() sq = db.query(lb_criteria, cls.count_and_label(lb_criteria)).group_by(lb_criteria).subquery()
@ -84,7 +88,7 @@ class Leaderboard:
return (leaderboard, position[0], position[1]) return (leaderboard, position[0], position[1])
@classmethod @classmethod
def get_hat_lb(cls, lb_criteria, v:User, db, users:Any, limit): def get_hat_lb(cls, lb_criteria, v:User, db:scoped_session, users:Any, limit):
leaderboard = db.query(User.id, func.count(lb_criteria)).join(lb_criteria).group_by(User).order_by(func.count(lb_criteria).desc()) leaderboard = db.query(User.id, func.count(lb_criteria)).join(lb_criteria).group_by(User).order_by(func.count(lb_criteria).desc())
sq = db.query(User.id, cls.count_and_label(lb_criteria), cls.rank_filtered_rank_label_by_desc(lb_criteria)).join(lb_criteria).group_by(User).subquery() sq = db.query(User.id, cls.count_and_label(lb_criteria), cls.rank_filtered_rank_label_by_desc(lb_criteria)).join(lb_criteria).group_by(User).subquery()
position = db.query(sq.c.rank, sq.c.count).filter(sq.c.id == v.id).limit(1).one_or_none() position = db.query(sq.c.rank, sq.c.count).filter(sq.c.id == v.id).limit(1).one_or_none()

View File

@ -152,6 +152,8 @@ DISCORD_CHANGELOG_CHANNEL_IDS = [1022232469606498324]
WPD_CHANNEL_ID = 1013990963846332456 WPD_CHANNEL_ID = 1013990963846332456
PIN_AWARD_TEXT = " (pin award)" PIN_AWARD_TEXT = " (pin award)"
LEADERBOARD_LIMIT = 25
################################################################################ ################################################################################
### SITE SPECIFIC CONSTANTS ### SITE SPECIFIC CONSTANTS
################################################################################ ################################################################################

View File

@ -345,24 +345,23 @@ def transfer_bux(v, username):
@app.get("/leaderboard") @app.get("/leaderboard")
@auth_required @auth_required
def leaderboard(v): def leaderboard(v):
LEADERBOARD_LIMIT = 25
users = g.db.query(User) users = g.db.query(User)
coins = Leaderboard("Coins", "coins", "coins", "Coins", None, Leaderboard.get_simple_lb, User.coins, v, v.coins, g.db, users, LEADERBOARD_LIMIT) coins = Leaderboard("Coins", "coins", "coins", "Coins", None, Leaderboard.get_simple_lb, User.coins, v, v.coins, g.db, users)
subscribers = Leaderboard("Followers", "followers", "followers", "Followers", None, Leaderboard.get_simple_lb, User.stored_subscriber_count, v, v.stored_subscriber_count, g.db, users, LEADERBOARD_LIMIT) subscribers = Leaderboard("Followers", "followers", "followers", "Followers", None, Leaderboard.get_simple_lb, User.stored_subscriber_count, v, v.stored_subscriber_count, g.db, users)
posts = Leaderboard("Posts", "post count", "posts", "Posts", None, Leaderboard.get_simple_lb, User.post_count, v, v.post_count, users, LEADERBOARD_LIMIT) posts = Leaderboard("Posts", "post count", "posts", "Posts", None, Leaderboard.get_simple_lb, User.post_count, v, v.post_count, g.db, users)
comments = Leaderboard("Comments", "comment count", "comments", "Comments", None, Leaderboard.get_simple_lb, User.post_count, v, v.post_count, users, LEADERBOARD_LIMIT) comments = Leaderboard("Comments", "comment count", "comments", "Comments", None, Leaderboard.get_simple_lb, User.comment_count, v, v.comment_count, g.db, users)
received_awards = Leaderboard("Awards", "received awards", "awards", "Awards", None, Leaderboard.get_simple_lb, User.received_award_count, v, v.received_award_count, db, users, LEADERBOARD_LIMIT) received_awards = Leaderboard("Awards", "received awards", "awards", "Awards", None, Leaderboard.get_simple_lb, User.received_award_count, v, v.received_award_count, g.db, users)
coins_spent = Leaderboard("Spent in shop", "coins spent in shop", "spent", "Coins", None, Leaderboard.get_simple_lb, User.coins_spent, v, v.coins_spent, db, users, LEADERBOARD_LIMIT) coins_spent = Leaderboard("Spent in shop", "coins spent in shop", "spent", "Coins", None, Leaderboard.get_simple_lb, User.coins_spent, v, v.coins_spent, g.db, users)
truecoins = Leaderboard("Truescore", "truescore", "truescore", "Truescore", None, Leaderboard.get_simple_lb, User.truecoins, v, v.truecoins, db, users, LEADERBOARD_LIMIT) truecoins = Leaderboard("Truescore", "truescore", "truescore", "Truescore", None, Leaderboard.get_simple_lb, User.truecoins, v, v.truecoins, g.db, users)
badges = Leaderboard("Badges", "badges", "badges", "Badges", None, Leaderboard.get_badge_marsey_lb, Badge.user_id, v, None, db, None, LEADERBOARD_LIMIT) badges = Leaderboard("Badges", "badges", "badges", "Badges", None, Leaderboard.get_badge_marsey_lb, Badge.user_id, v, None, g.db, None)
marseys = Leaderboard("Marseys", "Marseys made", "marseys", "Marseys", None, Leaderboard.get_badge_marsey_lb, Marsey.author_id, v, None, db, None, LEADERBOARD_LIMIT) if SITE_NAME == 'rDrama' else None marseys = Leaderboard("Marseys", "Marseys made", "marseys", "Marseys", None, Leaderboard.get_badge_marsey_lb, Marsey.author_id, v, None, g.db, None) if SITE_NAME == 'rDrama' else None
blocks = Leaderboard("Blocked", "most blocked", "blocked", "Blocked By", "blockers", Leaderboard.get_blockers_lb, UserBlock.target_id, v, None, db, None, LEADERBOARD_LIMIT) blocks = Leaderboard("Blocked", "most blocked", "blocked", "Blocked By", "blockers", Leaderboard.get_blockers_lb, UserBlock.target_id, v, None, g.db, None)
owned_hats = Leaderboard("Owned hats", "owned hats", "owned-hats", "Owned Hats", None, Leaderboard.get_hat_lb, User.owned_hats, v, None, db, None, LEADERBOARD_LIMIT) owned_hats = Leaderboard("Owned hats", "owned hats", "owned-hats", "Owned Hats", None, Leaderboard.get_hat_lb, User.owned_hats, v, None, g.db, None)
designed_hats = Leaderboard("Designed hats", "designed hats", "designed-hats", "Designed Hats", None, Leaderboard.get_hat_lb, User.designed_hats, v, None, db, None, LEADERBOARD_LIMIT) designed_hats = Leaderboard("Designed hats", "designed hats", "designed-hats", "Designed Hats", None, Leaderboard.get_hat_lb, User.designed_hats, v, None, g.db, None)
leaderboards = [coins, coins_spent, truecoins, subscribers, posts, comments, received_awards, badges, marseys, blocks, owned_hats, designed_hats] leaderboards = [coins, coins_spent, truecoins, subscribers, posts, comments, received_awards, badges, marseys, blocks, owned_hats, designed_hats]