# retoor <retoor@molodetz.nl>
from typing import Optional
from devplacepy.database import (
get_table,
get_users_by_uids,
get_user_votes,
get_vote_counts,
get_user_stars,
)
from devplacepy.services.devrant.avatar import avatar_payload
from devplacepy.services.devrant.feed import build_rant_list
from devplacepy.services.devrant.ids import to_unix
from devplacepy.services.devrant.serializers import serialize_comment
PROFILE_RANT_LIMIT = 50
PROFILE_COMMENT_LIMIT = 50
SKILLS_MAX_WORDS = 8
def skills_from_bio(bio: Optional[str]) -> str:
if not bio:
return ""
words = bio.replace("\n", " ").split()
return " ".join(words[:SKILLS_MAX_WORDS])
def _user_rants(user: dict, viewer: Optional[dict]) -> list:
posts = list(
get_table("posts").find(
user_uid=user["uid"],
deleted_at=None,
order_by=["-created_at"],
_limit=PROFILE_RANT_LIMIT,
)
)
return build_rant_list(posts, viewer)
def _user_comments(user: dict, viewer: Optional[dict]) -> list:
comments = list(
get_table("comments").find(
user_uid=user["uid"],
target_type="post",
deleted_at=None,
order_by=["-created_at"],
_limit=PROFILE_COMMENT_LIMIT,
)
)
if not comments:
return []
target_uids = list({comment["target_uid"] for comment in comments})
posts_table = get_table("posts")
rant_ids = {
post["uid"]: int(post["id"])
for post in posts_table.find(posts_table.table.columns.uid.in_(target_uids))
}
comment_uids = [comment["uid"] for comment in comments]
authors = get_users_by_uids([user["uid"]])
user_scores = {user["uid"]: get_user_stars(user["uid"])}
ups, downs = get_vote_counts(comment_uids)
score_map = {uid: ups.get(uid, 0) - downs.get(uid, 0) for uid in comment_uids}
my_votes = get_user_votes(viewer["uid"], comment_uids) if viewer else {}
return [
serialize_comment(
comment,
rant_ids.get(comment["target_uid"], 0),
authors=authors,
user_scores=user_scores,
my_votes=my_votes,
score_map=score_map,
)
for comment in comments
]
def build_profile(user: dict, viewer: Optional[dict]) -> dict:
bio = user.get("bio") or ""
rants = _user_rants(user, viewer)
comments = _user_comments(user, viewer)
return {
"username": user.get("username") or "",
"score": get_user_stars(user["uid"]),
"about": bio,
"location": user.get("location") or "",
"created_time": to_unix(user.get("created_at")),
"skills": skills_from_bio(bio),
"github": user.get("git_link") or "",
"website": user.get("website") or "",
"avatar": avatar_payload(user.get("username")),
"content": {
"content": {
"rants": rants,
"upvoted": [],
"comments": comments,
"favorites": [],
"viewed": [],
},
"counts": {
"rants": len(rants),
"upvoted": 0,
"comments": len(comments),
"favorites": 0,
"collabs": 0,
},
},
}