5.4 KiB
5.4 KiB
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/<file_id>
│
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/<task_id>,/download/<filename>,/formatsreader.py— Blueprint/reader,/reader/<filename>,/reader/serve/<filename>,/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, downloadreader.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