From 45f08c8b9b37531b147f46e2346f60226a6d9c95 Mon Sep 17 00:00:00 2001 From: truetype Date: Wed, 22 Jul 2026 15:58:01 +0200 Subject: [PATCH] fix: code review round 2 - logging, cleanup, TOC, simplify converter --- bookish/routes/convert.py | 10 +++++--- bookish/services/converter.py | 16 ++++-------- bookish/services/sse_manager.py | 43 ++++++++++++++++++--------------- bookish/static/js/reader.js | 12 ++++++++- 4 files changed, 45 insertions(+), 36 deletions(-) diff --git a/bookish/routes/convert.py b/bookish/routes/convert.py index d87a7a0..09be68c 100644 --- a/bookish/routes/convert.py +++ b/bookish/routes/convert.py @@ -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}" diff --git a/bookish/services/converter.py b/bookish/services/converter.py index b9e30ae..f2f3a22 100644 --- a/bookish/services/converter.py +++ b/bookish/services/converter.py @@ -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 + diff --git a/bookish/services/sse_manager.py b/bookish/services/sse_manager.py index 0f47fd2..78ab0ec 100644 --- a/bookish/services/sse_manager.py +++ b/bookish/services/sse_manager.py @@ -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) diff --git a/bookish/static/js/reader.js b/bookish/static/js/reader.js index c7c4341..57fe22b 100644 --- a/bookish/static/js/reader.js +++ b/bookish/static/js/reader.js @@ -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 ===