Skip to content

Instantly share code, notes, and snippets.

@xd003
Created September 22, 2023 01:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xd003/c20f6715724985f23f8c66aaeb16e7ca to your computer and use it in GitHub Desktop.
Save xd003/c20f6715724985f23f8c66aaeb16e7ca to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
[[ ${1} = "upgrade" ]] && _SKIP_CONFLICT_CHECK="override"
FILEBOT_BRANCH=beta # ( stable | beta )
if [ "${FILEBOT_BRANCH}" = "stable" ]; then
DOCKERURL=ghcr.io/xd003/filebot:latest
else
DOCKERURL=ghcr.io/xd003/filebot:latest
fi
DFILEBOT="docker run --rm -it -v /GD:/GD -v $HOME/.filebot:/data $DOCKERURL"
# Defining default paths
export ROOT="/GD"
export DST="${ROOT}/Media" \
MOVIESRC="${ROOT}/Uploads/Movies" \
TVSRC="${ROOT}/Uploads/TV Shows" \
ANIMESRC="${ROOT}/Uploads/Anime"
# Defining Variables for location of groovy format
export MOVIEFT="@/data/formats/MovieFormat.groovy" \
TVFT="@/data/formats/TVFormat.groovy" \
ANIMEFT="@/data/formats/AnimeFormat.groovy" \
WEBHOOK="https://discord.com/api/webhooks/756539677133242519/tpY0vrmp7aQFjtCp0vKGPuCwDzYzi2wBv8QiYkBeEmjvcAylKotE6_X0m0KNyeGbJDSE"
db_renaming() {
for type in f d; do
find "${MOVIESRC}" -mindepth 1 -maxdepth 1 -not -empty -not -name "*.plox" -regextype posix-extended -not -regex ".*MID[0-9]+.*" -type "${type}" | {
while IFS= read -r file_name; do
if [[ ${type} = "f" ]]; then
name="${file_name%.*}" ext="${file_name#*"$name"}"
final_name="${name}"
else
final_name="${file_name}"
fi
echo "¶ ${final_name}" | sed 's|/GD/Uploads/||'
read -r -e -p "Enter the TMDB ID/URL : " tmdb < /dev/tty
re='^[0-9]+$'
if ! [[ $tmdb =~ $re ]] ; then
tmdb="$(echo "$tmdb" | grep -Eo '/(tv|movie)/[0-9]{1,8}' | sed -e 's|/tv/||' -e 's|/movie/||')"
fi
echo "mv -f \"${file_name}\" \"${final_name} MID${tmdb}${ext}\"" >> $HOME/.filebot/tmdb.sh
echo
done
}
done
for content in "${TVSRC}" "${ANIMESRC}"; do
for type in f d; do
find "${content}" -mindepth 1 -maxdepth 1 -not -empty -not -name "*.plox" -regextype posix-extended -not -regex ".*\[imdb-tt[0-9]+\]\sTID[0-9]+.*" -type "${type}" | {
while IFS= read -r file_name; do
if [[ ${type} = "f" ]]; then
name="${file_name%.*}" ext="${file_name#*"$name"}"
final_name="${name}"
else
final_name="${file_name}"
fi
echo "¶ ${final_name}" | sed 's|/GD/Uploads/||'
read -r -e -p "Enter the IMDB ID/URL : " imdb < /dev/tty
re='^tt[0-9]+$'
if ! [[ $imdb =~ $re ]] ; then
imdb="$(echo "$imdb" | grep -Eo '\/title\/(tt[0-9]+)' | sed 's|/title/||')"
fi
imdb="[imdb-${imdb}]"
echo && read -r -e -p "Enter the TMDB ID/URL : " tmdb < /dev/tty
re='^[0-9]+$'
if ! [[ $tmdb =~ $re ]] ; then
tmdb="$(echo "$tmdb" | grep -Eo '/(tv|movie)/[0-9]{1,8}' | sed -e 's|/tv/||' -e 's|/movie/||')"
fi
echo "mv -f \"${file_name}\" \"${final_name} ${imdb} TID${tmdb}${ext}\"" >> $HOME/.filebot/tmdb.sh
echo
done
}
done
done
}
subtitle() {
cd "$MOVIESRC" || return 1
local script_path="$HOME/.filebot/subtitle.sh"
for f in . *; do
if [[ -d ${f} && -n $(find "${f}" -maxdepth 1 -type f) ]]; then
local d="$(cd "${f}" && pwd)"
else
continue
fi
local subs videos total_subs total_videos
mapfile -t subs <<< "$(find "${d}" -maxdepth 1 -type f -name "*.srt" -not -name "*.plox")"
total_subs="${#subs[@]}"
mapfile -t videos <<< "$(find "${d}" -maxdepth 1 -type f \( -iname \*.mp4 -o -iname \*.mkv -o -iname \*.avi -o -iname \*.webm \) -not -name "*.plox")"
total_videos="${#videos[@]}"
# return if either found subtitles or videos are zero
[[ -z ${subs} || -z ${videos} ]] && continue
if [[ ${total_subs} -eq 1 && ${total_videos} -eq 1 ]]; then
echo "mv '${subs[0]}' '${videos[0]%.*}.${subs[0]##*.}' 2> /dev/null" >> "${script_path}"
else
printf "\n%s\n" "===== Current dir: $(basename "${d}") ====="
local list_done="" srt_list="" list_num="0"
declare -a tmp_srt=()
for sub in "${subs[@]}"; do
echo && echo "Current subtitle: ${sub//*\//}"
echo "Available Movies:"
for video in "${videos[@]}"; do
( printf "%s\n" " $((num += 1)). ${video//*\//}" )
done
local choice_is_valid=""
until [[ ${choice_is_valid} = "true" ]]; do
[[ ${choice_is_valid} = "false" ]] && printf "Invalid number , please try again.\n"
printf "Enter the number corresponding to the video the current srt belongs to : "
read -r choice
if [[ -z "${choice}" || "$((choice))" -eq 0 || "$((choice))" -gt ${total_videos} ]]; then
choice_is_valid="false"
else
choice_is_valid="true"
fi
done
local video_index="$((choice - 1))"
__srt() {
local _srt="${1:?}"
case "${srt_list}" in
*"__$(basename "${sub}")__"*)
printf "%s\n%s\n" "mv '${sub}' '${_srt}.tmpsrt' 2> /dev/null" "$(< "${script_path}")" >| "${script_path}"
tmp_srt+=("${_srt}.tmpsrt")
;;
*)
printf "%s\n" "mv '${sub}' '${_srt}' 2> /dev/null" >> "${script_path}"
;;
esac
srt_list+="__$(basename "${_srt}")__"
}
case "${list_done}" in
*"__${video_index}__"*) __srt "${videos[${video_index}]%.*}.$((list_num += 1)).${sub##*.}" ;;
*) __srt "${videos[${video_index}]%.*}.${sub##*.}" ;;
esac
list_done+="__${video_index}__"
done
for i in "${tmp_srt[@]}"; do
echo "mv '${i}' '${i%%.tmpsrt}'" >> "${script_path}"
done
fi
done
}
preprocess_main() {
_rename_files() {
local subdir_name="${1:?}" subdir_num="${2:?}"
local parent_dir="${PWD}"
cd "$subdir_name" || exit 1
local current_dir="${PWD}"
mapfile -t filenames <<< "$(printf "%b\n" * | grep -iE 'mp4|avi|webm|mkv' | sort -uV)"
local num=0
for file in "${filenames[@]}"; do
num="$((num + 1))"
if [[ num -lt 10 ]]; then
num_final="0${num}"
else
num_final="${num}"
fi
nfile="${file%.*}" ext="${file#*"$nfile"}"
echo "mv -f \"${current_dir}/${file}\" \"${current_dir}/${nfile} ${subdir_num}x${num_final}${ext}\"" >> "${HOME}/.filebot/preprocess.sh"
done
cd "${parent_dir}" &> /dev/null || exit 1
}
for dir in *; do
local name="${dir}"
[[ -f ${name} ]] && continue #skip the files
local folders total_folders top_name_full top_name subdir_num=0
mapfile -t folders <<< "$(find "${name}" -type f -printf "%h\n" | sort -uV)"
total_folders="${#folders[@]}"
if [[ -z ${folders} ]]; then
continue #skip empty folders
elif [[ "${total_folders}" -gt 1 ]]; then
top_name_full="$(cd "$(dirname "${folders[0]}")" && pwd)"
top_name="$(basename "${top_name_full}")"
echo && printf "%s\n" "Current dir: ${top_name}"
printf "%s\n" "${folders[@]}" | xargs -I {} -n 1 basename "{}"
local choice_is_valid=""
until [[ ${choice_is_valid} = "true" ]]; do
[[ ${choice_is_valid} = "false" ]] && printf "Invalid Input , please try again.\n"
printf "Would you like to auto assign seaons in numerical order to the folders listed above [y/n]: "
read -r choice
if [[ -z "${choice}" || ! "${choice}" =~ (y|Y|n|N) ]]; then
choice_is_valid="false"
else
choice_is_valid="true"
fi
done
case "${choice}" in
y | Y)
for subdir in "${folders[@]}"; do
_rename_files "${subdir}" "$((subdir_num += 1))"
done
;;
n | N)
local subdir_num_array given_inputs="" show_err_msg=""
local required_inputs="${#total_folders[@]}"
until [[ ${show_err_msg} = "false" ]]; do
[[ ${show_err_msg} = "true" ]] &&
printf "%s\n" "Error: Total given values ( ${given_inputs:-0} ) is less than required ( ${required_inputs} ). !"
printf "Enter the numbers to manually assign seasons to folders listed above , separated by space.\n--> "
read -ra subdir_num_array
given_inputs="${#subdir_num_array[@]}"
{ [[ ${given_inputs} -ge "${required_inputs}" ]] && show_err_msg="false"; } || show_err_msg="true"
done
for subdir in "${folders[@]}"; do
_rename_files "${subdir}" "${subdir_num_array[$((subdir_num++))]}"
done
;;
esac
else
top_name_full="${folders[0]}"
top_name="$(basename "${top_name_full}")"
echo && printf "%s\n" "Current dir: ${top_name}"
( cd "${top_name_full}" && printf "%b\n" * | grep -iE 'mp4|avi|webm|mkv' | sort -uV | grep "" -m 2 )
printf "Enter the season number for the current dir: "
echo && echo && echo "NOTE - If above listed episodes are not in ascending order , exit the script immediately & don't proceed further . Manually fix the episode naming before running filebot again"
read -r subdir_num
_rename_files "${top_name_full}" "${subdir_num}"
fi
done
}
preprocess() {
for content in "$TVSRC" "$ANIMESRC"; do
check="$(printf "%b\n" "${content}"/* | wc -l)"
if [ ! "$check" == "1" ]; then
cd "$content" &&
preprocess_main
fi
done
}
verify() {
local type="${1:?}"
maxLimit=600 currRuntime=0
while true; do
case "${type}" in
preprocess)
check="$(find "${TVSRC}" "${ANIMESRC}" -type f \( -iname \*.mp4 -o -iname \*.mkv -o -iname \*.avi -o -iname \*.webm \) -regextype posix-extended -not -regex '.*[0-9]\s*x\s*[0-9]+.*' | wc -l)"
string="Preprocessing"
;;
tmdb)
check="$(find "${MOVIESRC}" "${TVSRC}" "${ANIMESRC}" -mindepth 1 -maxdepth 1 -not -empty -not -name "*.plox" -regextype posix-extended -not -regex ".*[MT]ID[0-9]+.*" -type f,d | wc -l)"
string="TMDB ID"
;;
subtitle)
check="$(find "${MOVIESRC}" -mindepth 1 -maxdepth 1 -not -empty -not -name "*.plox" -regextype posix-extended -not -regex ".*MID[0-9]+.*" -type f -name "*.srt" | wc -l)"
string="Subtitles"
;;
esac
if (($check == 0)); then
sleep 20s
case "${type}" in
preprocess)
check="$(find "${TVSRC}" "${ANIMESRC}" -type f \( -iname \*.mp4 -o -iname \*.mkv -o -iname \*.avi -o -iname \*.webm \) -regextype posix-extended -not -regex '.*[0-9]\s*x\s*[0-9]+.*' | wc -l)"
string="Preprocessing"
;;
tmdb)
check="$(find "${MOVIESRC}" "${TVSRC}" "${ANIMESRC}" -mindepth 1 -maxdepth 1 -not -empty -not -name "*.plox" -regextype posix-extended -not -regex ".*[MT]ID[0-9]+.*" -type f,d | wc -l)"
string="TMDB ID"
;;
subtitle)
check="$(find "${MOVIESRC}" -mindepth 1 -maxdepth 1 -not -empty -not -name "*.plox" -regextype posix-extended -not -regex ".*MID[0-9]+.*" -type f -name "*.srt" | wc -l)"
string="Subtitles"
;;
esac
((check == 0)) && echo "${string} has been updated in mount" && break
fi
((currRuntime > maxLimit)) && echo "Unable to update ${string} in mount" && export _SKIP_FILEBOT="true" && break
((currRuntime+=5))
sleep 5s
echo -ne "Waiting for mount to get updated [${currRuntime}/${maxLimit}]\r"
done
}
conflict-opt() {
[[ ${_SKIP_CONFLICT_CHECK} = "override" ]] && CFC="override" && return 0
echo
cat << EOF
1. skip
2. auto
EOF
read -r -e -p "Choose the conflict mode: " CFC
if [ "$CFC" == 1 ]; then
CFC=skip
elif [ "$CFC" == 2 ]; then
CFC=auto
fi
}
filebotf() {
# don't run filebot if _SKIP_FILEBOT is true
[[ ${_SKIP_FILEBOT} = "true" ]] && return 0
check1="$(ls "$MOVIESRC" | wc -l)"
check2="$(ls "$TVSRC" | wc -l)"
check3="$(ls "$ANIMESRC" | wc -l)"
if [ ! "$check1" == "1" ]; then
$DFILEBOT -script fn:amc --output "$DST" --action move --q "{f.path.match(/MID([0-9]{1,8})/)}" --conflict "${_SKIP_CONFLICT_CHECK:-skip}" --def movieFormat="$MOVIEFT" "$MOVIESRC" --def clean=y ut_label=Movie subtitles=en deleteAfterExtract=y artwork=n --apply nfo -no-probe --def storeReport="$ROOT/Reports" discord="$WEBHOOK" --log-file "/data/rename.log"
fi
if [ ! "$check2" == "1" ]; then
$DFILEBOT -script fn:amc --output "$DST" --action move --q "{f.path.match(/TID([0-9]{1,8})/)}" --conflict "${_SKIP_CONFLICT_CHECK:-skip}" --def seriesFormat="$TVFT" "$TVSRC" --def seriesDB=TheMovieDB::TV clean=y ut_label=TV subtitles=en deleteAfterExtract=y artwork=n --apply nfo -no-probe --def storeReport="$ROOT/Reports" discord="$WEBHOOK" --log-file "/data/rename.log"
fi
if [ ! "$check3" == "1" ]; then
$DFILEBOT -script fn:amc --output "$DST" --action move --q "{f.path.match(/TID([0-9]{1,8})/)}" --conflict "${_SKIP_CONFLICT_CHECK:-skip}" --mapper "[episode, order.absolute.episode]" -non-strict --def seriesFormat="$ANIMEFT" "$ANIMESRC" --def seriesDB=TheMovieDB::TV clean=y ut_label=TV minFileSize=0 minLengthMS=0 deleteAfterExtract=y artwork=n --apply nfo -no-probe --def storeReport="$ROOT/Reports" discord="$WEBHOOK" --log-file "/data/rename.log"
fi
}
################################################################################################################
clear
: > "$HOME/.filebot/rename.log" &&
: > "$HOME/.filebot/fbmount.log" &&
for file in "${HOME}/.filebot/"*.sh ; do
: > "$file"
done
check="$(find "$MOVIESRC" "$TVSRC" "$ANIMESRC" -mindepth 1 -maxdepth 1 -not -empty -not -name "*.plox" -type f,d | wc -l)"
if [ ! "$check" == "0" ]; then
db_renaming && [ -s $HOME/.filebot/tmdb.sh ] && bash $HOME/.filebot/tmdb.sh && verify tmdb
subtitle && [ -s $HOME/.filebot/subtitle.sh ] && bash $HOME/.filebot/subtitle.sh && verify subtitle
filebotf
fi
check="$(find "${TVSRC}" "${ANIMESRC}" -type f \( -iname \*.mp4 -o -iname \*.mkv -o -iname \*.avi -o -iname \*.webm \) -regextype posix-extended -not -regex '.*[0-9]\s*x\s*[0-9]+.*' | wc -l)"
if [ ! "$check" == "0" ]; then
echo && echo "Unidentified Content has been found , script will now proceed to preprocess them before running filebot again"
preprocess && [ -s $HOME/.filebot/preprocess.sh ] && bash $HOME/.filebot/preprocess.sh && verify preprocess
filebotf
fi
# Deleting crap/unneeded files & Empty Folders
find "$MOVIESRC" "$TVSRC" "$ANIMESRC" -type d -empty -delete
find "$MOVIESRC" "$TVSRC" "$ANIMESRC" -maxdepth 1 -type f \( -iname \*.txt -o -iname edit -o -iname view \) -delete
# Appending non filebot logs to Reports folder
append_dest="/GD/Reports/["`date +"%Y-%m-%d %R"`"]_Manual.txt"
for file in "${HOME}/.filebot/"*.sh ; do
{ [[ -f ${file} ]] && [[ -s ${file} ]] ;} || continue
echo >> "$append_dest" && echo "$file" >> "$append_dest"
echo >> "$append_dest" && cat "$file" >> "$append_dest"
echo >> "$append_dest" && printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - >> "$append_dest"
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment