Files
bookish/docs/plans/2026-07-22-bookish-design.md
T

4.6 KiB

Bookish — Design Document

Data: 2026-07-22 Stato: Validato

Overview

Bookish è un'app Flask self-hosted per convertire eBook tra formati e visualizzarli in un reader web integrato. Uso personale, girante su server Proxmox.

Stack

Componente Tecnologia
Backend Flask (Python 3)
Template Jinja2
Conversione Pandoc + WeasyPrint + python-docx
Frontend reader epub.js + pdf.js
Progresso real-time SSE (Server-Sent Events)
DB opzionale SQLite (cronologia, reading position)
Storage locale uploads/ + converted/

Struttura directory

bookish/
├── app.py
├── config.py
├── requirements.txt
├── run.sh
├── uploads/
├── converted/
└── bookish/
    ├── __init__.py           # create_app factory
    ├── routes/
    │   ├── __init__.py
    │   ├── convert.py         # upload, convert, download, SSE
    │   └── reader.py          # reader page, serve file
    ├── services/
    │   ├── __init__.py
    │   ├── converter.py       # dispatcher Pandoc/lib specialistiche
    │   ├── sse_manager.py     # eventi progresso in memoria
    │   └── formatter.py       # PDF/DOCX layout avanzato
    ├── templates/
    │   ├── base.html
    │   ├── index.html         # upload + convertitore
    │   └── reader.html        # reader
    └── static/
        ├── css/
        ├── js/
        └── lib/               # epub.js, pdf.js

Formati supportati

Formato Input Output Engine
EPUB ✅ ✅ Pandoc
Markdown ✅ ✅ Pandoc
DOCX ✅ ✅ Pandoc + python-docx
PDF ✅ ✅ Pandoc + WeasyPrint
TXT ✅ ✅ Pandoc
HTML ✅ ✅ Pandoc
FB2 ✅ ✅ Pandoc
MOBI ✅ ❌ Pandoc
LaTeX ✅ ✅ Pandoc

Flusso di conversione con SSE

  1. Utente carica file + seleziona formato output
  2. Flask avvia thread conversione, restituisce task_id
  3. Frontend apre connessione SSE a /progress/<task_id>
  4. Thread conversione emette eventi progresso (20%, 40%, ... 100%)
  5. A 100%, SSE invia download_url
  6. Frontend mostra link download
  7. File in converted/ puliti dopo 1h

Stati progresso: started → analyzing → converting (con %) → finalizing → completed / error

Conversion pipeline

convert(input_file, output_format):
  ├─ INPUT non-testuali (EPUB/FB2/MOBI/HTML/LaTeX) → Pandoc per qualsiasi output
  ├─ PDF in → EPUB/MD/DOCX/TXT/HTML → Pandoc
  ├─ DOCX → PDF → Pandoc → HTML intermedio → WeasyPrint
  ├─ MD/TXT → EPUB → Pandoc con template EPUB
  ├─ DOCX → EPUB/MD/HTML → Pandoc
  ├─ MD/TXT/HTML → DOCX → Pandoc + python-docx post-processing
  └─ Output PDF avanzato → WeasyPrint con template HTML custom

Reader

Route /reader/<file_id> carica il reader con:

  • EPUB → epub.js
  • PDF → pdf.js
  • Formati testo (md, txt, html, docx, fb2) → convertiti in HTML da Pandoc, renderizzati in iframe

Funzionalità reader

Feature Come
Zoom epub.js fontSize / pdf.js zoom / CSS scale
Temi (giorno/notte/seppia) epub.js themes / pdf.js CSS filter
Font (dimensione, famiglia) epub.js fontSize + CSS injection
Ricerca full-text epub.js search API / pdf.js findController
Sommario epub.js navigation / pdf.js outline
Segnalibri LocalStorage
Salvataggio posizione Auto-save su LocalStorage ad ogni cambio pagina
Vista singola/doppia epub.js spread mode
Scorrimento continuo epub.js continuous manager
Navigazione tastiera ← → per pagina, +/- per zoom
Fullscreen Fullscreen API
Annotazioni/highlights epub.js annotations API

Layout reader

  • Sidebar sinistra collassabile (Indice, Ricerca, Note)
  • Barra superiore col titolo capitolo
  • Area lettura centrale
  • Toolbar inferiore con navigazione, zoom, temi, fullscreen
  • Toolbar si nasconde dopo 3s inattività

Frontend convertitore

  • Drag & drop upload
  • Griglia formati output con validazione dinamica
  • Barra progresso animata con SSE
  • Download diretto a completamento
  • Tema chiaro iniziale

Gestione errori

  • Formato input non supportato → messaggio chiaro
  • Formato output non valido → bottoni disabilitati
  • Pandoc non installato → errore all'avvio
  • File >50MB → bloccato
  • Conversione fallita → SSE evento error
  • Pulizia automatica file vecchi >1h

Pre-requisiti server

  • Python 3.10+
  • Pandoc installato via apt
  • WeasyPrint dipende da librerie di sistema (libpango, libcairo)