c13d439034
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
211 lines
6.5 KiB
Markdown
211 lines
6.5 KiB
Markdown
# planning2ics
|
|
|
|
Convertit les PDFs de planning mensuel de l'**Opéra Orchestre National Montpellier** en fichiers `.ics` (iCalendar), un fichier par série artistique.
|
|
|
|
Les séries sont identifiées automatiquement grâce au site web de l'opéra (titres officiels) et à un LLM via [Ollama](https://ollama.com/).
|
|
|
|
---
|
|
|
|
## Fonctionnalités
|
|
|
|
- Extraction des événements depuis les PDFs de planning mensuel
|
|
- Identification des séries par correspondance avec le site web officiel
|
|
- Regroupement intelligent via LLM (gère les variantes de noms, séries parallèles (A)/(B)/(A')/(B'))
|
|
- Descriptions riches : œuvres répétées pour les répétitions, description officielle du site pour les concerts
|
|
- Cache local pour le scraping web et le mapping LLM (évite de refaire les appels à chaque run)
|
|
- **Script standalone** en ligne de commande
|
|
- **Application web** avec interface drag & drop, accessible sur iOS, Android et PC
|
|
|
|
---
|
|
|
|
## Structure du projet
|
|
|
|
```
|
|
planning2ics/
|
|
├── planning2ics.py # Script standalone (ligne de commande)
|
|
├── pdf/ # PDFs de planning à traiter (non versionnés)
|
|
├── ics/ # Fichiers ICS générés (non versionnés)
|
|
├── cache/ # Cache site web + mapping LLM (non versionné)
|
|
└── webapp/ # Application web
|
|
├── app.py # Backend FastAPI
|
|
├── core.py # Logique métier partagée
|
|
├── config.json # Configuration (Ollama, authentification)
|
|
├── requirements.txt
|
|
├── Dockerfile
|
|
├── docker-compose.yml # Déploiement Docker Swarm
|
|
└── static/
|
|
├── index.html
|
|
├── app.js
|
|
└── style.css
|
|
```
|
|
|
|
---
|
|
|
|
## Prérequis
|
|
|
|
- Python 3.11+
|
|
- [Ollama](https://ollama.com/) accessible sur le réseau avec les modèles :
|
|
- `qwen3.5:cloud` — clustering global des séries (rapide, requiert accès internet depuis Ollama)
|
|
- `qwen3:8b` — fallback local (fonctionne sur GPU 8 Go VRAM, ex : RX 7600)
|
|
- Docker (pour la webapp)
|
|
|
|
---
|
|
|
|
## Script standalone
|
|
|
|
### Installation
|
|
|
|
```bash
|
|
pip install pdfplumber icalendar requests beautifulsoup4
|
|
```
|
|
|
|
### Configuration
|
|
|
|
Éditer les constantes en haut de `planning2ics.py` :
|
|
|
|
```python
|
|
PDF_DIR = Path("pdf") # Dossier contenant les PDFs
|
|
OUTPUT_DIR = Path("ics") # Dossier de sortie ICS
|
|
OLLAMA_URL = "http://192.168.7.119:11434"
|
|
CLUSTER_MODEL = "qwen3.5:cloud" # Modèle pour le clustering global
|
|
OLLAMA_MODEL = "qwen3:8b" # Modèle local pour le fallback
|
|
```
|
|
|
|
### Utilisation
|
|
|
|
```bash
|
|
# Placer les PDFs dans le dossier pdf/
|
|
cp "Planning Mensuel JANV 2026.pdf" pdf/
|
|
|
|
# Lancer la conversion
|
|
python3 planning2ics.py
|
|
```
|
|
|
|
Les fichiers `.ics` sont générés dans `ics/`, un par série (ex : `La_Traviata.ics`, `Falstaff.ics`).
|
|
|
|
### Cache
|
|
|
|
Deux fichiers de cache sont créés dans `cache/` :
|
|
|
|
| Fichier | Contenu | Quand le supprimer |
|
|
|---|---|---|
|
|
| `website_catalog.json` | Titres et descriptions du site web | Nouvelle saison ou mise à jour du site |
|
|
| `series_mapping.json` | Mapping notes PDF → séries | Nouveaux PDFs avec de nouvelles œuvres |
|
|
|
|
```bash
|
|
# Vider le cache manuellement
|
|
rm cache/website_catalog.json cache/series_mapping.json
|
|
```
|
|
|
|
---
|
|
|
|
## Application web
|
|
|
|
### Configuration
|
|
|
|
Éditer `webapp/config.json` avant le déploiement :
|
|
|
|
```json
|
|
{
|
|
"ollama": {
|
|
"url": "http://192.168.7.119:11434",
|
|
"cluster_model": "qwen3.5:cloud",
|
|
"local_model": "qwen3:8b"
|
|
},
|
|
"site": {
|
|
"calendar_url": "https://www.opera-orchestre-montpellier.fr/calendrier/?saisons=32669",
|
|
"base_url": "https://www.opera-orchestre-montpellier.fr"
|
|
},
|
|
"auth": {
|
|
"session_secret": "une-cle-aleatoire-longue-et-unique",
|
|
"users": [
|
|
{"username": "admin", "password": "votre-mot-de-passe"}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
> **Important** : changer `session_secret` et le mot de passe avant tout déploiement.
|
|
> Plusieurs utilisateurs peuvent être ajoutés dans le tableau `users`.
|
|
|
|
### Déploiement Docker Swarm
|
|
|
|
```bash
|
|
# 1. Construire l'image (sur le nœud manager)
|
|
docker build -t planning2ics:latest ./webapp
|
|
|
|
# 2. Déployer le stack
|
|
docker stack deploy -c webapp/docker-compose.yml planning2ics
|
|
|
|
# 3. Vérifier le déploiement
|
|
docker stack ps planning2ics
|
|
```
|
|
|
|
L'application est accessible sur `http://<serveur>:8080`.
|
|
|
|
### Développement local
|
|
|
|
```bash
|
|
cd webapp
|
|
pip install -r requirements.txt
|
|
|
|
# Adapter les chemins pour l'environnement local
|
|
DATA_DIR=./data uvicorn app:app --reload --port 8000
|
|
```
|
|
|
|
> En local, créer un fichier `webapp/config.json` et un dossier `webapp/data/`.
|
|
|
|
### Utilisation de l'interface web
|
|
|
|
1. **Connexion** avec les identifiants du `config.json`
|
|
2. **Glisser-déposer** les PDFs de planning (ou cliquer pour les sélectionner)
|
|
3. Cliquer sur **Convertir en ICS** — la progression s'affiche en temps réel
|
|
4. **Télécharger** les fichiers ICS par série, ou tout télécharger d'un coup
|
|
5. Les traitements précédents restent accessibles dans l'**Historique**
|
|
|
|
Le bouton **Vider le cache** (section Paramètres) force un nouveau scraping du site et un nouveau clustering LLM au prochain traitement.
|
|
|
|
---
|
|
|
|
## Format des PDFs attendu
|
|
|
|
Les PDFs doivent être les plannings mensuels de l'orchestre, avec le tableau structuré :
|
|
|
|
| Jour | Date | Horaires | Titre | Lieu | Note | Déc. | Voy. |
|
|
|---|---|---|---|---|---|---|---|
|
|
| lun | 29/12 | 10:00 - 12:30 | Tutti Orch. | Beracasa (Le Corum) | PROGRAMME NOUVEL AN | 02:30 | |
|
|
|
|
Le nom du fichier doit contenir le mois et l'année (ex : `Planning Mensuel JANV 2026.pdf`) pour la détection automatique de l'année.
|
|
|
|
---
|
|
|
|
## Séries parallèles
|
|
|
|
Quand deux projets artistiques se déroulent en parallèle le même jour, le planning les distingue par les préfixes `(A)`, `(B)`, `(A')`, `(B')` dans le champ Note :
|
|
|
|
```
|
|
(A) : "Magdalena"
|
|
(B) : "Élémentaire, mon cher !"
|
|
```
|
|
|
|
Ces séries sont identifiées séparément et génèrent chacune leur propre fichier ICS.
|
|
|
|
---
|
|
|
|
## À venir
|
|
|
|
- Synchronisation directe avec Nextcloud via CalDAV
|
|
- Script de mise à jour différentielle (gestion des PDFs "Modif")
|
|
|
|
---
|
|
|
|
## Dépendances principales
|
|
|
|
| Bibliothèque | Usage |
|
|
|---|---|
|
|
| [pdfplumber](https://github.com/jsvine/pdfplumber) | Extraction des tableaux PDF |
|
|
| [icalendar](https://github.com/collective/icalendar) | Génération des fichiers ICS |
|
|
| [beautifulsoup4](https://www.crummy.com/software/BeautifulSoup/) | Scraping du site web |
|
|
| [FastAPI](https://fastapi.tiangolo.com/) | Backend de la webapp |
|
|
| [Ollama](https://ollama.com/) | Inférence LLM locale |
|