148 lines
5.5 KiB
Python
148 lines
5.5 KiB
Python
|
|
from devplacepy.database import (
|
||
|
|
db,
|
||
|
|
get_table,
|
||
|
|
get_setting,
|
||
|
|
get_site_stats,
|
||
|
|
get_top_authors,
|
||
|
|
get_featured_news,
|
||
|
|
get_gist_languages,
|
||
|
|
get_daily_topic,
|
||
|
|
get_streaks,
|
||
|
|
get_user_stars,
|
||
|
|
get_user_rank,
|
||
|
|
)
|
||
|
|
from devplacepy.utils import format_date
|
||
|
|
|
||
|
|
|
||
|
|
def _count(table: str, **criteria) -> int:
|
||
|
|
if table not in db.tables:
|
||
|
|
return 0
|
||
|
|
return get_table(table).count(**criteria)
|
||
|
|
|
||
|
|
|
||
|
|
def _recent(table: str, user_uid: str, limit: int = 5) -> list:
|
||
|
|
if table not in db.tables:
|
||
|
|
return []
|
||
|
|
return list(get_table(table).find(user_uid=user_uid, order_by=["-created_at"], _limit=limit))
|
||
|
|
|
||
|
|
|
||
|
|
def _user_facts(user: dict) -> dict:
|
||
|
|
uid = user["uid"]
|
||
|
|
|
||
|
|
posts = _recent("posts", uid)
|
||
|
|
gists = _recent("gists", uid)
|
||
|
|
projects = _recent("projects", uid)
|
||
|
|
badges = [b.get("badge_name", "") for b in get_table("badges").find(user_uid=uid)] if "badges" in db.tables else []
|
||
|
|
languages = sorted({
|
||
|
|
g.get("language") for g in (get_table("gists").find(user_uid=uid) if "gists" in db.tables else [])
|
||
|
|
if g.get("language")
|
||
|
|
})
|
||
|
|
|
||
|
|
return {
|
||
|
|
"username": user.get("username", ""),
|
||
|
|
"role": user.get("role", "Member"),
|
||
|
|
"member_since": format_date(user.get("created_at", "")) if user.get("created_at") else "",
|
||
|
|
"level": user.get("level", 1),
|
||
|
|
"xp": user.get("xp", 0),
|
||
|
|
"stars": get_user_stars(uid),
|
||
|
|
"rank": get_user_rank(uid),
|
||
|
|
"streak": get_streaks(uid),
|
||
|
|
"badges": badges,
|
||
|
|
"languages": languages,
|
||
|
|
"counts": {
|
||
|
|
"posts": _count("posts", user_uid=uid),
|
||
|
|
"gists": _count("gists", user_uid=uid),
|
||
|
|
"projects": _count("projects", user_uid=uid),
|
||
|
|
"comments": _count("comments", user_uid=uid),
|
||
|
|
"followers": _count("follows", following_uid=uid),
|
||
|
|
"following": _count("follows", follower_uid=uid),
|
||
|
|
"bookmarks": _count("bookmarks", user_uid=uid),
|
||
|
|
"unread_notifications": _count("notifications", user_uid=uid, read=False),
|
||
|
|
"unread_messages": _count("messages", receiver_uid=uid, read=False),
|
||
|
|
},
|
||
|
|
"recent_posts": [
|
||
|
|
{"title": (p.get("title") or (p.get("content") or "")[:60] or "Untitled"),
|
||
|
|
"url": f"/posts/{p.get('slug') or p['uid']}"}
|
||
|
|
for p in posts
|
||
|
|
],
|
||
|
|
"recent_gists": [
|
||
|
|
{"title": g.get("title", "Untitled"), "language": g.get("language", ""),
|
||
|
|
"url": f"/gists/{g.get('slug') or g['uid']}"}
|
||
|
|
for g in gists
|
||
|
|
],
|
||
|
|
"recent_projects": [
|
||
|
|
{"title": p.get("title", "Untitled"), "status": p.get("status", ""),
|
||
|
|
"url": f"/projects/{p.get('slug') or p['uid']}"}
|
||
|
|
for p in projects
|
||
|
|
],
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
def build_live_facts(user: dict | None) -> dict:
|
||
|
|
stats = get_site_stats()
|
||
|
|
facts = {
|
||
|
|
"site": {
|
||
|
|
"name": get_setting("site_name", "DevPlace"),
|
||
|
|
"tagline": get_setting("site_tagline", ""),
|
||
|
|
"total_members": stats.get("total_members", 0),
|
||
|
|
"posts_today": stats.get("posts_today", 0),
|
||
|
|
"total_projects": stats.get("total_projects", 0),
|
||
|
|
"total_gists": stats.get("total_gists", 0),
|
||
|
|
},
|
||
|
|
"top_authors": [
|
||
|
|
{"username": a.get("username", ""), "stars": a.get("stars", 0)}
|
||
|
|
for a in get_top_authors(10)
|
||
|
|
],
|
||
|
|
"languages": sorted(get_gist_languages()),
|
||
|
|
"news": get_featured_news(5),
|
||
|
|
"topic": get_daily_topic(),
|
||
|
|
"user": _user_facts(user) if user else None,
|
||
|
|
}
|
||
|
|
return facts
|
||
|
|
|
||
|
|
|
||
|
|
def live_text(facts: dict) -> str:
|
||
|
|
parts: list[str] = []
|
||
|
|
site = facts["site"]
|
||
|
|
parts += [
|
||
|
|
site["name"], site["tagline"],
|
||
|
|
"members", str(site["total_members"]),
|
||
|
|
"posts today", str(site["posts_today"]),
|
||
|
|
"projects", str(site["total_projects"]),
|
||
|
|
"gists", str(site["total_gists"]),
|
||
|
|
"top authors leaderboard",
|
||
|
|
]
|
||
|
|
parts += [f"{a['username']} {a['stars']} stars" for a in facts["top_authors"]]
|
||
|
|
parts += ["trending languages"] + facts["languages"]
|
||
|
|
parts += ["developer news"] + [n.get("title", "") for n in facts["news"]]
|
||
|
|
parts += [facts["topic"].get("title", "")]
|
||
|
|
|
||
|
|
user = facts.get("user")
|
||
|
|
if user:
|
||
|
|
counts = user["counts"]
|
||
|
|
parts += [
|
||
|
|
"your dashboard account stats",
|
||
|
|
user["username"], user["role"], "member since", user["member_since"],
|
||
|
|
"level", str(user["level"]), "xp", str(user["xp"]),
|
||
|
|
"stars", str(user["stars"]), "rank", str(user["rank"]),
|
||
|
|
"current streak", str(user["streak"].get("current", 0)),
|
||
|
|
"longest streak", str(user["streak"].get("longest", 0)),
|
||
|
|
"posts", str(counts["posts"]),
|
||
|
|
"gists", str(counts["gists"]),
|
||
|
|
"projects", str(counts["projects"]),
|
||
|
|
"comments", str(counts["comments"]),
|
||
|
|
"followers", str(counts["followers"]),
|
||
|
|
"following", str(counts["following"]),
|
||
|
|
"bookmarks saved", str(counts["bookmarks"]),
|
||
|
|
"unread notifications", str(counts["unread_notifications"]),
|
||
|
|
"unread messages", str(counts["unread_messages"]),
|
||
|
|
"badges",
|
||
|
|
]
|
||
|
|
parts += user["badges"]
|
||
|
|
parts += ["languages you use"] + user["languages"]
|
||
|
|
parts += ["your recent posts"] + [p["title"] for p in user["recent_posts"]]
|
||
|
|
parts += ["your gists"] + [g["title"] for g in user["recent_gists"]]
|
||
|
|
parts += ["your projects"] + [p["title"] for p in user["recent_projects"]]
|
||
|
|
|
||
|
|
return " ".join(str(part) for part in parts if part)
|