Andrew Ridgway bec1eaac87
Some checks failed
Test / test (push) Has been cancelled
first pass at the newspaper builder
2026-09-14 11:57:22 +10:00

61 lines
2.3 KiB
Python

"""funnies — builds the newspaper's fun section from the content itself.
Orchestrates theme derivation, find-a-word, crossword (AI-drafted clues),
cartoon/comic selection into a FunniesResult. Graceful empty/fallback when no
viable content (Q5=A / BR3.2); the emitted result stays self-contained (BR4.1).
"""
from __future__ import annotations
from .crossword import ClueDrafter, build_crossword
from .find_a_word import build_find_a_word, derive_theme_words
from .cartoon import CartoonSource, Comic, build_comic, select_cartoon
from .model import FunniesBrief, FunniesResult
class FunniesBuilder:
"""Funnies library entry point — assemble the funnies section."""
def __init__(
self,
clue_drafter: ClueDrafter | None = None,
cartoon_source: CartoonSource | None = None,
) -> None:
self._clue_drafter = clue_drafter
self._cartoon_source = cartoon_source
def build(self, brief: FunniesBrief) -> FunniesResult:
if not brief.theme_words and not brief.context.strip():
# BR3.2 / Q5=A: nothing viable — graceful empty, never a broken block
return FunniesResult(
funnies_result_id="funnies-1",
status="empty",
status_message="No theme words or context provided; funnies skipped.",
)
words = brief.theme_words or derive_theme_words(brief.context)
if not words:
return FunniesResult(
funnies_result_id="funnies-1",
status="empty",
status_message="Could not derive any theme words from content.",
)
find_word = build_find_a_word(words)
crossword = build_crossword(words, brief.context, self._clue_drafter)
cartoon = select_cartoon(brief.context, self._cartoon_source)
result = FunniesResult(
funnies_result_id="funnies-1",
crossword=crossword,
find_a_word=find_word,
cartoons=[cartoon],
comics=[],
status="ready",
)
# If the cartoon had to fall back, mark fallback (Q5=A)
if cartoon.source == "generated":
result.status = "fallback"
result.status_message = "No xkcd found; used a content-derived strip."
return result