NixOS/workstation/scripts/sub-sync.sh

185 lines
5.6 KiB
Bash
Executable File

#! /usr/bin/env nix-shell
#! nix-shell -i bash -p bash fd ripgrep file alass ffmpeg gum
MEDIA_ROOT=("/mnt/pool/multimedia/media/Series" "/mnt/pool/multimedia/media/Movies")
REPLACE_DIR="/mnt/pool/multimedia/media"
SUBTITLE_MIRROR="/mnt/pool/multimedia/backups/subtitles"
RAM_SUB="/dev/shm/sub.srt"
# BACKUPS SUBTITLES
backup_subtitles() {
while IFS= read -r subtitle; do
echo "backing up $subtitle"
dest_dir="$(dirname "$subtitle")"
dest_dir="${dest_dir/$REPLACE_DIR/$SUBTITLE_MIRROR}"
mkdir -p "$dest_dir"
cp "$subtitle" "${subtitle/$REPLACE_DIR/$SUBTITLE_MIRROR}"
done < <(fd . -tf -e srt --absolute-path "${MEDIA_ROOT[@]}")
}
clean_up() {
while IFS= read -r directory; do
echo "cleaning up $directory"
subtitles=()
mapfile -d $'\0' subtitles < <(fd . "$directory" -e srt -tf -d 1 -0)
if [ "${#subtitles[@]}" -lt 2 ]; then
continue
fi
unset base_subtitle
unset subtitles_group
for subtitle in "${subtitles[@]}"; do
group=()
mapfile -d $'\0' group < <(fd --fixed-strings \
"$(basename "$subtitle" .srt)" "$directory" \
-d 1 -tf -0 -e srt)
for key in "${!group[@]}"; do
if ! echo "${group[$key]}" | rg -P '\.\d{1,2}(\.\w+(-\w+)?)?\.srt' -q; then
unset "group[$key]"
continue
fi
if [ -z "${group[$key]}" ]; then
continue
fi
echo "removing $(basename "$subtitle")"
rm "$subtitle"
done
done
done < <(fd . -td --absolute-path "${MEDIA_ROOT[@]}")
}
rename_languages() {
while IFS= read -r file; do
base=$(basename "$file" .eng.srt)
dir=$(dirname "$file")
echo "renaming sub $base"
mv "$file" "$dir/$base.$2.srt"
done < <(fd . -tf --absolute-path "${MEDIA_ROOT[@]}" -e "$1.srt")
}
sync_subtitles() {
while IFS= read -r directory; do
echo "scanning for sync $directory"
while IFS= read -r subtitle; do
echo "processing $subtitle"
video=()
extension=$(echo "$subtitle" | rg -oP "(\.\w+(-\w+)?)?\.srt")
basename="$(basename "$subtitle" "$extension")"
mapfile -d $'\0' video < <(fd "$basename" \
"$directory" --fixed-strings \
-e mkv -e mp4 -e avi -e webm -tf -d 1 -0)
# skips directory if it contains more than 1 video file
# should never get triggered
if [ "${#video[@]}" -gt 1 ]; then
basename "$(dirname "$directory")"
echo "$(basename "$directory") has many video files: ${#video[@]}"
continue
fi
# update subtitle in ram
if [ -e "$RAM_SUB" ]; then
rm "$RAM_SUB"
fi
cp "$subtitle" "$RAM_SUB"
if [ ! -e $RAM_SUB ] && [ ! -e "${video[0]}" ]; then
continue
fi
echo "processing...$subtitle"
alass-cli "${video[0]}" "$RAM_SUB" "$subtitle"
done < <(fd . "$directory" -tf -e srt -d 1 --newer "$1")
done < <(fd . -td --absolute-path "${MEDIA_ROOT[@]}")
}
find_dupes() {
while IFS= read -r directory; do
videos=()
mapfile -d $'\0' videos < <(fd . \
"$directory" -tf -d 1 -0 \
-e mkv -e mp4 -e avi -e webm)
if [ "${#videos[@]}" == 0 ]; then
if [[ "$directory" != *"Season"* ]]; then
continue
fi
echo "NO FILES ERROR: $directory"
fi
if [ "${#videos[@]}" == 1 ]; then
continue
fi
if [ "${#videos[@]}" -gt 1 ]; then
if [[ "$directory" == *"media/Movies"* ]]; then
echo "Movie directory has more than a movie"
continue
fi
for episode in "${videos[@]}"; do
episode_number="$(echo "$episode" |
rg -oP "S\d+E\d+(-E\d+)? ")"
episode_files="$(
fd "$episode_number" "$directory" --fixed-strings \
-tf -d 1 \
-e mkv -e mp4 -e avi -e webm | wc -l
)"
if [ "$episode_files" == 1 ]; then
continue
fi
echo ____________________________
echo "The episode $episode_number is repeated on"
echo "$directory"
fd "$episode_number" "$directory" --fixed-strings \
-tf -d 1 \
-e mkv -e mp4 -e avi -e webm
done
fi
done < <(fd . -td --absolute-path "${MEDIA_ROOT[@]}")
}
fd . /mnt/pool/multimedia/media/Series/ --owner jawz -x chown sonarr:piracy {}
fd . /mnt/pool/multimedia/media/Movies/ --owner jawz -x chown radarr:piracy {}
fd . "${MEDIA_ROOT[@]}" -td -x chmod 775 {}
fd . "${MEDIA_ROOT[@]}" -tf -x chmod 664 {}
rename_languages eng en
rename_languages spa es
rename_languages mx es_MX
if [ -n "$1" ]; then
operation=$1
else
operation=$(gum choose backup clean sync all)
fi
if [ -n "$2" ]; then
start_time=$2
else
start_time="$(date '+%Y-%m-%d') 00:00:00"
fi
case $operation in
backup)
backup_subtitles
;;
clean)
clean_up
;;
sync)
sync_subtitles "$start_time"
;;
dupe)
find_dupes
;;
all)
echo "backing up"
backup_subtitles
echo "cleaning up"
clean_up
echo "syncing"
sync_subtitles "$start_time"
;;
esac