fix: update regenerate route to use image_paths for mosaic cover

Made-with: Cursor
This commit is contained in:
cottongin
2026-04-06 19:33:09 -04:00
parent bdab628953
commit da5792ceae
2 changed files with 155 additions and 5 deletions

View File

@@ -3,7 +3,7 @@ import json
from flask import Blueprint, render_template, send_file, redirect, url_for, flash from flask import Blueprint, render_template, send_file, redirect, url_for, flash
from app import db from app import db
from src.models import Issue, Article from src.models import Issue, Article, Image
from src.cover import generate_cover from src.cover import generate_cover
from src.epub_builder import build_epub from src.epub_builder import build_epub
import config import config
@@ -112,14 +112,22 @@ def regenerate(issue_id):
a.title for a in articles_for_issue a.title for a in articles_for_issue
if "Obituaries" not in json.loads(a.categories) if "Obituaries" not in json.loads(a.categories)
] ]
categories_list = []
image_paths = []
for a in articles_for_issue: for a in articles_for_issue:
categories_list.extend(json.loads(a.categories)) first_image = Image.query.filter_by(article_id=a.id).first()
if first_image:
image_paths.append(first_image.local_path)
cover_method = issue.cover_method
if cover_method == "ai":
issue.cover_method = "mosaic"
cover_method = "mosaic"
try: try:
cover_path = generate_cover( cover_path = generate_cover(
issue.cover_method, config.ISSUES_DIR, cover_method, config.ISSUES_DIR,
issue.week_start, issue.week_end, headlines, categories_list issue.week_start, issue.week_end, headlines, image_paths
) )
epub_path = build_epub( epub_path = build_epub(
issue.week_start, issue.week_end, article_ids, issue.week_start, issue.week_end, article_ids,

142
tests/test_issues.py Normal file
View File

@@ -0,0 +1,142 @@
import json
import os
from datetime import date, datetime
from unittest.mock import MagicMock, patch
from PIL import Image as PILImage
from app import db
from src.models import Article, Image, Issue
def test_regenerate_passes_ordered_image_paths_to_generate_cover(app, client, db, tmp_path):
"""First image per article, in pub_date order, passed to generate_cover."""
os.makedirs(tmp_path, exist_ok=True)
img1 = str(tmp_path / "a1.jpg")
img2 = str(tmp_path / "a2.jpg")
for p in (img1, img2):
PILImage.new("RGB", (100, 100), color="blue").save(p, format="JPEG")
with app.app_context():
a1 = Article(
guid="g1",
title="Earlier Article",
author="A",
pub_date=datetime(2026, 4, 6, 10, 0),
categories=json.dumps(["Government"]),
link="http://example.com/1",
content_html="<p>x</p>",
)
a2 = Article(
guid="g2",
title="Later Article",
author="B",
pub_date=datetime(2026, 4, 7, 10, 0),
categories=json.dumps(["Culture"]),
link="http://example.com/2",
content_html="<p>y</p>",
)
db.session.add_all([a1, a2])
db.session.flush()
db.session.add_all(
[
Image(
article_id=a1.id,
original_url="https://example.com/1.jpg",
local_path=img1,
width=100,
height=100,
),
Image(
article_id=a2.id,
original_url="https://example.com/2.jpg",
local_path=img2,
width=100,
height=100,
),
]
)
id1, id2 = a1.id, a2.id
issue = Issue(
week_start=date(2026, 4, 6),
week_end=date(2026, 4, 12),
cover_method="mosaic",
cover_path=str(tmp_path / "old-cover.jpg"),
epub_path=str(tmp_path / "old.epub"),
article_ids=json.dumps([id2, id1]),
status="published",
)
db.session.add(issue)
db.session.commit()
issue_id = issue.id
mock_cover = MagicMock(return_value=str(tmp_path / "new-cover.jpg"))
mock_epub = MagicMock(return_value=str(tmp_path / "new.epub"))
with patch("src.routes.issues.generate_cover", mock_cover), patch(
"src.routes.issues.build_epub", mock_epub
):
resp = client.post(f"/issues/{issue_id}/regenerate")
assert resp.status_code in (302, 303)
mock_cover.assert_called_once()
args = mock_cover.call_args[0]
assert args[0] == "mosaic"
assert args[4] == ["Earlier Article", "Later Article"]
assert args[5] == [img1, img2]
def test_regenerate_maps_ai_cover_method_to_mosaic(app, client, db, tmp_path):
"""Legacy ai issues use mosaic generation and persist cover_method=mosaic."""
os.makedirs(tmp_path, exist_ok=True)
img1 = str(tmp_path / "a1.jpg")
PILImage.new("RGB", (100, 100), color="blue").save(img1, format="JPEG")
with app.app_context():
a1 = Article(
guid="g-ai",
title="Some Article",
author="A",
pub_date=datetime(2026, 4, 6, 10, 0),
categories=json.dumps(["Government"]),
link="http://example.com/1",
content_html="<p>x</p>",
)
db.session.add(a1)
db.session.flush()
db.session.add(
Image(
article_id=a1.id,
original_url="https://example.com/1.jpg",
local_path=img1,
width=100,
height=100,
)
)
issue = Issue(
week_start=date(2026, 4, 6),
week_end=date(2026, 4, 12),
cover_method="ai",
cover_path=str(tmp_path / "old-cover.jpg"),
epub_path=str(tmp_path / "old.epub"),
article_ids=json.dumps([a1.id]),
status="published",
)
db.session.add(issue)
db.session.commit()
issue_id = issue.id
mock_cover = MagicMock(return_value=str(tmp_path / "new-cover.jpg"))
mock_epub = MagicMock(return_value=str(tmp_path / "new.epub"))
with patch("src.routes.issues.generate_cover", mock_cover), patch(
"src.routes.issues.build_epub", mock_epub
):
client.post(f"/issues/{issue_id}/regenerate")
mock_cover.assert_called_once()
assert mock_cover.call_args[0][0] == "mosaic"
with app.app_context():
updated = db.session.get(Issue, issue_id)
assert updated.cover_method == "mosaic"