# retoor <retoor@molodetz.nl>
import logging
from datetime import datetime, timezone
from devplacepy.database import (
db,
get_follow_counts,
get_table,
get_user_post_count,
get_user_rank,
)
logger = logging.getLogger(__name__)
MAX_BIO = 280
MAX_EXCERPT = 400
MAX_SOURCE = 1500
MAX_THREAD_MESSAGES = 6
MAX_MESSAGE = 240
TARGET_TABLES = {
"post": "posts",
"project": "projects",
"gist": "gists",
"news": "news",
}
def _truncate(text: str, limit: int) -> str:
text = " ".join((text or "").split())
if len(text) <= limit:
return text
return text[:limit].rstrip() + "..."
def _today() -> str:
return datetime.now(timezone.utc).strftime("%d/%m/%Y")
def _author_block(user_uid: str) -> str:
user = get_table("users").find_one(uid=user_uid)
if not user:
return ""
stats = [
f"role {user.get('role') or 'Member'}",
f"level {user.get('level', 1)}",
f"{user.get('stars', 0)} stars",
]
try:
stats.append(f"{get_user_post_count(user_uid)} posts")
except Exception:
pass
try:
rank = get_user_rank(user_uid)
if rank:
stats.append(f"rank #{rank}")
except Exception:
pass
try:
follows = get_follow_counts(user_uid)
stats.append(f"{follows.get('followers', 0)} followers")
except Exception:
pass
joined = (user.get("created_at") or "")[:10]
if joined:
stats.append(f"member since {joined}")
line = f"Author: {user.get('username', '')} ({', '.join(stats)})."
bio = _truncate(user.get("bio") or "", MAX_BIO)
if bio:
line += f' Bio: "{bio}".'
return line
def _target_excerpt(target_type: str, target_uid: str) -> str:
table = TARGET_TABLES.get(target_type)
if not table or table not in db.tables or not target_uid:
return ""
row = get_table(table).find_one(uid=target_uid)
if not row:
return ""
title = (row.get("title") or "").strip()
body = _truncate(row.get("content") or row.get("description") or "", MAX_EXCERPT)
label = f'the {target_type} "{title}"' if title else f"a {target_type}"
text = f"This is a comment on {label}."
if body:
text += f' Excerpt: "{body}".'
return text
def _comment_block(row: dict) -> str:
target_type = row.get("target_type") or "post"
target_uid = row.get("target_uid") or row.get("post_uid") or ""
text = _target_excerpt(target_type, target_uid)
parent_uid = row.get("parent_uid")
if parent_uid and "comments" in db.tables:
parent = get_table("comments").find_one(uid=parent_uid)
if parent:
text += f' In reply to: "{_truncate(parent.get("content") or "", MAX_EXCERPT)}".'
return text
def _post_block(row: dict) -> str:
topic = row.get("topic") or "general"
text = f"This is a post (topic: {topic})."
project_uid = row.get("project_uid")
if project_uid and "projects" in db.tables:
project = get_table("projects").find_one(uid=project_uid)
if project and project.get("title"):
text += f' Attached to the project "{project["title"]}".'
return text
def _item_block(table: str, row: dict) -> str:
kind = "project" if table == "projects" else "gist"
title = (row.get("title") or "").strip()
text = f'This is a {kind}' + (f' titled "{title}".' if title else ".")
description = _truncate(row.get("description") or "", MAX_EXCERPT)
if description:
text += f' Description: "{description}".'
if table == "gists":
language = row.get("language") or "plaintext"
source = _truncate(row.get("source_code") or "", MAX_SOURCE)
text += f" Language: {language}."
if source:
text += f" Source code (reference only, do not include unless asked): {source}"
return text
def _message_block(row: dict) -> str:
sender_uid = row.get("sender_uid")
receiver_uid = row.get("receiver_uid")
receiver = get_table("users").find_one(uid=receiver_uid) if receiver_uid else None
receiver_name = (receiver or {}).get("username") or "the recipient"
text = f"This is a direct message to {receiver_name}."
if "messages" not in db.tables or not sender_uid or not receiver_uid:
return text
rows = list(
db.query(
"SELECT sender_uid, content FROM messages "
"WHERE ((sender_uid = :a AND receiver_uid = :b) "
"OR (sender_uid = :b AND receiver_uid = :a)) "
"AND uid != :current AND deleted_at IS NULL "
"ORDER BY id DESC LIMIT :lim",
a=sender_uid,
b=receiver_uid,
current=row.get("uid") or "",
lim=MAX_THREAD_MESSAGES,
)
)
if not rows:
return text
lines = []
for entry in reversed(rows):
who = "you" if entry["sender_uid"] == sender_uid else receiver_name
lines.append(f"{who}: {_truncate(entry['content'] or '', MAX_MESSAGE)}")
return text + " Recent conversation:\n" + "\n".join(lines)
def _location_block(table: str, row: dict) -> str:
if table == "comments":
return _comment_block(row)
if table == "posts":
return _post_block(row)
if table in ("projects", "gists"):
return _item_block(table, row)
if table == "messages":
return _message_block(row)
return ""
def build_context(table: str, uid: str, row: dict, user_uid: str) -> str:
parts = [f"Today is {_today()} on the DevPlace developer network."]
try:
author = _author_block(user_uid)
if author:
parts.append(author)
except Exception as exc:
logger.warning("ai context author block failed: %s", exc)
try:
location = _location_block(table, row)
if location:
parts.append(location)
except Exception as exc:
logger.warning("ai context location block failed: %s", exc)
return "\n".join(parts)