# Architettura di Bookish ## Panoramica Bookish è un'applicazione web Flask monolitica progettata per l'uso self-hostato. Si compone di due macro-funzionalità: un **convertitore di formati ebook** e un **reader web** per visualizzarli. ``` ┌──────────┐ ┌─────────────────────────────────────┐ │ Browser │────▶│ Flask │ │ │ │ ┌─────────┐ ┌──────────────────┐ │ │ HTML/CSS │ │ │ Routes │ │ Services │ │ │ JS/ES │ │ │ │ │ │ │ │ │ │ │convert │─▶│converter.py │──▶│ Pandoc │epub.js │ │ │reader │ │sse_manager.py │ │ WeasyPrint │pdf.js │ │ │ │ │formatter.py │ │ python-docx └──────────┘ │ └─────────┘ └──────────────────┘ │ └─────────────────────────────────────┘ │ │ uploads/ converted/ (temporaneo) (temporaneo) ``` ## Stack Tecnologico | Componente | Tecnologia | Ruolo | |---|---|---| | Backend | Flask 3.x + Jinja2 | Server web, routing, template engine | | Conversione | Pandoc 3.x (via pypandoc) | Motore di conversione principale | | PDF avanzato | WeasyPrint | PDF con layout precisi da HTML | | DOCX avanzato | python-docx | Post-processing documenti Word | | Frontend | JavaScript vanilla | Nessun framework pesante | | Reader EPUB | epub.js 0.3 | Renderer EPUB lato client | | Reader PDF | pdf.js 3.x | Renderer PDF lato client | | Progresso | SSE (Server-Sent Events) | Barra progresso real-time | | Storage | Filesystem locale | `uploads/` e `converted/` | ## Flusso Conversione ``` Upload file → Validazione formato → Avvio thread conversione │ ┌──────────────────────┘ ▼ SSE Manager crea task_id │ Frontend apre connessione SSE │ Converter dispatcher: ├─ Pandoc per formati standard ├─ WeasyPrint per PDF avanzati ├─ python-docx per DOCX └─ BeautifulSoup per tabelle/HTML │ Ogni fase → update SSE progress │ ▼ File salvato in converted/ SSE invia download_url ``` ## Flusso Reader ``` Upload file → Salva in uploads/ → Redirect a /reader/ │ Template reader.html │ Rileva formato: ├─ EPUB → epub.js ├─ PDF → pdf.js └─ Testo → HTML renderizzato │ Interazioni tutte lato client: - Temi, zoom, ricerca - Segnalibri, posizione - Salvataggio in LocalStorage ``` ## Architettura del Codice ### Routes (`bookish/routes/`) - **`convert.py`** — Blueprint `/upload`, `/progress/`, `/download/`, `/formats` - **`reader.py`** — Blueprint `/reader`, `/reader/`, `/reader/serve/`, `/reader/formats` ### Services (`bookish/services/`) - **`converter.py`** — Dispatcher che sceglie Pandoc o pipeline custom in base alla coppia input/output. Aggiorna SSE progress ad ogni fase. - **`sse_manager.py`** — Gestisce task in memoria con `{task_id: {progress, status, output_file}}`. Thread-safe con lock. - **`formatter.py`** — WeasyPrint PDF da HTML con post-processing (tabelle, immagini via BeautifulSoup). ### Frontend (`bookish/static/js/`) - **`main.js`** — Convertitore: drag&drop, form, SSE connection, download - **`reader.js`** — Reader: epub.js/pdf.js/text viewer, side panel, temi, ricerca, segnalibri, posizione ## Decisioni Architetturali | Decisione | Motivazione | |---|---| | Thread invece di Celery | Uso singolo utente, niente Redis, minore complessità | | SSE invece di WebSocket | Sincrono semplice, nessuna dipendenza extra, supporto nativo | | LocalStorage per reader | Zero backend, nessun DB necessario per lettura | | File temporanei con cleanup | Nessun database, i file si auto-puliscono dopo 1h | | JS vanilla | Nessun framework, leggero, manutenibile | | Pandoc via pypandoc-binary | Include Pandoc binary, nessuna installazione systema richiesta | ## Limiti Attuali - **Thread in memoria**: I task di conversione muoiono se il processo Flask viene killato - **No autenticazione**: Uso personale, nessun multi-utente - **No HTTPS di base**: Da abilitare con reverse proxy (nginx/caddy) - **No ottimizzazione mobile**: Funziona ma non è prioritario - **estione code block reader**: Reader testo ha markdown renderer minimale