Files
shell_tmm_media_backup/shell_tmm_media_backup.sh
2025-02-20 20:50:17 +01:00

269 lines
12 KiB
Bash
Executable File

#!/bin/bash
settings_file="./settings.ini"
# Funktion zum Lesen der Pfade aus der settings.ini und Entfernen von Anführungszeichen
read_source_dirs() {
sed -nr "/^\[Paths\]/ { :l /^source_dir[ ]*=/ { s/[^=]*=[ ]*//; s/^\"//; s/\"$//; p; n; b l;}; n; b l;}" "$settings_file"
}
# Start- und Zielordner als Variablen
source_dirs=()
while IFS= read -r line; do
source_dirs+=("$line")
done < <(read_source_dirs)
backup_dir_movies=$(sed -nr "/^\[Paths\]/ { :l /^backup_dir_movies[ ]*=/ { s/[^=]*=[ ]*//; s/^\"//; s/\"$//; p; q;}; n; b l;}" "$settings_file")
backup_dir_series=$(sed -nr "/^\[Paths\]/ { :l /^backup_dir_series[ ]*=/ { s/[^=]*=[ ]*//; s/^\"//; s/\"$//; p; q;}; n; b l;}" "$settings_file")
# Sicherungsoptionen
backup_actors=$(sed -nr "/^\[Options\]/ { :l /^backup_actors[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" "$settings_file")
backup_trickplay=$(sed -nr "/^\[Options\]/ { :l /^backup_trickplay[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" "$settings_file")
backup_trailer=$(sed -nr "/^\[Options\]/ { :l /^backup_trailer[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" "$settings_file")
backup_banner=$(sed -nr "/^\[Options\]/ { :l /^backup_banner[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" "$settings_file")
backup_clearart=$(sed -nr "/^\[Options\]/ { :l /^backup_clearart[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" "$settings_file")
backup_clearlogo=$(sed -nr "/^\[Options\]/ { :l /^backup_clearlogo[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" "$settings_file")
backup_fanart=$(sed -nr "/^\[Options\]/ { :l /^backup_fanart[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" "$settings_file")
backup_landscape=$(sed -nr "/^\[Options\]/ { :l /^backup_landscape[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" "$settings_file")
backup_poster=$(sed -nr "/^\[Options\]/ { :l /^backup_poster[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" "$settings_file")
backup_discart=$(sed -nr "/^\[Options\]/ { :l /^backup_discart[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" "$settings_file")
backup_musictheme=$(sed -nr "/^\[Options\]/ { :l /^backup_musictheme[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" "$settings_file")
backup_nfo=$(sed -nr "/^\[Options\]/ { :l /^backup_nfo[ ]*=/ { s/[^=]*=[ ]*//; p; q;}; n; b l;}" "$settings_file")
# Liste der Dateimuster pro Typ
declare -A backup_patterns
backup_patterns[trailer]="*-trailer.* *-sample.* *-scene.* *-clip.* *-interview.* *-behindthescenes.* *-deleted.* *-featurette.* *-extra.* trailer.* sample.* scene.* clip.* interview.* behindthescenes.* deleted.* featurette.* extra.*"
backup_patterns[banner]="*-banner.* banner.*"
backup_patterns[clearart]="*-clearart.* cleartart.*"
backup_patterns[clearlogo]="*-clearlogo.* *-logo.* clearlogo.* logo.*"
backup_patterns[fanart]="*-backdrop.* *-fanart.* *-art.* backdrop.* fanart.* art.*"
backup_patterns[landscape]="*-landscape.* *-thumb.* landscape.* thumb.*"
backup_patterns[poster]="*-poster.* *-folder.* *-cover.* poster.* folder.* cover.*"
backup_patterns[discart]="*-discart.* *-disc.* discart.* disc.*"
backup_patterns[backup_musictheme]="*-theme.mp3 theme.mp3"
backup_patterns[nfo]="*.nfo"
# Spezielle Ordner für Backup
declare -A backup_folders
backup_folders[actors]=".actors"
backup_folders[trickplay]="*.trickplay"
backup_folders[fanart]="*extrafanart"
#colors
RED='\033[0;31m'
GREEN='\033[0;92m'
BLUE='\033[0;94m'
WHITE_ON_GRAY='\033[0;37;100m'
BLACK_ON_WHITE='\033[0;30;47m'
WHITE_ON_RED='\033[0;37;41m'
NC='\033[0m' # No Color
# Maximal 2 parallele Prozesse
max_parallel=1
current_jobs=0
# Prüfen, ob die Startordner existieren
for source_dir in "${source_dirs[@]}"; do
if [ ! -d "$source_dir" ]; then
echo "Startordner existiert nicht: $source_dir"
exit 1
fi
done
# Funktion für das Erstellen eines Backups für Filme
backup_movie_folder() {
local folder="$1"
local movie_name
local zip_file
# Prüfen, ob der Zielordner existiert, sonst erstellen
if [ ! -d "$backup_dir_movies" ]; then
mkdir -p "$backup_dir_movies"
fi
# Filmname aus dem Ordnernamen ableiten
movie_name=$(basename "$folder")
zip_file="${backup_dir_movies}/${movie_name}.zip"
zip_file=$(echo "$zip_file" | sed 's|//|/|g')
echo -e "${BLACK_ON_WHITE} Backup erstellen ${NC} $zip_file"
# Prüfen, ob die ZIP-Datei bereits existiert und ggf. löschen
if [ -f "$zip_file" ]; then
rm -f "$zip_file"
fi
# Temporären Ordner für das Backup erstellen
temp_dir=$(mktemp -d)
# Eigenen Ordner für den Film im temporären Verzeichnis erstellen
movie_backup_dir="${temp_dir}/${movie_name}"
mkdir -p "$movie_backup_dir"
# Dateien/Ordner sichern, basierend auf den Optionen
for type in "${!backup_patterns[@]}"; do
eval "should_backup=\$backup_$type"
if [ "$should_backup" = true ]; then
find "$folder" -type f \( $(echo "${backup_patterns[$type]}" | sed 's/ / -o -name /g' | sed 's/^/-name /') \) -exec cp --target-directory="$movie_backup_dir" -- {} +
fi
done
# Spezielle Ordner sichern
for type in "${!backup_folders[@]}"; do
eval "should_backup=\$backup_$type"
if [ "$should_backup" = true ]; then
find "$folder" -type d -name "${backup_folders[$type]}" -exec cp -r --target-directory="$movie_backup_dir" -- {} +
fi
done
# Zip-Datei erstellen
(
cd "$temp_dir" || exit
zip -r "$zip_file" "${movie_name}" >/dev/null
)
# Temporären Ordner löschen
rm -rf "$temp_dir"
}
# Funktion für das Erstellen eines Backups für Serien
backup_series_folder() {
local folder="$1"
local series_name
local zip_file
# Prüfen, ob der Zielordner existiert, sonst erstellen
if [ ! -d "$backup_dir_series" ]; then
mkdir -p "$backup_dir_series"
fi
# Serienname aus dem Ordnernamen ableiten
series_name=$(basename "$folder")
zip_file="${backup_dir_series}/${series_name}.zip"
zip_file=$(echo "$zip_file" | sed 's|//|/|g')
echo -e "${BLACK_ON_WHITE} Backup erstellen ${NC} $zip_file"
# Prüfen, ob die ZIP-Datei bereits existiert und ggf. löschen
if [ -f "$zip_file" ]; then
rm -f "$zip_file"
fi
# Temporären Ordner für das Backup erstellen
temp_dir=$(mktemp -d)
# Eigenen Ordner für die Serie im temporären Verzeichnis erstellen
series_backup_dir="${temp_dir}/${series_name}"
mkdir -p "$series_backup_dir"
# Hauptdateien der Serie sichern (im Serienordner selbst)
for type in "${!backup_patterns[@]}"; do
eval "should_backup=\$backup_$type"
if [ "$should_backup" = true ]; then
find "$folder" -maxdepth 1 -type f \( $(echo "${backup_patterns[$type]}" | sed 's/ / -o -name /g' | sed 's/^/-name /') \) -exec cp --target-directory="$series_backup_dir" -- {} +
fi
done
# Alle Unterordner (z. B. Staffel 01, Staffel 02) durchgehen und sichern
find "$folder" -mindepth 1 -maxdepth 1 -type d \( -name "Staffel*" -o -name "Season*" -o -name "Specials*" \) | while read -r season_folder; do
season_name=$(basename "$season_folder")
season_backup_dir="${series_backup_dir}/${season_name}"
mkdir -p "$season_backup_dir"
# Dateien innerhalb des Staffelordners sichern
for type in "${!backup_patterns[@]}"; do
eval "should_backup=\$backup_$type"
if [ "$should_backup" = true ]; then
find "$season_folder" -type f \( $(echo "${backup_patterns[$type]}" | sed 's/ / -o -name /g' | sed 's/^/-name /') \) -exec cp --target-directory="$season_backup_dir" -- {} +
fi
done
# Spezielle Ordner (z. B. .trickplay) innerhalb der Staffel sichern
for type in "${!backup_folders[@]}"; do
eval "should_backup=\$backup_$type"
if [ "$should_backup" = true ]; then
find "$season_folder" -type d -name "${backup_folders[$type]}" -exec cp -r --target-directory="$season_backup_dir" -- {} +
fi
done
done
# Zip-Datei erstellen
(
cd "$temp_dir" || exit
zip -r "$zip_file" "${series_name}" >/dev/null
)
# Temporären Ordner löschen
rm -rf "$temp_dir"
}
# Warte auf aktuell laufende Prozesse
wait_for_jobs() {
while [ "$current_jobs" -ge "$max_parallel" ]; do
wait -n
current_jobs=$((current_jobs - 1))
done
}
# Verarbeitung starten
export -f backup_movie_folder
export -f backup_series_folder
export backup_dir_movies backup_dir_series backup_patterns backup_folders
echo "────────────────────────────────────────────────────────────────"
echo -e "${BLACK_ON_WHITE} TMM Media Backup ${NC}"
echo "────────────────────────────────────────────────────────────────"
echo " "
for i in "${!source_dirs[@]}"; do
printf -v folder_number "%02d" "$((i+1))"
echo -e "${WHITE_ON_GRAY} Source Folder $folder_number ${NC} ${source_dirs[$i]}"
done
echo " "
echo "────────────────────────────────────────────────────────────────"
echo " "
echo -e "${WHITE_ON_GRAY} Movies Backups ${NC} ""$backup_dir_movies"""
echo -e "${WHITE_ON_GRAY} Series Backups ${NC} ""$backup_dir_series"""
echo " "
echo "────────────────────────────────────────────────────────────────"
for source_dir in "${source_dirs[@]}"; do
find "$source_dir" -type f \( -name "*.nfo" -o -name "tvshow.nfo" \) -print0 | \
while IFS= read -r -d '' nfo_file; do
folder=$(dirname "$nfo_file")
# Überspringe Ordner mit dem Namen ".deletedByTMM"
if [[ "$folder" == *"/.deletedByTMM"* ]]; then
continue
fi
if [[ "$(basename "$nfo_file")" == "tvshow.nfo" ]]; then
wait_for_jobs
echo "────────────────────────────────────────────────────────────────"
echo -e "${BLACK_ON_WHITE} NFO gefunden ${NC} $nfo_file"
echo -e "${BLACK_ON_WHITE} NFO Typ ${NC} Serie"
backup_series_folder "$folder"
echo -e "${BLACK_ON_WHITE} Abgeschlossen! ${NC} $(date +'%Y-%m-%d %H:%M:%S')"
else
# Sicherstellen, dass keine Staffel-/Season- oder Specials-Ordner als eigenständige Filme behandelt werden
if [[ "$folder" != *"/Staffel "* && "$folder" != *"/Season "* && "$folder" != *"/Specials"* ]]; then
wait_for_jobs
echo "────────────────────────────────────────────────────────────────"
echo -e "${BLACK_ON_WHITE} NFO gefunden ${NC} $nfo_file"
echo -e "${BLACK_ON_WHITE} NFO Typ ${NC} Film"
backup_movie_folder "$folder"
echo -e "${BLACK_ON_WHITE} Abgeschlossen! ${NC} $(date +'%Y-%m-%d %H:%M:%S')"
fi
fi
current_jobs=$((current_jobs + 1))
done
done
# Warte auf alle verbleibenden Prozesse
wait