From 680135755e92514296cb937defd08ca863073a41 Mon Sep 17 00:00:00 2001 From: Aevann Date: Wed, 25 Jan 2023 04:51:48 +0200 Subject: [PATCH] Revert "get rid of get_alt_graph" This reverts commit e2e3da4bda4e6f6a946697e796c63ab588c9794e. --- files/classes/user.py | 9 ++++----- files/routes/admin.py | 12 ++++++++---- files/routes/jinja2.py | 4 ++-- files/routes/routehelpers.py | 24 +++++++++++++++++++++++- files/routes/votes.py | 3 ++- files/templates/admin/alt_votes.html | 2 +- files/templates/userpage/banner.html | 2 +- 7 files changed, 41 insertions(+), 15 deletions(-) diff --git a/files/classes/user.py b/files/classes/user.py index 535e7fa19..bc881f11b 100644 --- a/files/classes/user.py +++ b/files/classes/user.py @@ -715,6 +715,10 @@ class User(Base): def do_reddit(self): return self.notifications_count == self.reddit_notifications_count + @property + @lazy + def alt_ids(self): + return [x.id for x in self.get_alt_graph(g.db)] @property @lazy @@ -1126,11 +1130,6 @@ class User(Base): return output - @property - @lazy - def alt_ids(self): - return [x.id for x in self.alts] - if IS_FISTMAS(): @property @lazy diff --git a/files/routes/admin.py b/files/routes/admin.py index 67b381d8f..aa641ff57 100644 --- a/files/routes/admin.py +++ b/files/routes/admin.py @@ -20,6 +20,7 @@ from files.helpers.settings import get_settings, toggle_setting from files.helpers.useractions import * from files.routes.routehelpers import check_for_alts from files.routes.wrappers import * +from files.routes.routehelpers import get_alt_graph, get_alt_graph_ids from .front import frontlist @@ -223,7 +224,7 @@ def revert_actions(v:User, username): send_repeatable_notification(user.id, f"@{v.username} (a site admin) has unbanned you!") g.db.add(user) - for u in user.alts: + for u in get_alt_graph(user.id): u.shadowbanned = None u.unban_utc = 0 u.ban_reason = None @@ -639,6 +640,9 @@ def admin_add_alt(v:User, username): g.db.add(a) g.db.flush() + cache.delete_memoized(get_alt_graph_ids, user1.id) + cache.delete_memoized(get_alt_graph_ids, user2.id) + check_for_alts(user1, include_current_session=False) check_for_alts(user2, include_current_session=False) @@ -805,7 +809,7 @@ def unshadowban(user_id, v): if not user.is_banned: user.ban_reason = None g.db.add(user) - for alt in user.alts: + for alt in get_alt_graph(user.id): alt.shadowbanned = None if not alt.is_banned: alt.ban_reason = None g.db.add(alt) @@ -900,7 +904,7 @@ def ban_user(id, v): user.ban(admin=v, reason=reason, days=days) if request.values.get("alts"): - for x in user.alts: + for x in get_alt_graph(user.id): if x.admin_level > v.admin_level: continue x.ban(admin=v, reason=reason, days=days) @@ -1061,7 +1065,7 @@ def unban_user(id, v): send_repeatable_notification(user.id, f"@{v.username} (a site admin) has unbanned you!") g.db.add(user) - for x in user.alts: + for x in get_alt_graph(user.id): if x.is_banned: send_repeatable_notification(x.id, f"@{v.username} (a site admin) has unbanned you!") x.is_banned = None x.unban_utc = 0 diff --git a/files/routes/jinja2.py b/files/routes/jinja2.py index 0ab654869..e2e5acc77 100644 --- a/files/routes/jinja2.py +++ b/files/routes/jinja2.py @@ -14,7 +14,7 @@ from files.helpers.config.const import * from files.helpers.regex import * from files.helpers.settings import get_settings, get_setting from files.helpers.sorting_and_time import make_age_string -from files.routes.routehelpers import get_formkey +from files.routes.routehelpers import get_alt_graph, get_formkey from files.__main__ import app, cache @app.template_filter("formkey") @@ -119,5 +119,5 @@ def inject_constants(): "HOUSE_JOIN_COST":HOUSE_JOIN_COST, "HOUSE_SWITCH_COST":HOUSE_SWITCH_COST, "IMAGE_FORMATS":','.join(IMAGE_FORMATS), "PAGE_SIZES":PAGE_SIZES, "THEMES":THEMES, "COMMENT_SORTS":COMMENT_SORTS, "SORTS":SORTS, "TIME_FILTERS":TIME_FILTERS, "HOUSES":HOUSES, "TIERS_ID_TO_NAME":TIERS_ID_TO_NAME, - "DEFAULT_CONFIG_VALUE":DEFAULT_CONFIG_VALUE, "IS_LOCALHOST":IS_LOCALHOST, "BACKGROUND_CATEGORIES":BACKGROUND_CATEGORIES, "PAGE_SIZE":PAGE_SIZE, "TAGLINES":TAGLINES, "IS_FISTMAS":IS_FISTMAS, "current_registered_users":current_registered_users, "gitref":git_head() + "DEFAULT_CONFIG_VALUE":DEFAULT_CONFIG_VALUE, "IS_LOCALHOST":IS_LOCALHOST, "BACKGROUND_CATEGORIES":BACKGROUND_CATEGORIES, "PAGE_SIZE":PAGE_SIZE, "TAGLINES":TAGLINES, "IS_FISTMAS":IS_FISTMAS, "get_alt_graph":get_alt_graph, "current_registered_users":current_registered_users, "gitref":git_head() } diff --git a/files/routes/routehelpers.py b/files/routes/routehelpers.py index 135388bce..be96c36e5 100644 --- a/files/routes/routehelpers.py +++ b/files/routes/routehelpers.py @@ -24,6 +24,26 @@ def validate_formkey(u:User, formkey:Optional[str]) -> bool: if not formkey: return False return validate_hash(get_raw_formkey(u), formkey) +@cache.memoize(timeout=604800) +def get_alt_graph_ids(uid:int) -> List[int]: + alt_graph_cte = g.db.query(literal(uid).label('user_id')).select_from(Alt).cte('alt_graph', recursive=True) + + alt_graph_cte_inner = g.db.query( + case( + (Alt.user1 == alt_graph_cte.c.user_id, Alt.user2), + (Alt.user2 == alt_graph_cte.c.user_id, Alt.user1), + ) + ).select_from(Alt, alt_graph_cte).filter( + or_(alt_graph_cte.c.user_id == Alt.user1, alt_graph_cte.c.user_id == Alt.user2) + ) + + alt_graph_cte = alt_graph_cte.union(alt_graph_cte_inner) + return set([x[0] for x in g.db.query(User.id).filter(User.id == alt_graph_cte.c.user_id, User.id != uid).all()]) + +def get_alt_graph(uid:int) -> List[User]: + alt_ids = get_alt_graph_ids(uid) + return g.db.query(User).filter(User.id.in_(alt_ids)).order_by(User.username).all() + def add_alt(user1:int, user2:int): li = [user1, user2] existing = g.db.query(Alt).filter(Alt.user1.in_(li), Alt.user2.in_(li)).one_or_none() @@ -31,6 +51,8 @@ def add_alt(user1:int, user2:int): new_alt = Alt(user1=user1, user2=user2) g.db.add(new_alt) g.db.flush() + cache.delete_memoized(get_alt_graph_ids, user1) + cache.delete_memoized(get_alt_graph_ids, user2) def check_for_alts(current:User, include_current_session=True): current_id = current.id @@ -64,7 +86,7 @@ def check_for_alts(current:User, include_current_session=True): if include_current_session: session["history"] = list(past_accs) g.db.flush() - for u in current.alts: + for u in get_alt_graph(current.id): if u.shadowbanned and not current.shadowbanned and current.id not in DONT_SHADOWBAN: current.shadowbanned = u.shadowbanned current.ban_reason = u.ban_reason diff --git a/files/routes/votes.py b/files/routes/votes.py index 676baed5e..13be19078 100644 --- a/files/routes/votes.py +++ b/files/routes/votes.py @@ -3,6 +3,7 @@ from files.helpers.config.const import * from files.helpers.get import * from files.routes.wrappers import * from files.__main__ import app, limiter +from files.routes.routehelpers import get_alt_graph from math import floor @@ -74,7 +75,7 @@ def vote_post_comment(target_id, new, v, cls, vote_cls): coin_delta = 0 alt = False - if target.author.id in v.alt_ids: + if target.author.id in [x.id for x in get_alt_graph(v.id)]: coin_delta = -1 alt = True diff --git a/files/templates/admin/alt_votes.html b/files/templates/admin/alt_votes.html index 3711a44ac..8709f4a35 100644 --- a/files/templates/admin/alt_votes.html +++ b/files/templates/admin/alt_votes.html @@ -49,7 +49,7 @@ {% if v.admin_level >= PERMS['USER_LINK'] %}

Link Accounts

- {% if u2.id in u1.alt_ids %} + {% if u2 in get_alt_graph(u1.id) %}

Accounts are known alts of each other.

{% else %} diff --git a/files/templates/userpage/banner.html b/files/templates/userpage/banner.html index 70f697d45..a6c58e8c3 100644 --- a/files/templates/userpage/banner.html +++ b/files/templates/userpage/banner.html @@ -2,7 +2,7 @@ {% set hats_total = u.hats_owned_proportion_display[1] if u else 0 %} {% set hats_owned_percent = u.hats_owned_proportion_display[0] if u else '' %} {% if v and (v.admin_level >= PERMS['VIEW_ALTS'] or v.alt) %} - {% set alts = u.alts %} + {% set alts = get_alt_graph(u.id) %} {% endif %} {% block desktopUserBanner %}