255 lines
7.6 KiB
Markdown
255 lines
7.6 KiB
Markdown
# 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 - Absolute Pfade mit Leerzeichen
|
|
python batch_uploader.py "C:\Users\lotzm\Nextcloud2\HH DropFolder with quota\=NutzerBildUploads=" \
|
|
--titel "Nextcloud Archive" \
|
|
--name "Lotz M." \
|
|
--verbose
|
|
|
|
# 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
|
|
``` |