Files
darktable-sync/scripts/darktable_sync.sh
T
martin 6fd8a8c308 Refaktorierung: Common-Library mit generischen Funktionen
- Neue `darktable_common.sh` mit wiederverwendbaren Shell-Funktionen (Locking, Logging, Validierung)
- `darktable_sync.sh` nutzt jetzt Common-Library statt eingebettete Logik
- `darktable_wrapper.sh` vereinfacht durch Nutzung von Common-Funktionen
- Eliminiert Code-Duplikation zwischen Sync und Wrapper
- Verbessert Wartbarkeit und Testbarkeit

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 20:35:56 +02:00

222 lines
8.0 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=darktable_common.sh
source "$SCRIPT_DIR/darktable_common.sh"
log_step "Darktable Sync gestartet (PID $$, Argumente: ${*:-keine})"
check_dependency rsync
check_dependency ssh openssh-client
check_dependency notify-send libnotify-bin
check_dependency darktable
log "Alle Abhängigkeiten vorhanden."
load_config
validate_config
log "Konfiguration geladen: Server=$SERVER_USER@$SERVER_IP:$SERVER_SSH_PORT"
log " DB lokal: $LOCAL_DARKTABLE_DB_DIR"
log " DB Server: $SERVER_DB_DIR"
log " Fotos lokal: $LOCAL_PHOTO_DIR"
log " Fotos Server:$SERVER_PHOTO_DIR"
export DISPLAY="${DISPLAY:-:0}"
count_synced_files() {
local log_file="$1" direction="$2" count=0
case "$direction" in
up) count=$(grep -cE '^>f|^cd' "$log_file" 2>/dev/null) || count=0 ;;
down) count=$(grep -cE '^<f|^cd' "$log_file" 2>/dev/null) || count=0 ;;
esac
echo "$count"
}
LOCKDIR="$CONFIG_DIR/sync.lock"
LOCKPID="$LOCKDIR/pid"
TMPFILES=()
log "Lock anfordern: $LOCKDIR"
if ! mkdir "$LOCKDIR" 2>/dev/null; then
EXISTING_PID=$(cat "$LOCKPID" 2>/dev/null || true)
if [ -n "$EXISTING_PID" ] && ! kill -0 "$EXISTING_PID" 2>/dev/null; then
log "Verwaisten Lock gefunden (PID $EXISTING_PID läuft nicht mehr) wird entfernt."
rm -f "$LOCKPID"
rmdir "$LOCKDIR" 2>/dev/null || true
mkdir "$LOCKDIR"
else
log_error "Sync läuft bereits (PID ${EXISTING_PID:-unbekannt}). Lock: $LOCKDIR"
echo " rmdir $LOCKDIR" >&2
exit 1
fi
fi
echo "$$" > "$LOCKPID"
log "Lock erworben (PID $$)."
trap 'rm -f "${TMPFILES[@]}" "$LOCKPID"; rmdir "$LOCKDIR" 2>/dev/null || true; log "Lock freigegeben."' EXIT
SHOW_NOTIFY_START_STOP=false
if [[ "${1:-}" == "--with-notify-start-stop" ]]; then
SHOW_NOTIFY_START_STOP=true
fi
log "Prüfen ob Darktable läuft..."
if pgrep -x darktable > /dev/null 2>&1; then
log "Darktable läuft (PID: $(pgrep -x darktable | tr '\n' ' ')) Sync übersprungen."
notify-send "Darktable Sync Abbruch" \
"Darktable ist gerade geöffnet. Sync erst nach dem Beenden möglich." \
-u normal -t 8000
exit 0
fi
log "Darktable läuft nicht Sync kann fortfahren."
if [ -f "$CONFIG_DIR/sync_pending" ]; then
log "Ausstehender Sync aus vorherigem Lauf wird jetzt nachgeholt."
notify-send "Darktable Sync" "Ausstehender Sync wird jetzt ausgeführt..." -t 3000
fi
log "Serververbindung prüfen ($SERVER_USER@$SERVER_IP Port $SERVER_SSH_PORT)..."
if ! server_reachable; then
log "Server nicht erreichbar Sync übersprungen, sync_pending gesetzt."
touch "$CONFIG_DIR/sync_pending"
exit 0
fi
log "Server erreichbar."
if [ "$SHOW_NOTIFY_START_STOP" = true ]; then
notify-send "Darktable Sync" "Sync gestartet..." -t 3000
fi
log "Active-Marker auf Server prüfen..."
ACTIVE=$(ssh_server "cat '$SERVER_DB_DIR/darktable.active' 2>/dev/null || true")
if [ -n "$ACTIVE" ]; then
log "WARNUNG: Active-Marker vorhanden: $ACTIVE"
notify-send "Darktable Sync Warnung" \
"Darktable läuft möglicherweise auf: $ACTIVE" -u normal -t 10000
else
log "Kein Active-Marker kein anderer Client aktiv."
fi
log "Darktable-Versionen prüfen..."
SERVER_VERSION=$(ssh_server "cat '$SERVER_DB_DIR/darktable_version' 2>/dev/null || true")
LOCAL_VERSION=$(darktable --version 2>&1 | head -1 || true)
log " Lokal: ${LOCAL_VERSION:-unbekannt}"
log " Server: ${SERVER_VERSION:-noch nicht gespeichert}"
if [ -n "$SERVER_VERSION" ]; then
LOCAL_MM=$(echo "$LOCAL_VERSION" | grep -oP '\d+\.\d+' | head -1 || true)
SERVER_MM=$(echo "$SERVER_VERSION" | grep -oP '\d+\.\d+' | head -1 || true)
if [ -n "$SERVER_MM" ] && [ "$LOCAL_MM" != "$SERVER_MM" ]; then
log_error "Versionskonflikt: lokal=$LOCAL_MM, server=$SERVER_MM"
log_error "Bitte beide Rechner auf gleichen Stand bringen."
notify-send "Darktable Sync Versionskonflikt" \
"Lokal: $LOCAL_MM Server: $SERVER_MM\nBitte angleichen!" \
-u critical
touch "$CONFIG_DIR/sync_pending"
exit 1
fi
log "Versionen übereinstimmend ($LOCAL_MM)."
fi
log_step "Datenbank-Backup"
log " $LOCAL_DARKTABLE_DB_DIR/library.db → library.db.bak"
cp "$LOCAL_DARKTABLE_DB_DIR/library.db" "$LOCAL_DARKTABLE_DB_DIR/library.db.bak"
log " $LOCAL_DARKTABLE_DB_DIR/data.db → data.db.bak"
cp "$LOCAL_DARKTABLE_DB_DIR/data.db" "$LOCAL_DARKTABLE_DB_DIR/data.db.bak"
log "Backup abgeschlossen."
SYNC_LOG=$(mktemp)
TMPFILES+=("$SYNC_LOG")
log_step "Upload: Datenbank"
log " Quelle: $LOCAL_DARKTABLE_DB_DIR/"
log " Ziel: $SERVER_USER@$SERVER_IP:$SERVER_DB_DIR/"
UPLOAD_LOG_DB=$(mktemp)
TMPFILES+=("$UPLOAD_LOG_DB")
if ! rsync -uavh --itemize-changes \
--exclude '*.lock' \
--exclude 'darktable_version' \
-e "ssh -p $SERVER_SSH_PORT" \
"$LOCAL_DARKTABLE_DB_DIR/" "$SERVER_USER@$SERVER_IP:$SERVER_DB_DIR/" \
2>&1 | tee -a "$SYNC_LOG" "$UPLOAD_LOG_DB"; then
log_error "Upload Datenbank fehlgeschlagen (Quelle: $LOCAL_DARKTABLE_DB_DIR)"
touch "$CONFIG_DIR/sync_pending"
exit 1
fi
SENT_DB=$(count_synced_files "$UPLOAD_LOG_DB" "up")
log "Datenbank-Upload abgeschlossen: $SENT_DB Datei(en) übertragen."
log_step "Upload: Fotos"
log " Quelle: $LOCAL_PHOTO_DIR/"
log " Ziel: $SERVER_USER@$SERVER_IP:$SERVER_PHOTO_DIR/"
UPLOAD_LOG_PHOTOS=$(mktemp)
TMPFILES+=("$UPLOAD_LOG_PHOTOS")
if ! rsync -uavh --itemize-changes \
--exclude '*.lock' \
-e "ssh -p $SERVER_SSH_PORT" \
"$LOCAL_PHOTO_DIR/" "$SERVER_USER@$SERVER_IP:$SERVER_PHOTO_DIR/" \
2>&1 | tee -a "$SYNC_LOG" "$UPLOAD_LOG_PHOTOS"; then
log_error "Upload Fotos fehlgeschlagen (Quelle: $LOCAL_PHOTO_DIR)"
touch "$CONFIG_DIR/sync_pending"
exit 1
fi
SENT_PHOTOS=$(count_synced_files "$UPLOAD_LOG_PHOTOS" "up")
log "Foto-Upload abgeschlossen: $SENT_PHOTOS Datei(en) übertragen."
log_step "Download: Datenbank"
log " Quelle: $SERVER_USER@$SERVER_IP:$SERVER_DB_DIR/"
log " Ziel: $LOCAL_DARKTABLE_DB_DIR/"
DOWNLOAD_LOG_DB=$(mktemp)
TMPFILES+=("$DOWNLOAD_LOG_DB")
if ! rsync -uavh --itemize-changes \
--exclude '*.lock' \
-e "ssh -p $SERVER_SSH_PORT" \
"$SERVER_USER@$SERVER_IP:$SERVER_DB_DIR/" "$LOCAL_DARKTABLE_DB_DIR/" \
2>&1 | tee -a "$SYNC_LOG" "$DOWNLOAD_LOG_DB"; then
log_error "Download Datenbank fehlgeschlagen (Ziel: $LOCAL_DARKTABLE_DB_DIR)"
touch "$CONFIG_DIR/sync_pending"
exit 1
fi
RECEIVED_DB=$(count_synced_files "$DOWNLOAD_LOG_DB" "down")
log "Datenbank-Download abgeschlossen: $RECEIVED_DB Datei(en) empfangen."
log_step "Download: Fotos"
log " Quelle: $SERVER_USER@$SERVER_IP:$SERVER_PHOTO_DIR/"
log " Ziel: $LOCAL_PHOTO_DIR/"
DOWNLOAD_LOG_PHOTOS=$(mktemp)
TMPFILES+=("$DOWNLOAD_LOG_PHOTOS")
if ! rsync -uavh --itemize-changes \
--exclude '*.lock' \
-e "ssh -p $SERVER_SSH_PORT" \
"$SERVER_USER@$SERVER_IP:$SERVER_PHOTO_DIR/" "$LOCAL_PHOTO_DIR/" \
2>&1 | tee -a "$SYNC_LOG" "$DOWNLOAD_LOG_PHOTOS"; then
log_error "Download Fotos fehlgeschlagen (Ziel: $LOCAL_PHOTO_DIR)"
touch "$CONFIG_DIR/sync_pending"
exit 1
fi
RECEIVED_PHOTOS=$(count_synced_files "$DOWNLOAD_LOG_PHOTOS" "down")
log "Foto-Download abgeschlossen: $RECEIVED_PHOTOS Datei(en) empfangen."
log "Versionsdatei aktualisieren: $LOCAL_DARKTABLE_DB_DIR/darktable_version"
echo "$LOCAL_VERSION" > "$LOCAL_DARKTABLE_DB_DIR/darktable_version"
rm -f "$CONFIG_DIR/sync_pending"
log "sync_pending entfernt."
TOTAL_SENT=$((SENT_DB + SENT_PHOTOS))
TOTAL_RECEIVED=$((RECEIVED_DB + RECEIVED_PHOTOS))
log_step "Sync abgeschlossen"
log " Hochgeladen: $TOTAL_SENT ($SENT_DB DB + $SENT_PHOTOS Fotos)"
log " Heruntergeladen: $TOTAL_RECEIVED ($RECEIVED_DB DB + $RECEIVED_PHOTOS Fotos)"
if [ "$TOTAL_SENT" -gt 0 ] || [ "$TOTAL_RECEIVED" -gt 0 ]; then
notify-send "Darktable Sync" \
"$TOTAL_SENT hochgeladen | ↓ $TOTAL_RECEIVED heruntergeladen" -t 10000
else
log "Keine Änderungen alles aktuell."
fi
if [ "$SHOW_NOTIFY_START_STOP" = true ]; then
notify-send "Darktable Sync" "Sync abgeschlossen." -t 3000
fi