# retoor from .core import TTLCache, _in_clause, _now_iso, db, get_table from .users import get_users_by_uids from .soft_delete import soft_delete, soft_delete_in VOTABLE_TARGETS: dict[str, str] = { "post": "posts", "project": "projects", "gist": "gists", "comment": "comments", } STAR_TARGETS: set[str] = {"post", "project", "gist"} _authors_cache = TTLCache(ttl=300, max_size=200) def _ranked_authors() -> list: cached = _authors_cache.get("ranked") if cached is not None: return cached sources = [ (target_type, table_name) for target_type, table_name in VOTABLE_TARGETS.items() if table_name in db.tables ] if "votes" not in db.tables or not sources: _authors_cache.set("ranked", []) return [] target_union = " UNION ALL ".join( f"SELECT uid, user_uid, '{target_type}' AS target_type FROM {table_name} WHERE deleted_at IS NULL" for target_type, table_name in sources ) rows = db.query( f"SELECT t.user_uid, SUM(v.value) AS total " f"FROM votes v JOIN ({target_union}) t ON v.target_uid = t.uid AND v.target_type = t.target_type " f"WHERE v.deleted_at IS NULL " f"GROUP BY t.user_uid HAVING SUM(v.value) > 0 ORDER BY total DESC" ) ranked = [(row["user_uid"], row["total"]) for row in rows] users_map = get_users_by_uids([uid for uid, _ in ranked]) authors = [] for uid, total in ranked: user = users_map.get(uid) if user: author = dict(user) author["stars"] = total authors.append(author) _authors_cache.set("ranked", authors) _authors_cache.set( "rank_map", {author["uid"]: position for position, author in enumerate(authors, start=1)}, ) return authors def _rank_map() -> dict: cached = _authors_cache.get("rank_map") if cached is not None: return cached _ranked_authors() return _authors_cache.get("rank_map") or {} def get_top_authors(limit: int = 5) -> list: return _ranked_authors()[:limit] def get_leaderboard(limit: int = 50, offset: int = 0) -> list: sliced = _ranked_authors()[offset : offset + limit] leaderboard = [] for position, author in enumerate(sliced, start=offset + 1): entry = dict(author) entry["rank"] = position leaderboard.append(entry) return leaderboard def get_user_rank(user_uid: str): return _rank_map().get(user_uid) def get_user_stars(user_uid: str) -> int: if "votes" not in db.tables: return 0 target_union = " UNION ALL ".join( f"SELECT uid, '{target_type}' AS target_type FROM {table_name} WHERE user_uid = :u AND deleted_at IS NULL" for target_type, table_name in VOTABLE_TARGETS.items() if table_name in db.tables ) if not target_union: return 0 for row in db.query( f"SELECT COALESCE(SUM(v.value), 0) AS s " f"FROM votes v JOIN ({target_union}) t ON v.target_uid = t.uid AND v.target_type = t.target_type " f"WHERE v.deleted_at IS NULL", u=user_uid, ): return row["s"] or 0 return 0 def update_target_stars(target_type: str, target_uid: str, net_stars: int) -> None: table_name = VOTABLE_TARGETS.get(target_type) if not table_name: return if target_type in STAR_TARGETS: get_table(table_name).update({"uid": target_uid, "stars": net_stars}, ["uid"]) _authors_cache.clear() def soft_delete_engagement(target_type: str, target_uids: list, deleted_by: str) -> None: uids = [uid for uid in (target_uids or []) if uid] if not uids: return stamp = _now_iso() soft_delete_in( "reactions", "target_uid", uids, deleted_by, stamp=stamp, target_type=target_type ) soft_delete_in( "bookmarks", "target_uid", uids, deleted_by, stamp=stamp, target_type=target_type ) if target_type == "post" and "polls" in db.tables: for uid in uids: for poll in db["polls"].find(post_uid=uid, deleted_at=None): soft_delete("poll_votes", deleted_by, stamp=stamp, poll_uid=poll["uid"]) soft_delete("poll_options", deleted_by, stamp=stamp, poll_uid=poll["uid"]) soft_delete("polls", deleted_by, stamp=stamp, post_uid=uid) def delete_engagement(target_type: str, target_uids: list) -> None: uids = [uid for uid in (target_uids or []) if uid] if not uids: return if "reactions" in db.tables: placeholders, params = _in_clause(uids) params["tt"] = target_type db.query( f"DELETE FROM reactions WHERE target_type=:tt AND target_uid IN ({placeholders})", **params, ) if "bookmarks" in db.tables: placeholders, params = _in_clause(uids) params["tt"] = target_type db.query( f"DELETE FROM bookmarks WHERE target_type=:tt AND target_uid IN ({placeholders})", **params, ) if target_type == "post" and "polls" in db.tables: for uid in uids: for poll in db["polls"].find(post_uid=uid): if "poll_votes" in db.tables: db["poll_votes"].delete(poll_uid=poll["uid"]) if "poll_options" in db.tables: db["poll_options"].delete(poll_uid=poll["uid"]) db["polls"].delete(post_uid=uid) def get_target_owner_uid(target_type: str, target_uid: str) -> str | None: table_name = VOTABLE_TARGETS.get(target_type) if not table_name: return None row = get_table(table_name).find_one(uid=target_uid, deleted_at=None) return row["user_uid"] if row else None