Files
json-to-metadata/CLAUDE.md
Antoine Van Elstraete 954d644e79 Ajout du fichier CLAUDE.md pour contexte agent IA
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>
2026-02-10 16:23:56 +01:00

3.5 KiB

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

# 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)

{
  "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)