# Batch Image Uploader Ein Python-Skript für automatischen Batch-Upload von Bildern mit Metadaten-Extraktion. ## Features - 🔍 **Rekursives Verzeichnis-Scanning** nach unterstützten Bildformaten - 📊 **Automatische Metadaten-Extraktion** aus EXIF-Daten und Pfad-Struktur - 🚀 **Batch-Upload** mit konfigurierbarer Chunk-Größe - 📈 **Progress-Tracking** und Error-Handling - 🏗️ **Strukturierte Metadaten** (Jahr, Titel, Beschreibung, Name) ## Installation ```bash # Python Dependencies installieren pip install -r requirements.txt # Oder einzeln: pip install requests pillow ``` ## Usage ### Einfacher Upload ```bash # Linux/macOS python batch_uploader.py /path/to/images --titel "Meine Foto-Sammlung" # Windows python batch_uploader.py "C:\Users\username\Photos" --titel "Meine Foto-Sammlung" ``` ### Erweiterte Optionen ```bash # Linux/macOS - Mit Standard-Name und Backend-URL python batch_uploader.py ./photos \ --titel "Urlaubsbilder 2024" \ --name "Max Mustermann" \ --backend http://localhost:5000 \ --chunk-size 10 ## Windows / WSL: Pfade mit Leerzeichen und Sonderzeichen Windows-PowerShell (empfohlen): ```powershell # Doppelte Anführungszeichen um den kompletten Pfad, Backslashes bleiben unverändert python batch_uploader.py "C:\Users\lotzm\Nextcloud2\HH DropFolder with quota\=NutzerBildUploads=" --titel "Nextcloud Archive" --name "Lotz M." --verbose ``` Windows (CMD) – ohne Anführungszeichen mit Escapes oder mit Anführungszeichen: ```bat REM Mit Backslashes escapen (CMD): python batch_uploader.py C:\Users\lotzm\Nextcloud2\HH\ DropFolder\ with\ quota\=NutzerBildUploads= --titel "Nextcloud Archive" REM Oder einfacher mit Anführungszeichen: python batch_uploader.py "C:\Users\lotzm\Nextcloud2\HH DropFolder with quota\=NutzerBildUploads=" --titel "Nextcloud Archive" ``` WSL / Linux (bash) – Pfad in /mnt/c/... verwenden, ohne zusätzliche Backslashes in Quotes: ```bash python3 batch_uploader.py "/mnt/c/Users/lotzm/Nextcloud2/HH DropFolder with quota/=NutzerBildUploads=" --titel "Nextcloud Archive" --name "Lotz M." --verbose # oder ohne Quotes, mit Backslash-Escapes: python3 batch_uploader.py /mnt/c/Users/lotzm/Nextcloud2/HH\ DropFolder\ with\ quota/=NutzerBildUploads= --titel "Nextcloud Archive" ``` Hinweis: - Verwende nicht gleichzeitig single-quotes und Backslash-Escapes: in single-quotes werden Backslashes nicht als Escape interpretiert. - Prüfe mit `ls` (oder Tab-Completion), ob der Pfad exakt existiert, bevor du das Skript startest. # Dry-Run (nur Analyse) - Cross-Platform python batch_uploader.py /photos --dry-run --verbose python batch_uploader.py "D:\Photos" --dry-run --verbose # Nicht-rekursiv (nur Top-Level) python batch_uploader.py ./images --no-recursive ``` ### Parameter | Parameter | Beschreibung | Standard | |-----------|--------------|----------| | `directory` | Verzeichnis mit Bildern (Required) | - | | `--titel` | Standard-Titel für alle Bilder | Aus Pfad extrahiert | | `--name` | Standard-Name für alle Bilder | Leer | | `--backend` | Backend-URL | `http://localhost:5000` | | `--chunk-size` | ~~Bilder pro Upload-Batch~~ (Deprecated) | ~~5~~ | | `--no-recursive` | Nicht in Unterverzeichnisse | `False` | | `--dry-run` | Nur Analyse, kein Upload | `False` | | `--verbose` | Detailliertes Logging | `False` | ## Metadaten-Extraktion ### Erwartete Struktur: `Photos/Jahr/Name/Projekt/dateiname.endung` ### Jahr 1. **Verzeichnis-Struktur**: Aus dem Jahr-Verzeichnis (z.B. `2024/`) 2. **EXIF-Daten**: `DateTime`, `DateTimeOriginal`, `DateTimeDigitized` 3. **Pfad-Pattern**: `2024`, `2023`, etc. in anderen Verzeichnis/Dateinamen 4. **Fallback**: Aktuelles Jahr ### Titel 1. **Parameter**: `--titel` (überschreibt alles) 2. **Projekt-Verzeichnis**: `Urlaub_Mallorca` → `Urlaub Mallorca` 3. **Cleaning**: Unterstriche/Bindestriche → Leerzeichen ### Beschreibung 1. **README.md im Projekt-Verzeichnis**: Erste Zeile der README.md 2. **README.md im Name-Verzeichnis**: Als Fallback 3. **Pfad-Info**: `Jahr: 2024 | Name: Max Mustermann | Projekt: Urlaub Mallorca` 4. **Final-Fallback**: Verzeichnis-Pfad ### Name 1. **Parameter**: `--name` (überschreibt alles) 2. **Name-Verzeichnis**: Aus dem Namen-Verzeichnis (z.B. `Max_Mustermann`) 3. **Fallback**: Leer ## Unterstützte Formate - **Bilder**: `.jpg`, `.jpeg`, `.png`, `.gif`, `.bmp`, `.webp`, `.tiff`, `.tif` - **Max. Größe**: 10MB pro Datei ## Beispiel-Output ``` 12:34:56 - __main__ - INFO - Teste Verbindung zu http://localhost:5000... 12:34:56 - __main__ - INFO - ✅ Backend erreichbar 12:34:56 - __main__ - INFO - Scanne Verzeichnis: /home/user/photos 12:34:56 - __main__ - INFO - 📁 25 Bilder gefunden 12:34:56 - __main__ - INFO - 🚀 Starte Upload... 12:34:56 - __main__ - INFO - Starte Upload von 25 Bildern in 5er Batches 12:34:57 - __main__ - INFO - Chunk erfolgreich: 5 Bilder 12:34:57 - __main__ - INFO - Progress: 20.0% (5/25) 12:34:58 - __main__ - INFO - Chunk erfolgreich: 5 Bilder 12:34:58 - __main__ - INFO - Progress: 40.0% (10/25) ... 12:35:01 - __main__ - INFO - 📊 Upload abgeschlossen: 12:35:01 - __main__ - INFO - ✅ Erfolgreich: 25 12:35:01 - __main__ - INFO - ❌ Fehlgeschlagen: 0 ``` ## Verzeichnis-Struktur Beispiele ### Input-Struktur: `Photos/Jahr/Name/Projekt/dateiname.endung` **Linux/macOS:** ``` photos/ ├── 2024/ │ ├── Max_Mustermann/ │ │ ├── Urlaub_Mallorca/ │ │ │ ├── README.md │ │ │ ├── sonnenuntergang.jpg │ │ │ └── strand_spaziergang.jpg │ │ └── Hochzeit_Anna/ │ │ ├── README.md │ │ ├── zeremonie.jpg │ │ └── party.jpg │ └── Anna_Schmidt/ │ └── Architektur_Berlin/ │ ├── README.md │ └── brandenburger_tor.jpg └── 2023/ └── Familie_Mueller/ └── Weihnachten/ ├── README.md └── weihnachtsbaum.jpg ``` **Windows:** ``` C:\Users\lotzm\Nextcloud2\HH DropFolder with quota\=NutzerBildUploads=\ ├── 2024\ │ ├── Familie_Schmidt\ │ │ ├── Urlaub_Toskana\ │ │ │ ├── README.md │ │ │ ├── florenz_dom.jpg │ │ │ └── vineyard_sunset.jpg │ │ └── Geburtstag_Opa\ │ │ ├── README.md │ │ ├── torte.jpg │ │ └── familie_komplett.jpg │ └── Max_Mueller\ │ └── Business_Frankfurt\ │ ├── README.md │ └── skyline_evening.jpg └── 2023\ └── Events\ └── Hochzeit_Sarah\ ├── README.md └── kirche_aussen.jpg ``` ### README.md Beispiel ```markdown # Urlaub Mallorca Traumhafter Urlaub auf Mallorca mit Sonne, Strand und entspannten Momenten am Pool. ## Details - Jahr: 2024 - Fotograf: Max Mustermann - Projekt: Urlaub Mallorca ``` ### Extrahierte Metadaten ```json { "jahr": "2024", "titel": "Urlaub Mallorca", "beschreibung": "Traumhafter Urlaub auf Mallorca mit Sonne, Strand und entspannten Momenten am Pool.", "name": "Max Mustermann" } ``` ## Error-Handling - **Connection-Timeout**: 10s für Backend-Test, 60s für Upload - **File-Errors**: Automatisches Skip von beschädigten Bildern - **Chunk-Failures**: Einzelne Chunks können fehlschlagen ohne Abbruch - **Retry-Logic**: Verwendet Session für Connection-Reuse ## Cross-Platform Support - **✅ Windows**: Vollständige Unterstützung für Windows-Pfade und Leerzeichen - **✅ Linux/macOS**: Native Unix-Pfad Unterstützung - **✅ Nextcloud/Dropbox**: Funktioniert mit Sync-Ordnern - **✅ Netzwerk-Pfade**: UNC-Pfade (`\\server\share`) unterstützt ### Windows-spezifische Hinweise ```bash # Absolute Pfade mit Leerzeichen in Anführungszeichen python batch_uploader.py "C:\Users\lotzm\Nextcloud2\HH DropFolder with quota\=NutzerBildUploads=" # Escape-Zeichen für Sonderzeichen im Pfad python batch_uploader.py "D:\Photos\Familie Schmidt\2024 Events" # UNC-Netzwerk-Pfade python batch_uploader.py "\\\\nas-server\\photos\\2024" --verbose ``` ## Performance - **Single-Group Upload**: Alle Bilder einer Session gehören zu EINER Gruppe (Fixed!) - **Session-Reuse**: HTTP-Connections werden wiederverwendet - **Memory-Effizient**: Bilder werden einzeln gelesen und direkt uploaded - **Path-Performance**: `pathlib.Path.resolve()` für optimale Pfad-Verarbeitung - **Robuste Uploads**: Längere Timeouts für große Batches (120s) ## Troubleshooting ### Backend nicht erreichbar ```bash ### Backend Status prüfen ```bash # Prüfe Backend-Status curl http://localhost:5000/groups # Backend starten cd ../ ./prod.sh ``` ### EXIF-Fehler ```bash # Pillow neu installieren pip install --upgrade Pillow ``` ### Performance bei großen Batches ```bash # Kleinere Chunk-Size verwenden python batch_uploader.py /photos --chunk-size 3 # Progress verfolgen python batch_uploader.py /photos --verbose ```