Documentation du projet pour faciliter les futures sessions : structure, commandes, formats supportés, points d'extension. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
124 lines
3.5 KiB
Markdown
124 lines
3.5 KiB
Markdown
# CLAUDE.md - Contexte projet pour agent IA
|
|
|
|
## Description du projet
|
|
|
|
Script Python de gestion des métadonnées EXIF pour photos argentiques. Lit un fichier JSON généré par l'application mobile **Exif Notes** et écrit les métadonnées dans les fichiers images correspondants.
|
|
|
|
## Stack technique
|
|
|
|
- **Python 3.11+** (utilise `zoneinfo` natif)
|
|
- **exiftool** (CLI) appelé via `subprocess` — pas de wrapper Python
|
|
- **pytest** pour les tests
|
|
- **flake8** pour le linting (max-line-length=100)
|
|
|
|
## Structure du projet
|
|
|
|
```
|
|
json_to_metadata/
|
|
├── __init__.py # Version du package
|
|
├── cli.py # Point d'entrée CLI (argparse)
|
|
├── json_parser.py # Lecture et validation du JSON
|
|
├── metadata_mapper.py # Mapping JSON → tags EXIF
|
|
├── exif_writer.py # Écriture EXIF via exiftool
|
|
└── xmp_writer.py # Génération de fichiers XMP sidecar
|
|
|
|
tests/
|
|
├── test_json_parser.py
|
|
├── test_metadata_mapper.py
|
|
├── test_exif_writer.py
|
|
└── test_xmp_writer.py
|
|
```
|
|
|
|
## Commandes utiles
|
|
|
|
```bash
|
|
# Activer l'environnement
|
|
source venv/bin/activate
|
|
|
|
# Lancer le script
|
|
python -m json_to_metadata <fichier.json> -d <dossier_images>
|
|
|
|
# Options CLI
|
|
# -v, --verbose Mode verbeux (DEBUG)
|
|
# --dry-run Affiche sans exécuter
|
|
# --force-xmp Force création XMP même pour TIFF/JPEG
|
|
|
|
# Tests
|
|
pytest tests/ -v
|
|
|
|
# Linting
|
|
flake8 json_to_metadata/ tests/ --max-line-length=100
|
|
```
|
|
|
|
## Format JSON attendu (Exif Notes)
|
|
|
|
```json
|
|
{
|
|
"id": "roll-001",
|
|
"camera": { "make": "Nikon", "model": "FM2" },
|
|
"lens": { "make": "Nikon", "model": "Nikkor 50mm f/1.4" },
|
|
"filmStock": { "make": "Kodak", "model": "Portra 400" },
|
|
"iso": 400,
|
|
"frames": [
|
|
{
|
|
"id": 1,
|
|
"date": "2024-03-15T14:30",
|
|
"shutter": "1/125",
|
|
"aperture": "f/2.8",
|
|
"focalLength": 50,
|
|
"location": { "latitude": 48.8584, "longitude": 2.2945 },
|
|
"note": "Description de la photo",
|
|
"flashUsed": false,
|
|
"lightSource": "daylight"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
## Mapping JSON → EXIF
|
|
|
|
| Champ JSON | Tag EXIF |
|
|
|------------|----------|
|
|
| `camera.make/model` | `Make`, `Model` |
|
|
| `lens.make/model` | `LensMake`, `LensModel` |
|
|
| `iso` | `ISO` |
|
|
| `frame.date` | `DateTimeOriginal`, `CreateDate` |
|
|
| `frame.shutter` | `ExposureTime`, `ShutterSpeedValue` |
|
|
| `frame.aperture` | `FNumber`, `ApertureValue` |
|
|
| `frame.focalLength` | `FocalLength` |
|
|
| `frame.location.*` | `GPSLatitude/Ref`, `GPSLongitude/Ref` |
|
|
| `frame.note` | `ImageDescription`, `UserComment` |
|
|
| `frame.flashUsed` | `Flash` |
|
|
| `filmStock.*` | Inclus dans `ImageDescription` |
|
|
|
|
## Formats supportés
|
|
|
|
### Vitesses d'obturation
|
|
- Fractions : `1/125`, `1/1000`
|
|
- Secondes : `2`, `2s`, `2"`, `4'`
|
|
- Mode Bulb : `B`, `bulb`
|
|
|
|
### Dates
|
|
- ISO complet : `2024-03-15T14:30:00`
|
|
- Sans secondes : `2024-03-15T14:30`
|
|
- Avec timezone : `2024-03-15T14:30:00+02:00`
|
|
- Date seule : `2024-03-15`
|
|
|
|
### Images
|
|
- EXIF intégré : `.tif`, `.tiff`, `.jpg`, `.jpeg`
|
|
- Support partiel (fallback XMP) : `.avif`, `.heic`, `.webp`
|
|
- XMP sidecar uniquement : autres formats
|
|
|
|
## Conventions de code
|
|
|
|
- Docstrings en français
|
|
- Messages de log en français
|
|
- Fuseau horaire par défaut : `Europe/Paris`
|
|
- Pas d'emoji sauf demande explicite
|
|
|
|
## Points d'extension possibles
|
|
|
|
- Ajout de nouveaux tags EXIF dans `metadata_mapper.py` (fonction `map_frame_to_exif`)
|
|
- Nouveaux formats de date dans `parse_date()` (liste `formats`)
|
|
- Support de nouveaux formats d'image dans `exif_writer.py` (constantes `*_EXTENSIONS`)
|