Commit Graph

4 Commits

Author SHA1 Message Date
thejayman77 50dc2167cd Durable image quality: stop trusting feed thumbnails; cycle enriches Latest
Make "no blurry images" sustainable, not a one-off cleanup. RSS feed thumbnails
(~44% were ~90px) were stored at ingest and upscaled to mush, so new articles
would reintroduce them. Now image_url is filled ONLY by the quality-gated
og:image enrichment:

* insert_article no longer stores the feed image (was canonicalize_url(item...)).
* enrich_recent_images(): the cycle fetches a quality og:image for the newest
  accepted, imageless articles each run (bounded), keeping Latest photo-rich.
* Brief + on-open enrichment unchanged.

Net: every stored image is a validated, ≥450px og:image; the rest are clean
placeholders.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 15:55:57 -04:00
thejayman77 b134c2dab6 Image quality gate: reject too-small images (no more blurry thumbnails)
Some cards showed blurry photos — feed RSS thumbnails (~90×90, e.g. Phys.org's
/tmb/ path) that load fine but upscale to mush in the banner. Add a header-based
dimension parser (PNG/GIF/JPEG/WebP, stdlib only) and fold a minimum-size gate
(450×250) into the image validation, alongside the existing load check. Images
we can't measure (SVG/AVIF) still pass on content-type. A re-prune clears the
small ones already stored so those cards fall back to the clean placeholder.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 15:40:04 -04:00
thejayman77 d472b63cbf Validate images actually load (fix overcounted coverage)
A stored og:image isn't proof it renders: signed/hotlink-protected URLs (e.g.
the Guardian's i.guim.co.uk) 401 on a direct browser load, so they counted
toward coverage yet always fell back. Now fetch_og_image confirms the image
truly returns 200 + image/* (requested no-referrer, same SSRF-safe redirect
handling) before storing it. Add prune_broken_images() to clear already-stored
URLs that no longer load, so coverage is honest and those cards show the
placeholder cleanly. The browser onerror→placeholder remains the final safety net.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 13:20:12 -04:00
thejayman77 403749e26f Images phase 1: attention-triggered og:image coverage
Tie image enrichment to attention (per review): when an article earns a summary
(i.e. a reader reached it), best-effort fetch a real og:image if it lacks one —
never blanket-fetch every ingested article. Adds:

* enrich_article_image() — single-article fetch, leaves existing images alone,
  retries an imageless article only after 7 days, stamps image_checked_at.
* generate_summary() calls it after caching (wrapped; never breaks summaries).
* enrich_summarized_images() + `goodnews enrich-images` CLI — slow background
  backfill of already-summarized, accepted, imageless articles.
* Quality gate: extend the generic-image skip list with data:/tracking-pixel/
  spacer markers (on top of the existing logo/placeholder + unbranded-BBC logic).

This is coverage only; display (editorial rhythm, tile treatment) comes next.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 12:30:11 -04:00