File size: 2,269 Bytes
55d0eca
 
 
 
 
 
 
 
89250ee
55d0eca
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
"""Thumbs up or down on generated reports, quizzes, flashcards and infographics: what can be rated, why a thumbs down can be
given, and how the ratings ride along on the artifacts the app lists."""

import uuid

from sqlalchemy import select
from sqlalchemy.orm import Session

from app.models import Artifact, ArtifactFeedback

# What each kind can be marked down for (the ids the app sends; anything else is dropped).
REASONS: dict[str, set[str]] = {
    "report": {"inaccurate", "missed_points", "structure", "tone", "too_long", "too_short", "other"},
    "quiz": {"wrong_answers", "too_easy", "too_hard", "unclear", "off_topic", "other"},
    "flashcards": {"inaccurate", "too_basic", "too_detailed", "unclear", "other"},
    "infographic": {"messy_layout", "cut_off", "missing_content", "look", "hard_to_read", "other"},
}
RATEABLE = tuple(REASONS)


def feedback_out(f: ArtifactFeedback | None) -> dict | None:
    if not f:
        return None
    return {"rating": "up" if f.rating > 0 else "down", "reasons": f.reasons or [], "comment": f.comment}


def attach(db: Session, user_id: uuid.UUID, items: list[dict]) -> list[dict]:
    """Add `feedback` (this person's rating, or None) to each serialized artifact that can be rated. One query."""
    ids = [uuid.UUID(i["id"]) for i in items if i.get("type") in RATEABLE]
    rows = {f.artifact_id: f for f in db.scalars(select(ArtifactFeedback).where(
        ArtifactFeedback.artifact_id.in_(ids), ArtifactFeedback.user_id == user_id))} if ids else {}
    for i in items:
        if i.get("type") in RATEABLE:
            i["feedback"] = feedback_out(rows.get(uuid.UUID(i["id"])))
    return items


def snapshot(a: Artifact) -> dict:
    """What the artifact was when it was rated: enough to tell what a rating is about."""
    c = a.content_json or {}
    inner = c.get("content") if isinstance(c.get("content"), dict) else {}
    keep = {k: c.get(k) for k in ("title", "prompt", "source", "theme", "format", "template_id", "difficulty", "question_count",
                                  "card_count", "language", "topic") if c.get(k) is not None}
    if a.type == "infographic":
        keep["layout"] = "composed" if "body_html" in inner else "fixed"
        keep["fit"] = inner.get("fit")
    return keep