fix: code review round 2 - logging, cleanup, TOC, simplify converter
This commit is contained in:
1 parent
723e50eb25
commit
45f08c8b9b
4 files changed
+45
-36
No files matched your search
@@ -1,15 +1,14 @@
|
||||
import os
|
||||
import uuid
|
||||
import logging
|
||||
import threading
|
||||
from flask import Blueprint, request, jsonify, Response, send_file, render_template, current_app
|
||||
from werkzeug.utils import secure_filename
|
||||
from config import SUPPORTED_FORMATS, OUTPUT_FORMATS_BY_INPUT
|
||||
from bookish.services.sse_manager import (
|
||||
create_task, generate_sse_events, update_progress,
|
||||
mark_error, get_status, cleanup_task
|
||||
)
|
||||
from bookish.services.sse_manager import create_task, generate_sse_events, get_status
|
||||
from bookish.services.converter import run_conversion, get_format_from_ext
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
convert_bp = Blueprint("convert", __name__)
|
||||
|
||||
ALLOWED_EXTENSIONS = set(SUPPORTED_FORMATS.keys())
|
||||
@@ -82,6 +81,8 @@ def upload():
|
||||
)
|
||||
thread.start()
|
||||
|
||||
logger.info("Conversione avviata: %s -> %s (task=%s)", input_ext, output_format, task_id)
|
||||
|
||||
return jsonify({
|
||||
"task_id": task_id,
|
||||
"input_format": input_ext,
|
||||
@@ -115,6 +116,7 @@ def download(filename):
|
||||
return jsonify({"error": "File non trovato o già rimosso"}), 404
|
||||
|
||||
ext = os.path.splitext(safe)[1].lower().lstrip(".")
|
||||
logger.info("Download: %s.%s", safe, ext)
|
||||
mime = SUPPORTED_FORMATS.get(ext, {}).get("mime", "application/octet-stream")
|
||||
download_name = f"converted.{ext}"
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import os
|
||||
import logging
|
||||
import pypandoc
|
||||
from config import SUPPORTED_FORMATS
|
||||
from bookish.services.sse_manager import update_progress, mark_complete, mark_error
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_format_from_ext(filename):
|
||||
ext = os.path.splitext(filename)[1].lower().lstrip(".")
|
||||
@@ -24,27 +27,20 @@ def run_conversion(input_path, output_path, input_format, output_format, task_id
|
||||
|
||||
update_progress(task_id, 30, "converting")
|
||||
|
||||
# Formati speciali che richiedono pipeline custom
|
||||
if input_format == "docx" and output_format == "pdf":
|
||||
_convert_docx_to_pdf(input_path, output_path, task_id)
|
||||
elif output_format == "pdf":
|
||||
_convert_to_pdf(input_path, output_path, input_format, task_id)
|
||||
elif input_format == "docx" and output_format in ("epub", "md", "html"):
|
||||
_convert_with_pandoc(input_path, output_path, input_format, output_format, task_id)
|
||||
elif input_format == "pdf" and output_format in ("epub", "docx", "md", "txt", "html"):
|
||||
_convert_with_pandoc(input_path, output_path, input_format, output_format, task_id)
|
||||
else:
|
||||
_convert_with_pandoc(input_path, output_path, input_format, output_format, task_id)
|
||||
|
||||
update_progress(task_id, 90, "finalizing")
|
||||
_post_process(output_path, output_format)
|
||||
|
||||
update_progress(task_id, 100)
|
||||
mark_complete(task_id, os.path.basename(output_path))
|
||||
|
||||
except Exception as e:
|
||||
logger.exception("Conversione fallita: %s -> %s (%s)", input_format, output_format, filename)
|
||||
mark_error(task_id, str(e))
|
||||
raise
|
||||
|
||||
|
||||
def _validate_pandoc_format(input_format, output_format):
|
||||
@@ -148,6 +144,4 @@ def _convert_docx_to_pdf(input_path, output_path, task_id):
|
||||
os.remove(html_path)
|
||||
|
||||
|
||||
def _post_process(output_path, output_format):
|
||||
"""Post-processing opzionale sul file generato."""
|
||||
pass
|
||||
|
||||
@@ -50,26 +50,29 @@ def cleanup_task(task_id):
|
||||
def generate_sse_events(task_id):
|
||||
"""Genera eventi SSE finché la conversione non è completata o in errore."""
|
||||
prev_progress = -1
|
||||
while True:
|
||||
status = get_status(task_id)
|
||||
if not status:
|
||||
yield f"event: error\ndata: {json.dumps({'message': 'Task not found'})}\n\n"
|
||||
break
|
||||
try:
|
||||
while True:
|
||||
status = get_status(task_id)
|
||||
if not status:
|
||||
yield f"event: error\ndata: {json.dumps({'message': 'Task not found'})}\n\n"
|
||||
return
|
||||
|
||||
progress = status["progress"]
|
||||
if progress != prev_progress or status["status"] in ("completed", "error"):
|
||||
data = {
|
||||
"progress": progress,
|
||||
"status": status["status"],
|
||||
}
|
||||
if status.get("error"):
|
||||
data["error"] = status["error"]
|
||||
if status.get("output_file"):
|
||||
data["download_url"] = f"/download/{status['output_file']}"
|
||||
yield f"data: {json.dumps(data)}\n\n"
|
||||
prev_progress = progress
|
||||
progress = status["progress"]
|
||||
if progress != prev_progress or status["status"] in ("completed", "error"):
|
||||
data = {
|
||||
"progress": progress,
|
||||
"status": status["status"],
|
||||
}
|
||||
if status.get("error"):
|
||||
data["error"] = status["error"]
|
||||
if status.get("output_file"):
|
||||
data["download_url"] = f"/download/{status['output_file']}"
|
||||
yield f"data: {json.dumps(data)}\n\n"
|
||||
prev_progress = progress
|
||||
|
||||
if status["status"] in ("completed", "error"):
|
||||
break
|
||||
if status["status"] in ("completed", "error"):
|
||||
return
|
||||
|
||||
sleep(0.3)
|
||||
sleep(0.3)
|
||||
finally:
|
||||
cleanup_task(task_id)
|
||||
@@ -386,8 +386,18 @@
|
||||
}
|
||||
|
||||
function updateActiveToc(loc, toc, book) {
|
||||
// epub.js provides location.start.cfi
|
||||
document.querySelectorAll("#tocList li").forEach((l) => l.classList.remove("active"));
|
||||
if (!loc || !loc.start || !toc || !book) return;
|
||||
const href = loc.start.href;
|
||||
if (!href) return;
|
||||
const items = document.querySelectorAll("#tocList li");
|
||||
for (const li of items) {
|
||||
if (li.textContent && href.includes(li.textContent.trim())) {
|
||||
li.classList.add("active");
|
||||
li.scrollIntoView({ block: "nearest" });
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// === Search ===
|
||||
|
||||
Reference in new issue
Block a user