HumeraR's picture
Refactor code structure for improved readability and maintainability; removed redundant code blocks and optimized function calls.
0649f1b
Raw History Blame Contribute Delete
5.31 kB
"""What a shared report shows to someone with the link.
The public view is built from a whitelist, field by field, never by filtering the stored content: a field added to a
block later stays private until it is added here on purpose. It carries no post text, no quoted lines, no ids, no
paths, no instructions, no suggestions, and no name of the author or workspace."""
import re
import secrets
from app.config import settings
from app.models import Artifact, ArtifactShare
from app.pipeline.infographic import infographic_html
from app.services.artifacts import report_blocks
MARKER = re.compile(r"\s*\[\d+\](?:\[\d+\])*") # [n] points into citations the public view does not carry
MAX_TEXT = 20_000
def new_token() -> str:
return secrets.token_urlsafe(16)
def share_url(token: str) -> str:
return f"{settings.frontend_url.rstrip('/')}/r/{token}"
def _s(value, limit: int = MAX_TEXT) -> str:
return str(value or "")[:limit]
def _node(n: dict, depth: int = 0) -> dict:
"""A mind map node as label, note and children only (no sources, no quotes)."""
kids = [] if depth > 6 else [_node(c, depth + 1) for c in (n.get("children") or []) if isinstance(c, dict)]
return {"id": _s(n.get("id"), 40), "label": _s(n.get("label"), 120), "note": _s(n.get("note"), 500),
"sources": [], "children": kids}
def _block(b: dict) -> dict | None:
kind, base = b.get("type"), {"id": _s(b.get("id"), 20), "type": b.get("type"), "title": _s(b.get("title"), 200)}
if kind == "prose":
return {**base, "title": "", "text": MARKER.sub("", _s(b.get("text")))}
if kind == "callout":
return {**base, "text": MARKER.sub("", _s(b.get("text"), 2000))}
if kind == "key_terms":
return {**base, "terms": [{"term": _s(t.get("term"), 200), "definition": _s(t.get("definition"), 800)}
for t in b.get("terms") or [] if isinstance(t, dict)][:60]}
if kind == "table":
return {**base, "headers": [_s(h, 120) for h in b.get("headers") or []][:12],
"rows": [[_s(c, 400) for c in r][:12] for r in b.get("rows") or [] if isinstance(r, list)][:60]}
if kind == "timeline":
return {**base, "events": [{"when": _s(e.get("when"), 80), "title": _s(e.get("title"), 200),
"detail": _s(e.get("detail"), 800)}
for e in b.get("events") or [] if isinstance(e, dict)][:40]}
if kind == "mind_map" and isinstance(b.get("root"), dict):
return {**base, "root": _node(b["root"])}
if kind == "infographic": # only a finished one, as the page our own template built (never the model's markup)
html, wide = b.get("html"), b.get("html_landscape")
return {**base, "html": html, "html_landscape": wide if isinstance(wide, str) else None} if isinstance(html, str) and html else None
if kind == "flashcards":
return {**base, "cards": [{"front": _s(c.get("front"), 300), "back": _s(c.get("back"), 800)}
for c in b.get("cards") or [] if isinstance(c, dict)][:60]}
if kind == "quiz":
return {**base, "questions": [{
"type": q.get("type"), "question": _s(q.get("question"), 600),
"options": [_s(o, 300) for o in q.get("options") or []][:8],
"correct": [i for i in q.get("correct") or [] if isinstance(i, int)][:8],
"answer": _s(q.get("answer"), 600), "accepted": [_s(a, 200) for a in q.get("accepted") or []][:8],
"explanation": _s(q.get("explanation"), 800)}
for q in b.get("questions") or [] if isinstance(q, dict)][:30]}
return None
def public_report(artifact: Artifact, share: ArtifactShare) -> dict:
"""The shared page's data for a report."""
c = artifact.content_json or {}
blocks = [x for b in report_blocks(artifact) if isinstance(b, dict) and (x := _block(b))]
out = {"kind": "report", "title": _s(c.get("title"), 300), "format": "interactive" if c.get("format") == "interactive" else "document",
"language": _s(c.get("language"), 40),
"created_at": artifact.created_at.isoformat() if artifact.created_at else None, "blocks": blocks,
"show_sources": bool(share.show_sources)}
if share.show_sources:
source = c.get("source") or {}
# Only a post's own public web address is shown; an upload or anything else is named by its title alone.
out["sources"] = {"chats": len(source.get("chat_ids") or []), "posts": [
{"title": _s(s.get("title"), 300),
"url": s["url"] if isinstance(s.get("url"), str) and re.match(r"https?://", s["url"]) else None}
for s in c.get("sources") or [] if isinstance(s, dict)][:60]}
return out
def public_infographic(artifact: Artifact) -> dict:
"""The shared page's data for an infographic: its title and the page our own template builds from the stored text
(every word escaped there). No source, no prompt, no ids."""
c = artifact.content_json or {}
return {"kind": "infographic", "title": _s(c.get("title"), 300), "html": infographic_html(c) or "",
"html_landscape": infographic_html(c, "landscape") or "",
"created_at": artifact.created_at.isoformat() if artifact.created_at else None}