Ajout d'une clé (date, start_time, titre, note) pour éviter qu'un même événement soit ajouté plusieurs fois (PDFs qui se chevauchent ou lignes dupliquées par pdfplumber sur tables multi-pages). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.
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 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
pip install pdfplumber icalendar requests beautifulsoup4
Configuration
Éditer les constantes en haut de planning2ics.py :
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
# 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 |
# Vider le cache manuellement
rm cache/website_catalog.json cache/series_mapping.json
Application web
Configuration
Éditer webapp/config.json avant le déploiement :
{
"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_secretet le mot de passe avant tout déploiement. Plusieurs utilisateurs peuvent être ajoutés dans le tableauusers.
Déploiement Docker Swarm
# 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
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.jsonet un dossierwebapp/data/.
Utilisation de l'interface web
- Connexion avec les identifiants du
config.json - Glisser-déposer les PDFs de planning (ou cliquer pour les sélectionner)
- Cliquer sur Convertir en ICS — la progression s'affiche en temps réel
- Télécharger les fichiers ICS par série, ou tout télécharger d'un coup
- 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 | Extraction des tableaux PDF |
| icalendar | Génération des fichiers ICS |
| beautifulsoup4 | Scraping du site web |
| FastAPI | Backend de la webapp |
| Ollama | Inférence LLM locale |