Initial commit

This commit is contained in:
Thorsten committed 2026-05-12 15:50:33 +02:00
commit b5ecfd8f40
3 files changed
+361

No files matched your search

+64
View File
@@ -0,0 +1,64 @@
# Metadaten von Videodateien sichern
TinyMediaManager speichert zu Filmen und Serien eine Reihe von Bildern und Metadaten. Diese können händisch ergänzt werden. Teilweise steckt viel Arbeit in der Auswahl der Artwork. Mit diesem Tool können sie gesichert werden. Dieses Tool versucht, möglichst viele Naming Conventions zu berücksichtigen. Es können alle bekannten Artwork-Typen einzeln gesichert oder ausgelassen werden.
## Funktion
Das Skript durchläuft jeden Unterordner im angegebenen Verzeichnis. Wird eine `.nfo`-Datei gefunden, werden alle dazugehörigen Artworks eingesammelt und in eine `.zip`-Datei im Zielordner gepackt. Der Name der `.zip`-Datei entspricht dabei dem Namen des Films oder der Serie.
## Installation
1. Stellen Sie sicher, dass `zip` auf Deinem System installiert ist:
```bash
sudo apt install zip
```
2. Lade das Skript herunter und mache es ausführbar:
```bash
chmod +x shell_tmm_media_backup.sh
```
3. Passe die `settings.ini` an deine Bedürfnisse an (siehe Beispiel unten).
## Beispiel für die Ausführung
Führe das Skript aus, indem du den folgenden Befehl im Terminal eingibst:
```bash
./shell_tmm_media_backup.sh
```
## settings.ini
In der `settings.ini` werden die Quell- und Zielpfade festgelegt. Außerdem wird definiert, welche Artwork-Typen gesichert werden sollen:
```ini
[Paths]
source_dir=/Filme/
source_dir=/Filme 2/
source_dir=/Serien/
backup_dir_movies=/Backups/Filme
backup_dir_series/Backups/Serien
[Options]
backup_actors=true
backup_trickplay=true
backup_trailer=true
backup_banner=true
backup_clearart=true
backup_clearlogo=true
backup_fanart=true
backup_landscape=true
backup_poster=true
backup_discart=true
backup_nfo=true
backup_musictheme=true
```
## Hinweis
- Das Script verwendet **keine** Befehle wie **verschieben** oder **löschen** in deinem `source_dir`. Deine Dateien bleiben wo sie sind.
- Das Script **überschreibt** alte Backups in deinem `backup_dir` mit gleichem Film oder Seriennamen.
+28
View File
@@ -0,0 +1,28 @@
[Paths]
source_dir=/home/thorsten/mnt/unRAID/Media/Filme/FSK 0/
source_dir=/home/thorsten/mnt/unRAID/Media/Filme/FSK 6/
source_dir=/home/thorsten/mnt/unRAID/Media/Filme/FSK 12/
source_dir=/home/thorsten/mnt/unRAID/Media/Filme/FSK 16/
source_dir=/home/thorsten/mnt/unRAID/Media/Filme/FSK 18/
source_dir=/home/thorsten/mnt/unRAID/Media 2/TV Serien/FSK 0/
source_dir=/home/thorsten/mnt/unRAID/Media 2/TV Serien/FSK 6/
source_dir=/home/thorsten/mnt/unRAID/Media 2/TV Serien/FSK 12/
source_dir=/home/thorsten/mnt/unRAID/Media 2/TV Serien/FSK 16/
source_dir=/home/thorsten/mnt/unRAID/Media 2/TV Serien/FSK 18/
backup_dir_movies=/home/thorsten/mnt/unRAID/Media/[0] Temp/Backup/Filme/
backup_dir_series=/home/thorsten/mnt/unRAID/Media/[0] Temp/Backup/Serien/
[Options]
backup_actors=false
backup_trickplay=false
backup_trailer=false
backup_banner=true
backup_clearart=true
backup_clearlogo=true
backup_fanart=true
backup_landscape=true
backup_poster=true
backup_discart=true
backup_nfo=true
backup_musictheme=true
+269
View File
@@ -0,0 +1,269 @@
#!/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