- Python 100%
| docs | ||
| src/nextcloud_uploader | ||
| tests | ||
| .gitignore | ||
| config.example.yaml | ||
| pyproject.toml | ||
| README.md | ||
Nextcloud Media Uploader
Ein stateless CLI-Uploader für Bilder und Videos. Dateien aus einem gemeinsamen lokalen Ordner werden anhand ihres Aufnahmedatums nach folgendem Muster in Nextcloud abgelegt:
/Bilder/Fotos/2026/06/IMG_20260620_120052125.jpg
/Bilder/Fotos/2026/06/VID_20260621_105904.mp4
Nach einem bestätigten Upload wird die lokale Datei gelöscht. Es gibt keine SQLite-Datenbank; Nextcloud ist die einzige Quelle der Wahrheit.
Eine vollständige Beschreibung von Installation, Konfiguration, internem Ablauf, Fehlerbehandlung sowie Cron- und systemd-Betrieb enthält das ausführliche Benutzer- und Betriebshandbuch.
Voraussetzungen
- Python 3.11 oder neuer
- ExifTool (
sudo apt install libimage-exiftool-perlunter Debian/Ubuntu) - Ein Nextcloud-App-Passwort
- Ein gültiges, vom System akzeptiertes HTTPS-Zertifikat
Installation
python3 -m venv .venv
. .venv/bin/activate
pip install -e .
mkdir -p ~/.config/nextcloud-uploader
cp config.example.yaml ~/.config/nextcloud-uploader/config.yaml
In ~/.config/nextcloud-uploader/config.yaml muss mindestens der lokale Quellordner angepasst
werden. Das Kennwort
wird nicht in YAML gespeichert:
export NEXTCLOUD_APP_PASSWORD='mein-app-passwort'
nextcloud-uploader --dry-run
nextcloud-uploader
Der Quellordner kann pro Lauf angegeben werden und überschreibt dann upload.source:
nextcloud-uploader --source /pfad/zu/meinen/medien --dry-run
nextcloud-uploader --source /pfad/zu/meinen/medien
--dry-run darf Nextcloud lesen und für einen sicheren Duplikatvergleich Dateien streamen,
ändert aber weder lokale noch entfernte Dateien.
Verhalten bei Kollisionen
Existiert der ursprüngliche Dateiname, prüft das Programm nacheinander _1, _2 usw.
Kandidaten gleicher Größe werden per SHA-256 vollständig verglichen. Bei identischem Inhalt
wird nur die lokale Kopie gelöscht. Bei unterschiedlichem Inhalt wird der nächste Name geprüft.
Ein neuer Upload erfolgt zunächst unter einem temporären Namen und wird anschließend ohne
Überschreibrecht auf den endgültigen Namen verschoben.
Vorübergehende Serverantworten (404, 408, 429 und 5xx) werden mit den in
nextcloud.retry_delays_seconds konfigurierten Pausen wiederholt. Nach einem unklaren PUT
oder MOVE prüft der Uploader zunächst, ob die Datei trotz der Fehlerantwort angekommen ist.
Authentifizierungsfehler und echte Namenskollisionen werden nicht blind wiederholt.
Cron
Beispiel für einen Lauf alle zehn Minuten, wobei das Passwort aus einer nur für den Benutzer lesbaren Environment-Datei geladen wird:
*/10 * * * * . "$HOME/.config/nextcloud-uploader.env" && /pfad/.venv/bin/nextcloud-uploader >> "$HOME/nextcloud-uploader.log" 2>&1
Beispielinhalt der Environment-Datei:
NEXTCLOUD_APP_PASSWORD='mein-app-passwort'
export NEXTCLOUD_APP_PASSWORD
Die Datei sollte mit chmod 600 geschützt werden. Ein Prozess-Lock verhindert überlappende
Läufe für denselben Quellordner.
Exitcodes
0: Alle verarbeitbaren Dateien wurden erfolgreich behandelt.1: Mindestens eine Datei ist fehlgeschlagen; sie bleibt lokal erhalten.2: Konfiguration, ExifTool oder Prozess-Lock ist fehlerhaft.
Dateien, deren letzte Änderung weniger als fünf Minuten zurückliegt, werden auf einen späteren Lauf verschoben. Nicht unterstützte Dateien, Symlinks und leere Unterordner bleiben unverändert.
Entwicklung
pip install -e '.[test]'
pytest