docs: update all docs with SQLite, API, content_hash, reader features

This commit is contained in:
truetype committed 2026-07-23 22:40:13 +02:00
1 parent c1421665c0
commit e62c50c616
5 files changed
+458 -199

No files matched your search

+115 -81
View File
@@ -1,98 +1,132 @@
# Analisi Completa del Progetto Bookish
# Analisi del Progetto Bookish
## 1. Analisi del Codice
### Qualità Generale
- **Leggibilità**: Buona. Codice Python pulito con nomi descrittivi. JS ben strutturato.
- **Manutenibilità**: Alta. Modulare (routes/services/static). Ogni file ha una responsabilità chiara.
- **Type Safety**: Assente (Python). JS è vanilla senza TypeScript. Accettabile per un progetto personale.
## 1. Qualità del Codice
### Punti di Forza
- App factory pattern Flask (creazione configurabile)
- SSE nativo senza dipendenze esterne
- Thread-safe SSE manager con lock
- Pulizia automatica file temporanei
- Secure filename e path sanitization
- Fallback ricerche porta libera
- Formati validati dinamicamente lato server + client
- **Architettura modulare**: blueprint Flask separati per convertitore, reader, API
- **Servizi isolati**: converter, formatter, SSE manager, database come moduli indipendenti
- **Pattern Factory**: `create_app()` con registrazione blueprint e init DB
- **Responsabilità chiare**: ogni file ha uno scopo ben definito
- **Thread safety**: lock `threading.Lock()` in SSE manager per accesso concorrente
- **Frontend vanilla**: nessuna dipendenza framework pesante, codice lineare
- **Path robust**: `os.path.basename()`, `secure_filename()`, sanity check su ogni path
- **Error handling**: try/except in routes con fallback e messaggi d'errore
### Punti di Debolezza
- **Nessun logging**: Manca logging strutturato per debug
- **Error handling**: Le eccezioni in conversion thread vengono catturate ma non loggate
- **Nessun rate limiting**: Upload illimitati (accettabile per uso singolo)
- **CSS in unico file**: Diventerà grande con l'aggiunta di feature
- **Reader JS monolitico**: `reader.js` gestisce EPUB, PDF e testo in un unico file (può essere suddiviso)
- **Nessun test**: Il progetto non ha test automatici
- **Markdown renderer**: Il simpleMarkdownToHtml è minimale (non gestisce code block, elenchi annidati, tabelle)
### Aree di Miglioramento
- **Tipo**: usare mypy con typing anche per i parametri Flask
- **Test**: nessuna suite di test (accettabile per single-user)
- **Logging**: log minimale, potrebbe essere più strutturato
- **Cleanup SSE**: il thread cleanup ogni 60s funziona ma non è elegante
- **Race condition DB**: `allow_commit` come flag per SKIP/LOCKED è un workaround. In pratica SQLite gestisce bene le race con WAL mode — testato con debounce 1.5s e non dà problemi
### Pattern e Convenzioni
- Flask Blueprints per separazione route
- Template Jinja2 con estensione base
- JS in IIFE (Immediately Invoked Function Expression) per isolamento scope
- CSS organizzato per sezioni (navbar, converter, reader)
- Config centralizzata in config.py
## 2. Sicurezza
## 2. Analisi della Sicurezza
- ✅ **Path traversal**: `secure_filename()` + `os.path.basename()` + sanity check
- ✅ **Estensione validata**: controllo su SUPPORTED_FORMATS/OUTPUT_FORMATS_BY_INPUT
- ✅ **MIME check**: al download per prevenire tipo sbagliato
- ✅ **Cleanup automatico**: file temporanei eliminati dopo 1h
- ✅ **SQLite parametriziato**: query con placeholder `?`, niente interpolazione stringhe
- ✅ **Niente eval/exec**: zero codice dinamico pericoloso
- ✅ **CSRF**: non rilevante per single-user con API REST semplici
- ⚠️ **Secret key hardcoded**: default in `app.py`. Impostare `BOOKISH_SECRET` in produzione
- ⚠️ **Upload estensione**: solo check estensione, non MIME reale (sufficiente per single-user)
- ⚠️ **No rate limiting**: Upload illimitati (accettabile per uso personale)
| Asse | Valutazione | Note |
## 3. Performance
- **SSE leggero**: nessuna dipendenza (Celery/Redis), thread in memoria
- **SQLite WAL mode**: letture non bloccano scritture
- **File temporanei su disco**: senza streaming, ma i formati ebook sono <50MB
- **Debounce position save (1.5s)**: evita flooding di scritture DB ad ogni cambio pagina
- **Sync server + localStorage**: UX veloce con aggiornamento asincrono
- **WeasyPrint**: lento su PDF grandi (>200 pagine) per limiti del motore di rendering
- **Pandoc**: performante, tempi medi 1-5s per file standard
## 4. Manutenibilità
- **Codice auto-documentante**: nomi di funzioni e variabili chiari
- **Config centralizzata**: `config.py` con tutti i path e formati
- **Servizi disaccoppiati**: modificare il converter non impatta reader o API
- **Separazione API**: le rotte `/api/` sono in blueprint dedicato
- **reader.js separato**: anche se lungo (800+ righe), è l'unico file JS del reader
- **CSS strutturato**: sezioni per reader, converter, generiche
- **Documentazione completa**: README, architecture, deploy, wiki
## 5. Affidabilità
- **Porta libera automatica**: se 5000 occupata, `find_free_port()` scorre fino a trovare una libera
- **Cleanup temp**: thread timer ogni 60 minuti elimina file scaduti
- **Fallback localStorage**: se server API non risponde, bookmarks e posizioni funzionano comunque (solo in locale)
- **Content hash come ID**: stesso file → stesso hash → stessi segnalibri, anche su PC diverso
- **Auto-creazione DB**: database creato al primo avvio senza intervento manuale
- **Gestione errori conversione**: errori Pandoc catturati e propagati come messaggio utente
## 6. Dipendenze
### Python (produzione)
| Pacchetto | Versione | Ruolo |
|---|---|---|
| Path traversal | ✅ Protetto | `os.path.basename()` + `secure_filename()` |
| Upload dimensioni | ✅ Limitato | MAX_CONTENT_LENGTH = 50MB |
| XSS (templates) | ✅ Protetto | Jinja2 auto-escape |
| XSS (reader) | ⚠️ Parziale | HTML renderizzato direttamente nel text viewer |
| Command injection | ✅ Safe | Pandoc chiamato via libreria, non shell |
| Secret key | ✅ Config | Tramite env var BOOKISH_SECRET |
| CSRF | ⚠️ Assente | Nessun token CSRF sui form (uso personale) |
| Autenticazione | ⚠️ Assente | Volutamente, uso singolo utente |
| Flask | ≥3.0 | Web framework |
| Flask-CORS | ≥4.0 | CORS per API |
| pypandoc_binary | ≥2.0 | Pandoc binary + binding |
| WeasyPrint | ≥62 | PDF da HTML |
| python-docx | ≥1.0 | DOCX post-processing |
| beautifulsoup4 | ≥4.0 | HTML/tabelle post-processing |
| lxml | ≥5.0 | Parser XML per BeautifulSoup |
| Werkzeug | ≥3.0 | Secure filename, HTTP utilities |
| markdown | ≥3.0 | MD → HTML per anteprime |
| pdfminer.six | ≥2022 | Testo base da PDF |
## 3. Analisi Performance
### Frontend (browser)
| Libreria | Versione | Ruolo |
|---|---|---|
| epub.js | 0.3.93 | Render EPUB |
| pdf.js | 3.x | Render PDF |
| PDF.js | 3.x | Text layer PDF |
| jszip | 3.x | ZIP per EPUB |
- **Conversione**: Pandoc è veloce (ebook < 1 secondo). PDF via WeasyPrint può richiedere qualche secondo.
- **Thread**: Ogni conversione è un thread separato. Per uso singolo non ci sono problemi.
- **SSE**: Connessione keep-alive leggera, ~300 bytes ogni 300ms.
- **Reader**: epub.js rende tutto lato client. File EPUB fino a 50MB senza problemi.
- **Memoria**: L'app in idle usa ~50MB. Durante conversione PDF ~150MB (WeasyPrint).
## 4. Analisi Modularità
## 7. Architettura Componenti
```
bookish/
├── routes/ ⬅️ Separati per dominio (convert vs reader)
│ ├── convert.py
│ └── reader.py
├── services/ ⬅️ Logica di business isolata dal routing
│ ├── converter.py
│ ├── sse_manager.py
│ └── formatter.py
├── templates/ ⬅️ HTML separato per pagina
├── static/ ⬅️ CSS, JS, immagini
│ ├── css/
│ ├── js/
│ └── lib/
┌──────────────────────────────────────────────────┐
│ Flask App │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Convert │ │ Reader │ │ API │ │
│ │ /upload │ │ /reader │ │ /api/* │ │
│ │ /progress│ │ /reader/ │ │ │ │
│ │ /download│ │ <file> │ │ bookmarks│ │
│ └─────┬────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ ┌─────▼─────────────▼─────────────▼──────┐ │
│ │ Services │ │
│ │ ┌──────────┐ ┌──────────┐ │ │
│ │ │converter │ │ database │─▶ SQLite │ │
│ │ │sse_mgr │ └──────────┘ │ │
│ │ │formatter │ │ │
│ │ └──────────┘ │ │
│ └──────────────────────────────────────────┘ │
│ │
│ Filesystem: uploads/ converted/ bookish.db │
└──────────────────────────────────────────────────┘
```
La separazione è chiara. Unica nota: `converter.py` importa `formatter.py` — dipendenza circolare potenziale ma gestita con import differito.
## 8. Conclusioni
## 5. Possibili Miglioramenti
**Bookish è un'applicazione solida per il suo scopo**: self-hosted, single-user, conversione e lettura ebook.
### Breve termine
- [ ] Aggiungere logging strutturato (Python logging + file di log)
- [ ] Migliorare il renderer Markdown nel reader (usare marked.js via CDN)
- [ ] Aggiungere favicon diversa per stato conversione
- [ ] Test di base con pytest
### Cosa funziona bene
- Il flusso conversione con SSE progress è semplice ma efficace
- Il reader supporta EPUB, PDF e formati testo in un'unica interfaccia
- La persistenza segnalibri con content_hash è robusta: funziona anche su PC diversi
- Il fallback localStorage assicura che il reader non si rompa se il server API è giù
- Slider larghezza e help modal completano l'UX del reader
- La documentazione è completa e in italiano
### Medio termine
- [ ] Supporto per code block syntax highlighting nel reader
- [ ] Drag&drop anche nella pagina reader per caricamento diretto
- [ ] Modalità notte persistente con preferenza sistema (prefers-color-scheme)
- [ ] Aggiungere pipeline di CI/CD per test
### Lungo termine
- [ ] Supporto multi-utente con autenticazione
- [ ] Libreria personale con cronologia conversioni (SQLite)
- [ ] Plugin system per engine di conversione custom
- [ ] Mobile app via PWA
## 6. Conclusioni
Bookish è un'applicazione solida per il suo scopo. L'architettura è pulita, la separazione delle responsabilità è corretta, e le scelte tecnologiche sono appropriate per un progetto self-hostato a uso singolo. Le aree di miglioramento principali sono logging, testing e completezza del reader markdown.
### Cosa sarebbe migliorabile (ma non necessario per single-user)
- Suite di test automatici
- Pipeline CI/CD
- HTTPS nativo (gestito da reverse proxy in produzione)
- Gestione code block più sofisticata nel reader testo
- Mobile optimization
- Logging strutturato (può essere aggiunto con poche righe)