feat: complete web UI — dashboard, articles, publish, settings, issues
Made-with: Cursor
This commit is contained in:
77
src/routes/issues.py
Normal file
77
src/routes/issues.py
Normal file
@@ -0,0 +1,77 @@
|
||||
import os
|
||||
import json
|
||||
from flask import Blueprint, render_template, send_file, redirect, url_for, flash
|
||||
|
||||
from app import db
|
||||
from src.models import Issue, Article
|
||||
from src.cover import generate_cover
|
||||
from src.epub_builder import build_epub
|
||||
import config
|
||||
|
||||
issues_bp = Blueprint("issues", __name__)
|
||||
|
||||
|
||||
@issues_bp.route("/issues")
|
||||
def index():
|
||||
issues = Issue.query.order_by(Issue.created_at.desc()).all()
|
||||
issue_data = []
|
||||
for issue in issues:
|
||||
article_count = len(json.loads(issue.article_ids))
|
||||
issue_data.append({
|
||||
"issue": issue,
|
||||
"article_count": article_count,
|
||||
})
|
||||
return render_template("issues.html", issues=issue_data)
|
||||
|
||||
|
||||
@issues_bp.route("/issues/<int:issue_id>/download")
|
||||
def download(issue_id):
|
||||
issue = Issue.query.get_or_404(issue_id)
|
||||
if not os.path.exists(issue.epub_path):
|
||||
flash("ePub file not found.", "error")
|
||||
return redirect(url_for("issues.index"))
|
||||
return send_file(
|
||||
issue.epub_path,
|
||||
as_attachment=True,
|
||||
download_name=os.path.basename(issue.epub_path),
|
||||
)
|
||||
|
||||
|
||||
@issues_bp.route("/issues/<int:issue_id>/cover")
|
||||
def cover_image(issue_id):
|
||||
issue = Issue.query.get_or_404(issue_id)
|
||||
if not issue.cover_path or not os.path.exists(issue.cover_path):
|
||||
flash("Cover image not found.", "error")
|
||||
return redirect(url_for("issues.index"))
|
||||
return send_file(issue.cover_path, mimetype="image/jpeg")
|
||||
|
||||
|
||||
@issues_bp.route("/issues/<int:issue_id>/regenerate", methods=["POST"])
|
||||
def regenerate(issue_id):
|
||||
issue = Issue.query.get_or_404(issue_id)
|
||||
article_ids = json.loads(issue.article_ids)
|
||||
|
||||
headlines = [
|
||||
a.title for a in Article.query.filter(Article.id.in_(article_ids))
|
||||
.order_by(Article.pub_date.asc()).all()
|
||||
]
|
||||
|
||||
try:
|
||||
cover_path = generate_cover(
|
||||
issue.cover_method, config.ISSUES_DIR,
|
||||
issue.week_start, issue.week_end, headlines
|
||||
)
|
||||
epub_path = build_epub(
|
||||
issue.week_start, issue.week_end, article_ids,
|
||||
cover_path, config.ISSUES_DIR
|
||||
)
|
||||
|
||||
issue.cover_path = cover_path
|
||||
issue.epub_path = epub_path
|
||||
db.session.commit()
|
||||
|
||||
flash("Issue regenerated successfully.")
|
||||
except Exception as e:
|
||||
flash(f"Regeneration failed: {e}", "error")
|
||||
|
||||
return redirect(url_for("issues.index"))
|
||||
Reference in New Issue
Block a user