Enhance newsletter generation with editorial features

- Introduce optional fields for "Top Highlights" and "Editorial Note" in the newsletter dashboard, allowing editors to highlight key articles and provide additional context.
- Update the HTML and plain text generation functions to incorporate these new fields, ensuring they are displayed correctly in the newsletter output.
- Modify the dashboard template to include input areas for these new features, improving the user interface for newsletter creation.
This commit is contained in:
smueller
2026-07-07 13:26:26 +02:00
parent b35c524ba5
commit 83e6908f9f
4 changed files with 483 additions and 254 deletions

View File

@@ -29,6 +29,7 @@ from app.services.newsletter import (
create_subject,
filter_articles,
parse_display_options,
parse_highlights,
split_articles_by_type,
)
from app.services.smtp_sender import get_smtp_settings, run_scheduled_send_if_due, send_newsletter
@@ -213,6 +214,8 @@ async def dashboard(request: Request, db: Session = Depends(get_db), current_use
"only_edited": False,
"category": "",
"display": DEFAULT_DISPLAY,
"editor_tip": "",
"highlights": "",
},
"wiki_error": None,
})
@@ -231,6 +234,8 @@ async def dashboard_generate(
show_date: str | None = Form(None),
show_user: str | None = Form(None),
show_category: str | None = Form(None),
editor_tip: str = Form(""),
highlights: str = Form(""),
db: Session = Depends(get_db),
current_user: User = Depends(require_editor_or_admin),
):
@@ -238,6 +243,7 @@ async def dashboard_generate(
days = max(1, min(days, 90))
only_edited_flag = only_edited == "true"
display = parse_display_options(show_date, show_user, show_category)
highlight_list = parse_highlights(highlights)
wiki_error = None
filtered: list = []
articles_new: list = []
@@ -250,9 +256,9 @@ async def dashboard_generate(
filtered = filter_articles(articles, category_filter=category or None)
articles_new, articles_edited = split_articles_by_type(filtered)
title = create_subject(days, category)
plain_text = create_plain_text(filtered, days, display, category)
raw_html = create_html(filtered, days, display, category)
outlook_html = create_outlook_html(filtered, days, display, category)
plain_text = create_plain_text(filtered, days, display, category, editor_tip, highlight_list)
raw_html = create_html(filtered, days, display, category, editor_tip, highlight_list)
outlook_html = create_outlook_html(filtered, days, display, category, editor_tip, highlight_list)
run_scheduled_send_if_due(db, title, raw_html, plain_text)
except WikiFetchError as exc:
wiki_error = exc.message
@@ -270,6 +276,8 @@ async def dashboard_generate(
"only_edited": only_edited_flag,
"category": category,
"display": display,
"editor_tip": editor_tip,
"highlights": highlights,
},
"send_logs": db.query(SendLog).order_by(SendLog.created_at.desc()).limit(20).all(),
"wiki_error": wiki_error,
@@ -288,20 +296,24 @@ async def send_now(
show_date: str | None = Form(None),
show_user: str | None = Form(None),
show_category: str | None = Form(None),
editor_tip: str = Form(""),
highlights: str = Form(""),
db: Session = Depends(get_db),
current_user: User = Depends(require_editor_or_admin),
):
validate_csrf(request, csrf_token)
display = parse_display_options(show_date, show_user, show_category)
only_edited_flag = only_edited == "true"
highlight_list = parse_highlights(highlights)
days = max(1, min(days, 90))
try:
articles = await wiki_service.get_recent_changes(days=max(1, min(days, 90)), only_edited=only_edited_flag)
articles = await wiki_service.get_recent_changes(days=days, only_edited=only_edited_flag)
except WikiFetchError as exc:
raise HTTPException(status_code=502, detail=exc.message) from exc
filtered = filter_articles(articles, category_filter=category or None)
title = create_subject(max(1, min(days, 90)), category)
plain_text = create_plain_text(filtered, max(1, min(days, 90)), display, category)
raw_html = create_html(filtered, max(1, min(days, 90)), display, category)
title = create_subject(days, category)
plain_text = create_plain_text(filtered, days, display, category, editor_tip, highlight_list)
raw_html = create_html(filtered, days, display, category, editor_tip, highlight_list)
recipients = [r.strip() for r in get_config(db, "smtp.recipients", "").split(",") if r.strip()]
send_newsletter(db, title, raw_html, plain_text, recipients, scheduled=False)
return RedirectResponse(url="/dashboard", status_code=status.HTTP_302_FOUND)