import time import uuid from random import randint from sqlalchemy.orm import aliased, deferred from sqlalchemy.sql import case, literal from sqlalchemy.sql.expression import or_ from flask import g, session from files.classes import Alt, Comment, User, Post from files.helpers.config.const import * from files.helpers.security import generate_hash, validate_hash from files.__main__ import cache def check_session_id(): if not session.get("session_id"): session.permanent = True session["session_id"] = str(uuid.uuid4()) def get_raw_formkey(u): check_session_id() return f"{session['session_id']}+{u.id}+{u.login_nonce}" def get_formkey(u): if not u: return "" # if no user exists, give them a blank formkey return generate_hash(get_raw_formkey(u)) def validate_formkey(u, formkey): if not formkey: return False return validate_hash(get_raw_formkey(u), formkey) @cache.memoize() def get_alt_graph_ids(uid): 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)) def get_alt_graph(uid): 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, user2): if user1 in {1375580,14713} or user2 in {1375580,14713}: session.pop("history", None) if session.get("GLOBAL"): return if AEVANN_ID in (user1, user2): return li = [user1, user2] g.db.flush() existing = g.db.query(Alt).filter(Alt.user1.in_(li), Alt.user2.in_(li)).one_or_none() if not existing: 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, include_current_session=False): if session.get("GLOBAL"): return past_accs = set(session.get("history", [])) if include_current_session else set() if current.email and current.email_verified: more_ids = [x[0] for x in g.db.query(User.id).filter( User.email == current.email, User.email_verified == True, User.id != current.id, ).all()] past_accs.update(more_ids) for past_id in list(past_accs): if past_id == current.id: continue li = [past_id, current.id] add_alt(past_id, current.id) other_alts = g.db.query(Alt).filter(Alt.user1.in_(li), Alt.user2.in_(li)).all() for a in other_alts: if a.user1 != past_id: add_alt(a.user1, past_id) if a.user1 != current.id: add_alt(a.user1, current.id) if a.user2 != past_id: add_alt(a.user2, past_id) if a.user2 != current.id: add_alt(a.user2, current.id) past_accs.add(current.id) if include_current_session: session["history"] = list(past_accs) g.db.flush() for u in get_alt_graph(current.id): if u.shadowbanned and not current.shadowbanned: current.shadowbanned = u.shadowbanned current.shadowban_reason = u.shadowban_reason g.db.add(current) elif current.shadowbanned and not u.shadowbanned: u.shadowbanned = current.shadowbanned u.shadowban_reason = current.shadowban_reason g.db.add(u) elif u.is_permabanned and not current.is_permabanned: current.is_banned = u.is_banned current.ban_reason = u.ban_reason current.unban_utc = None g.db.add(current) elif current.is_permabanned and not u.is_permabanned: u.is_banned = current.is_banned u.ban_reason = current.ban_reason u.unban_utc = None g.db.add(u) if u.is_muted and not current.is_muted: current.is_muted = u.is_muted g.db.add(current) elif current.is_muted and not u.is_muted: u.is_muted = current.is_muted g.db.add(u) if u.blacklisted_by and not current.blacklisted_by: current.blacklisted_by = u.blacklisted_by g.db.add(current) elif current.blacklisted_by and not u.blacklisted_by: u.blacklisted_by = current.blacklisted_by g.db.add(u) def execute_shadowban_viewers_and_voters(v, target): if not v or not v.shadowbanned: return if not target: return if v.id != target.author_id: return if not (86400 > time.time() - target.created_utc > 20): return ti = max(int((time.time() - target.created_utc)/60), 3) max_upvotes = min(ti, 13) rand = randint(0, max_upvotes) if target.upvotes >= rand: return amount = randint(0, 3) target.upvotes += amount if isinstance(target, Post): target.views += amount*randint(3, 5) g.db.add(target)