1
0
Fork 0
mirror of https://github.com/Jonny007-MKD/OTR-SaneRename synced 2024-05-08 21:54:04 +02:00
OTR-SaneRename/saneRenamix.sh

514 lines
16 KiB
Bash
Raw Normal View History

#!/bin/bash
2014-09-11 17:36:43 +02:00
### Exit codes:
# 1 : General error (invalid argument option, missing parameter)
# 2 : Specified language not recognized
# 3 : Aborted (Ctrl+C)
# 10 : Series not found in TvDB
# 11 : Series not found in EPG
2014-09-11 17:36:43 +02:00
# 12 : Several possible series found
# 20 : No info for this episode found
# 21 : No episode title found in EPG
# 40 : Downloading EPG data failed
# 41 : Downloading list of episodes from TvDB failed
2014-07-27 02:59:45 +02:00
2014-09-11 17:36:43 +02:00
### What this program does
# Analyze the file name
# Ask TvDB or cache for the ID of the series
# Get EPG from OTR
# Search the episode title in EPG
# Get a list of all episodes from TvDB
# Search the episode in this list
# Print file name with episode and series number
##########
# Config #
##########
2014-07-27 02:59:45 +02:00
apikey="2C9BB45EFB08AD3B"
2014-09-11 17:36:43 +02:00
productname="SaneRename for OTR (ALPHA) v0.3"
lang="de"
2014-07-27 02:59:45 +02:00
##########
# Script #
##########
# Print only of not silent
2014-07-27 19:48:56 +02:00
function eecho {
if [ -z "$silent" ]; then
echo "$1" "$2" "$3"
fi
}
2014-08-19 00:28:38 +02:00
function logNexit {
2014-09-04 14:09:02 +02:00
str="$1 - $file_name - $series_title"
if ! grep -q "$str" "$PwD/log" ; then
echo "$str" >> "$PwD/log"
fi
2014-08-19 00:28:38 +02:00
exit $1
}
# trap ctrl-c and call ctrl_c()
trap ctrl_c INT
function ctrl_c() {
if $wget_running; then
rm -f $wget_file
fi
exit 3
}
wget_running=false;
# Parse the parameters
function funcParam {
while getopts "f:l:s" optval; do
case $optval in
"f") # Path to file
path="$OPTARG";;
"s") # Silent switch
silent=1;;
"l") # Language
case "$OPTARG" in
de*)
lang="de";;
en*)
lang="en";;
us*)
lang="en";;
fr*)
lang="fr";;
*)
echo "Language not recognized: $OPTARG"
exit 2;;
esac;;
"?") # Help
echo "Usage: $0 -f pathToAvi [-s] [-l LANG]"
exit;;
":")
echo "No argument value for option $OPTARG"
exit 1;;
esac
done
}
# Print the header
function funcHeader {
eecho " :: $productname"
eecho " :: by Leroy Foerster"
eecho
}
# Get title, date and time
function funcAnalyzeFilename {
# Split filename into words, divided by _ (underscores)
file="${file_name//_/ }"
firstField="${file%% *}" # Get the first word
test $firstField -eq 0 2>/dev/null # If first word is a number -> cutlist id
if [ $? -ne 2 ]; then
file=${file##$firstField } # remove it
fi
file_title=${file%% [0-9][0-9].*} # Cut off everything after the title: date, hour, sender, ...
file_sender=${file##*-[0-9][0-9]} # Cut off everything bevor the sender: title, date, time, ...
file_date=${file%%$file_sender} # Cut off the sender
file_date=${file_date##$file_title } # Cut off the title, now we do have the date and time
file_time=${file_date##* }
file_date=${file_date%% *}
file_dateInv=$(date +%d.%m.%Y --date="${file_date//./-}") # Convert YY.MM.DD to DD.MM.YY
2014-09-11 17:36:43 +02:00
file_time=${file_time/-/:} # Convert HH-MM to HH:MM
eecho -e " Work dir:\t$PwD"
eecho -e " Datum:\t$file_dateInv"
eecho -e " Uhrzeit:\t$file_time"
2014-09-11 17:36:43 +02:00
funcConvertName "$file_title"
eecho -e " Titel:\t$tmp"
}
function funcConvertName {
tmp="$1"
tmp=${tmp// s /\'s } # Replace a single s with 's
if [ "$lang" == "de" ]; then
tmp=${tmp//Ae/Ä} # Replace umlauts
tmp=${tmp//Oe/Ö}
tmp=${tmp//Ue/Ü}
tmp=${tmp//ae/ä}
tmp=${tmp//oe/ö}
tmp=${tmp//ue/ü}
fi
}
# Get the series ID from TvDB (needed to fetch episodes from TvDB)
function funcGetSeriesId {
local tmp;
if [ -f "$PwD/series.cache" ]; then # Search the series cache
2014-09-19 22:14:36 +02:00
funcGetSeriesIdFromCache "$file_title"
fi
if [ -z "$series_id" ]; then # Otherwise search the cache with translation
funcConvertName "$file_title"
funcGetSeriesIdFromCache "$tmp"
fi
if [ -z "$series_id" ]; then # Otherwise ask TvDB whether they do know the series
2014-09-19 21:54:42 +02:00
funcGetSeriesIdFromTvdb "$file_title"
fi
2014-09-19 22:14:36 +02:00
if [ -z "$series_id" ]; then # Otherwise ask TvDB with translation
2014-09-19 21:54:42 +02:00
funcGetSeriesIdFromTvdb "$tmp"
fi
if [ -z "$series_id" ]; then # This series was not found anywhere :(
eecho -e " TVDB:\tSeries not found!"
2014-08-19 00:28:38 +02:00
logNexit 10
fi
if [ -n "$series_alias" ]; then
eecho -e "\t\t\t\tAlias: $series_alias"
fi
}
# Search the series.cache file for this series and get TvDB series id
function funcGetSeriesIdFromCache {
local title;
local tmp;
2014-09-19 22:14:36 +02:00
title="$1";
while true; do
2014-09-19 22:14:36 +02:00
series_id="$(grep "$title|" "$PwD/series.cache")" # Search for this title in the cache
if [ -n "$series_id" ]; then # Stop if we have found something
2014-09-11 17:36:43 +02:00
series_title_file="${series_id%|_|*}"
series_title_tvdb="${series_id#*|_|}"
series_title_tvdb="${series_title_tvdb%|#|*}"
series_id="${series_id##*|#|}"
eecho -e " Cache:\tSeries found.\tID:\t$series_id"
2014-09-11 17:36:43 +02:00
eecho -e " \t \tName:\t$series_title_tvdb"
break;
fi
tmp="${title% *}" # Shorten the title by one word
if [ ${#tmp} -le 4 ] || [ "$tmp" == "$title" ]; then # Too short or was not shortened
break;
fi
title="$(echo $tmp | sed -e 's/^[^a-zA-Z0-9]*//' -e 's/ *$//')"
done
}
# Search the TvDB for this series and get TvDB series id
function funcGetSeriesIdFromTvdb {
local title;
local tmp;
2014-09-19 21:54:42 +02:00
title="$1";
while true; do
series_db="https://www.thetvdb.com/api/GetSeries.php?seriesname=${title}&language=$lang"
wget_file="$PwD/series.xml"
wget_running=true;
wget "$series_db" -O "$wget_file" -o /dev/null
wget_running=false;
error=$?
if [ $error -ne 0 ]; then
2014-08-19 00:28:38 +02:00
eecho -e "\t\t\tDownloading $series_db failed \(Exit code: $error\)!"
fi
2014-09-11 17:36:43 +02:00
tmp="$(grep -i -m 1 -B 3 -A 1 ">$title<" "$wget_file")"
if [ ${#tmp} -eq 0 ]; then # No series with this name found
tmp="$(grep "<SeriesName>" "$wget_file")" # Let's get all series from the query
if [ $(echo "$tmp" | wc -l) -eq 1 ]; then # If we only found one series
tmp="$(grep -B 3 -A 1 "<SeriesName>" "$wget_file")" # Lets use this one
else
2014-08-19 00:28:38 +02:00
eecho -e " TvDB: $(echo "$tmp" | wc -l) series found with this title \($title\)"
2014-09-11 17:36:43 +02:00
logNexit 12
fi
fi
if [ -n "$tmp" ]; then
series_id=$(echo "$tmp" | grep "seriesid>")
2014-09-11 17:36:43 +02:00
series_title_file="$file_title"
series_title_tvdb=$(echo "$tmp" | grep "SeriesName>") # Get series name from TvDB
series_alias=$(echo "$tmp" | grep "AliasNames>")
series_id=${series_id%<*} # Remove XML tags
series_id=${series_id#*>}
2014-09-11 17:36:43 +02:00
series_title_tvdb=${series_title_tvdb%<*}
series_title_tvdb=${series_title_tvdb#*>}
series_alias=${series_alias%<*}
series_alias=${series_alias#*>}
2014-09-11 17:36:43 +02:00
echo "$title|_|$series_title_tvdb|#|$series_id" >> "$PwD/series.cache"
eecho -e " TVDB:\tSeries found.\tID: $series_id"
2014-09-11 17:36:43 +02:00
eecho -e " \t \tName: $series_title_tvdb"
break
fi
tmp="${title% *}" # Shorten the title by one word
if [ ${#tmp} -le 4 ] || [ "$tmp" == "$title" ]; then # Too short or was not shortened
break;
fi
title="$(echo $tmp | sed -e 's/^[^a-zA-Z0-9]*//' -e 's/ *$//')"
done
}
# Get the EPG from OnlineTvRecorder and get the title of the episode
function funcGetEPG {
# Download OTR EPG data and search for series and time
wget_file="$PwD/epg-${file_date}.csv"
2014-10-15 15:08:25 +02:00
if [ -f "$wget_file" ]; then
wget_file_date=$(stat --format=%Y "$wget_file")
if [ $(( $(date +%s) - $wget_file_date)) -gt $((60*60*24*7*2)) ]; then # if file is older than 2 weeks
rm "$wget_file"
fi
fi
if [ ! -f "$wget_file" ]; then # This EPG file does not exist
#rm -f ${PwD// /\\ }/epg-*.csv 2> /dev/null # Delete all old files
epg_csv="https://www.onlinetvrecorder.com/epg/csv/epg_20${file_date//./_}.csv"
wget_running=true;
wget "$epg_csv" -O "$wget_file" -o /dev/null # Download the csv
wget_running=false;
error=$?
if [ $error -ne 0 ]; then
eecho "Downloading $epg_csv failed (Exit code: $error)!"
2014-08-19 00:28:38 +02:00
logNexit 40
fi
iconv -f LATIN1 -t utf8 "$wget_file" -o "${wget_file}.iconv"
mv "${wget_file}.iconv" "$wget_file"
fi
epg="$(grep -i "$series_title_file" "$wget_file" | grep "${file_time}")" # Get the line with the movie
if [ -z "$epg" ]; then
2014-09-11 17:36:43 +02:00
funcConvertName "$series_title_file"
epg="$(grep -i "$tmp" "$wget_file" | grep "${file_time}")" # Get the line with the movie
2014-09-11 17:36:43 +02:00
if [ -z "$epg" ]; then
epg="$(grep -i "$series_title_tvdb" "$wget_file" | grep "${file_time}")" # Get the line with the movie
2014-09-11 17:36:43 +02:00
if [ -z "$epg" ]; then
eecho -e " EPG:\tSeries \"$series_title_file\" not found in EPG data" # This cannot happen :)
logNexit 11
fi
fi
fi
# Parse EPG data using read
OLDIFS=$IF
IFS=";"
while read epg_id epg_start epg_end epg_duration epg_sender epg_title epg_type epg_text epg_genre epg_fsk epg_language epg_weekday epg_additional epg_rpt epg_downloadlink epg_infolink epg_programlink; do
if [[ "$epg_start" == *$file_time* ]]; then # Use the one with the correct start time
break
fi
done <<< "$epg"
IFS=$OLDIFS
}
# Get the title of the episode from description in EPG using $1 as delimiter to the real description
function funcGetEpgEpisodeTitle {
2014-09-11 17:36:43 +02:00
local delimiter;
delimiter="$1"
episode_title="${epg_text%%$delimiter*}" # Text begins with episode title, cut off the rest
episode_title="${episode_title#$series_title_file}" # Get the title without the series title
episode_title="$(echo ${episode_title#$series_title_tvdb} | sed -e 's/^[^a-zA-Z0-9]*//' -e 's/ *$//')" # Get the title without the series title
if [ -z "$episode_title" ]; then
2014-10-26 14:00:44 +01:00
eecho -e " EPG:\tNo episode title found"
else
2014-10-26 14:00:44 +01:00
episode_title="$(echo $episode_title | sed -e 's/^[^a-zA-Z0-9]*//' -e 's/ *$//')"
eecho -e " EPG:\tEpisode title:\t$episode_title" # We found some title :)
fi
}
2014-09-11 17:36:43 +02:00
# Download episodes list from TvDB, language as argument
function funcGetEpisodes {
wget_file="$PwD/episodes-${series_id}.xml"
2014-10-15 15:08:25 +02:00
if [ -f "$wget_file" ]; then
wget_file_date=$(stat --format=%Y "$wget_file")
if [ $(( $(date +%s) - $wget_file_date)) -gt $(( 60*60*24*7*2 )) ]; then # if file is older than 2 weeks
rm "$wget_file"
fi
fi
if [ ! -f "$wget_file" ]; then
# Download Episode list of series
episode_db="https://www.thetvdb.com/api/$apikey/series/$series_id/all/$1.xml"
wget_running=true;
wget $episode_db -O "$wget_file" -o /dev/null
wget_running=false;
error=$?
if [ $error -ne 0 ]; then
eecho "Downloading $episode_db failed (Exit code: $error)!"
2014-08-19 00:28:38 +02:00
logNexit 41
fi
2014-07-27 02:59:45 +02:00
fi
}
2014-07-29 18:21:22 +02:00
# Get the information from episodes list of TvDB
function funcGetEpisodeInfo {
local tmp;
local title;
2014-09-11 17:36:43 +02:00
local title1;
title="$episode_title" # Use coded version of episode title
funcConvertName "$episode_title"
if [ "$episode_title" != "$tmp" ]; then # Save state to change to decoded version later
title1=true;
else
title1=false;
fi
wget_file="$PwD/episodes-${series_id}.xml"
while true; do
episode_info=$(grep -i "sodeName>$title" "$wget_file" -B 10) # Get XML data of episode
if [ -z "$episode_info" ]; then # Nothing found. Search the description
if [ ${#title} -gt 10 ]; then # If title is long enough
episode_info=$(grep -i "verView>$title" "$wget_file" -B 16)
fi
if [ -z "$episode_info" ]; then # Still nothing found. Shorten the title
tmp=${title% *}
if [ ${#tmp} -le 4 ] || [ "$tmp" == "$title" ]; then
if $title1; then
funcConvertName "$episode_title"
title1=false;
else
break;
fi
2014-09-11 17:36:43 +02:00
fi
else
break;
fi
title="$(echo $tmp | sed -e 's/^[^a-zA-Z0-9]*//' -e 's/ *$//')" # Remove special characters
eecho -e " \tEpisode title:\t$title"
else
2014-07-29 11:33:39 +02:00
break;
fi
done
2014-09-11 17:36:43 +02:00
if [ -z "$episode_info" ]; then # If we have not found anything
tmp="${episode_title%% *}" # Get the first word
title="${episode_title#$tmp }" # Remove it from the title
eecho -e " \tEpisode title:\t$title"
episode_info=$(grep -i "sodeName>$title" "$wget_file" -B 10) # Get XML data of episode
if [ -z "$episode_info" ]; then # Nothing found. Search the description
if [ ${#title} -gt 10 ]; then # If title is long enough
episode_info=$(grep -i "verView>$title" "$wget_file" -B 16)
fi
fi
fi
if [ -n "$episode_info" ]; then # If we have found something
episode_number=$(echo -e "$episode_info" | grep -m 1 "Combined_episodenumber") # Get episode number
episode_season=$(echo -e "$episode_info" | grep -m 1 "Combined_season") # Get season number
episode_title=$(echo -e "$episode_info" | grep -m 1 "EpisodeName") # Get season name
episode_number=${episode_number%<*} # remove xml tags
episode_number=${episode_number#*>}
episode_season=${episode_season%<*}
episode_season=${episode_season#*>}
episode_title=${episode_title%<*}
episode_title=${episode_title#*>}
if [[ "$episode_number" == *.* ]]; then # Convert float to integer. Float!?
episode_number=${episode_number%%.*}
fi
if [[ "$episode_season" == *.* ]]; then
episode_season=${episode_number%%.*}
fi
if [ $episode_number -le 9 ]; then # add leading zero
episode_number="0$episode_number"
fi
if [ $episode_season -le 9 ]; then
episode_season="0$episode_season"
fi
eecho -e " TvDB:\tSeason: \t$episode_season"
eecho -e " \tEpisode:\t$episode_number"
fi
}
function funcMakeFilename {
if [ "$lang" == "de" ]; then
episode_title=${episode_title//Ä/Ae} # Replace umlauts
episode_title=${episode_title//Ö/Oe}
episode_title=${episode_title//Ü/Ue}
episode_title=${episode_title//ä/ae}
episode_title=${episode_title//ö/oe}
episode_title=${episode_title//ü/ue}
fi
2014-09-11 17:36:43 +02:00
echo "${series_title_tvdb// /.}..S${episode_season}E${episode_number}..${episode_title// /.}.$file_suffix"
}
2014-07-29 18:21:22 +02:00
# This function does everything
function doIt {
funcHeader
if [ -z "$path" ]; then # If no path was specified (-f)
echo "Usage: $0 -f pathToAvi [-s] [-l LANG]"
exit 1
fi
PwD=$(readlink -e $0) # Get the path to this script
PwD=$(dirname "$PwD")
file_name="$(basename $path)" # Get file name
file_suffix="${file_name##*.}" # Get file suffix
file_dir="$(dirname $path)" # Get file directory
funcAnalyzeFilename # Get info from $file_name
funcGetSeriesId # Get series ID from cache or TvDB
2014-09-11 17:36:43 +02:00
funcConvertName "$file_title"
if [ "$tmp" != "$series_title_tvdb" ]; then # Title in file is not series title. This mey mean the episode title is also in the file title
episode_title="${file_title#$series_title_file }"
funcConvertName "$series_title_file"
episode_title="${episode_title#$tmp }"
episode_title="${episode_title#$series_title_tvdb }"
episode_title="${episode_title#$series_alias }"
eecho -e " \t\tEpisode title:\t$episode_title"
episode_title_set=true # used in doItEpisodes (whether the episode title shall be search in epg)
else # Otherwise search the episode title in the EPG:
funcGetEPG # Download epg file
episode_title_set=false
fi
2014-07-29 18:53:03 +02:00
doItEpisodes $lang # Search for the episode in the specified language
if [ -z "$episode_info" ]; then # Episode was not found!
if [ "$lang" != "en" ]; then
doItEpisodes "en" # Try it again with english
fi
fi
if $episode_title_set && [ -z "$episode_info" ]; then # Episode was not found!
episode_title_set=false # Do not use file name as episode title
funcGetEPG # Download epg file
doItEpisodes $lang # Search for the episode in the specified language and get title from EPG
if [ -z "$episode_info" ]; then # Episode was not found!
if [ "$lang" != "en" ]; then
doItEpisodes "en" # Try it again with english
fi
if [ -z "$episode_info" ]; then # Again/still no info found! Damn :(
2014-09-11 17:36:43 +02:00
eecho "No episode info found!"
2014-08-19 00:28:38 +02:00
logNexit 20
fi
2014-07-29 18:53:03 +02:00
fi
fi
2014-09-11 17:36:43 +02:00
if [ -n "$episode_info" ] && [ -n "$series_title_tvdb" ]; then
funcMakeFilename
2014-08-19 00:40:28 +02:00
exit 0
2014-07-29 18:53:03 +02:00
fi
}
# Parse the episodes, language as argument
function doItEpisodes {
if ! $episode_title_set; then
funcGetEpgEpisodeTitle "." # Get the episode title using . as delimiter
fi
2014-07-29 18:53:03 +02:00
funcGetEpisodes $1 # Download episodes file
if [ -n "$episode_title" ]; then
funcGetEpisodeInfo
fi
if [ -z "$episode_info" ] && ! $episode_title_set; then # No info found and delimiter , is possible:
funcGetEpgEpisodeTitle "," # Try again with , as delimiter
if [ -n "episode_title" ]; then # If we have got an episode title
funcGetEpisodeInfo
else
eecho -e " EPG:\tNo episode title found in EPG!"
2014-08-19 00:28:38 +02:00
logNexit 21
fi
fi
}
funcParam $@
2014-07-29 18:21:22 +02:00
doIt
2014-08-19 00:28:38 +02:00
logNexit 20