Project-Image-Uploader/scripts
2025-10-17 22:37:26 +02:00
..
test_images Initial Commit 2025-10-15 21:33:00 +02:00
batch_uploader.py Initial Commit 2025-10-15 21:33:00 +02:00
examples.sh Initial Commit 2025-10-15 21:33:00 +02:00
README.md IMP: Moved database to src/data/db and imges to src/data/images 2025-10-17 22:37:26 +02:00
requirements.txt Initial Commit 2025-10-15 21:33:00 +02:00
test_path_compatibility.py Initial Commit 2025-10-15 21:33:00 +02:00
test_setup.py Initial Commit 2025-10-15 21:33:00 +02:00

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

# Python Dependencies installieren
pip install -r requirements.txt

# Oder einzeln:
pip install requests pillow

Usage

Einfacher Upload

# 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

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

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:

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

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

# 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

### Backend Status prüfen
```bash
# Prüfe Backend-Status
curl http://localhost:5000/groups

# Backend starten
cd ../
./prod.sh

EXIF-Fehler

# Pillow neu installieren
pip install --upgrade Pillow

Performance bei großen Batches

# Kleinere Chunk-Size verwenden
python batch_uploader.py /photos --chunk-size 3

# Progress verfolgen
python batch_uploader.py /photos --verbose