feat: complete web UI — dashboard, articles, publish, settings, issues
Made-with: Cursor
This commit is contained in:
102
src/routes/publish.py
Normal file
102
src/routes/publish.py
Normal file
@@ -0,0 +1,102 @@
|
||||
import json
|
||||
from datetime import date, timedelta
|
||||
from flask import Blueprint, render_template, request, redirect, url_for, flash
|
||||
|
||||
from app import db
|
||||
from src.models import Article, Issue
|
||||
from src.cover import generate_cover
|
||||
from src.epub_builder import build_epub
|
||||
import config
|
||||
|
||||
publish_bp = Blueprint("publish", __name__)
|
||||
|
||||
|
||||
@publish_bp.route("/publish", methods=["GET"])
|
||||
def index():
|
||||
week_str = request.args.get("week")
|
||||
if week_str:
|
||||
try:
|
||||
year, week_num = week_str.split("-W")
|
||||
week_start = date.fromisocalendar(int(year), int(week_num), 1)
|
||||
except (ValueError, TypeError):
|
||||
week_start = date.today() - timedelta(days=date.today().weekday())
|
||||
else:
|
||||
week_start = date.today() - timedelta(days=date.today().weekday())
|
||||
|
||||
week_end = week_start + timedelta(days=6)
|
||||
|
||||
articles = (
|
||||
Article.query
|
||||
.filter(
|
||||
Article.pub_date >= str(week_start),
|
||||
Article.pub_date < str(week_end + timedelta(days=1)),
|
||||
)
|
||||
.order_by(Article.pub_date.asc())
|
||||
.all()
|
||||
)
|
||||
|
||||
return render_template(
|
||||
"publish.html",
|
||||
articles=articles,
|
||||
week_start=week_start,
|
||||
week_end=week_end,
|
||||
week_str=f"{week_start.year}-W{week_start.isocalendar()[1]:02d}",
|
||||
)
|
||||
|
||||
|
||||
@publish_bp.route("/publish", methods=["POST"])
|
||||
def create_issue():
|
||||
week_start_str = request.form.get("week_start")
|
||||
week_end_str = request.form.get("week_end")
|
||||
cover_method = request.form.get("cover_method", "text")
|
||||
included_ids = request.form.getlist("article_ids", type=int)
|
||||
|
||||
if not included_ids:
|
||||
flash("No articles selected.", "error")
|
||||
return redirect(url_for("publish.index"))
|
||||
|
||||
week_start = date.fromisoformat(week_start_str)
|
||||
week_end = date.fromisoformat(week_end_str)
|
||||
|
||||
all_week_articles = (
|
||||
Article.query
|
||||
.filter(
|
||||
Article.pub_date >= str(week_start),
|
||||
Article.pub_date < str(week_end + timedelta(days=1)),
|
||||
)
|
||||
.all()
|
||||
)
|
||||
all_ids = {a.id for a in all_week_articles}
|
||||
excluded_ids = list(all_ids - set(included_ids))
|
||||
|
||||
headlines = [
|
||||
a.title for a in Article.query.filter(Article.id.in_(included_ids))
|
||||
.order_by(Article.pub_date.asc()).all()
|
||||
]
|
||||
|
||||
try:
|
||||
cover_path = generate_cover(
|
||||
cover_method, config.ISSUES_DIR, week_start, week_end, headlines
|
||||
)
|
||||
epub_path = build_epub(
|
||||
week_start, week_end, included_ids, cover_path, config.ISSUES_DIR
|
||||
)
|
||||
except Exception as e:
|
||||
flash(f"Error generating issue: {e}", "error")
|
||||
return redirect(url_for("publish.index"))
|
||||
|
||||
issue = Issue(
|
||||
week_start=week_start,
|
||||
week_end=week_end,
|
||||
cover_method=cover_method,
|
||||
cover_path=cover_path,
|
||||
epub_path=epub_path,
|
||||
article_ids=json.dumps(included_ids),
|
||||
excluded_article_ids=json.dumps(excluded_ids),
|
||||
status="published",
|
||||
)
|
||||
db.session.add(issue)
|
||||
db.session.commit()
|
||||
|
||||
flash(f"Issue published! {len(included_ids)} articles included.")
|
||||
return redirect(url_for("issues.index"))
|
||||
Reference in New Issue
Block a user