Skip to content

Instantly share code, notes, and snippets.

@blooalien
Forked from diazona/rip-tvnamer.py
Created March 4, 2022 21:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save blooalien/4d87ac3d4a394fc0b206d06e74a3657f to your computer and use it in GitHub Desktop.
Save blooalien/4d87ac3d4a394fc0b206d06e74a3657f to your computer and use it in GitHub Desktop.
#!/usr/bin/python3
'''A script that reads episode filenames from standard input, one per line,
and prints out the corresponding filenames in a standard format on standard
output, one per line. The tvnamer Python library is used to generate the
new filenames, and TheTVDB is used to access episode titles. So this does
basically the same thing as tvnamer, except that instead of actually
renaming files, it just transforms filenames.'''
import os.path, sys, json
from tvdb_api import Tvdb
from tvnamer.tvnamer_exceptions import BaseTvnamerException, DataRetrievalError
from tvnamer.utils import Config, FileParser, split_extension
def read_config(cfg_filename, dry=False, verbose=False):
Config.update({
'search_all_languages': False,
'language': 'en',
'batch': True,
'dry-run': dry,
'verbose': verbose,
'episode_separator': '-',
'episode_single': 'e%02d',
'multiep_format': '%(epname)s (%(episodemin)s-%(episodemax)s)',
'filename_anime_with_episode': '%(seriesname)s - %(episode)s - %(episodename)s%(ext)s',
'filename_anime_with_episode_without_crc': '%(seriesname)s - %(episode)s - %(episodename)s%(ext)s',
'filename_anime_without_episode': '%(seriesname)s - %(episode)s%(ext)s',
'filename_anime_without_episode_without_crc': '%(seriesname)s - %(episode)s%(ext)s',
'filename_with_date_and_episode': '%(seriesname)s - %(year)04d-%(month)02d-%(day)02d - %(episodename)s%(ext)s',
'filename_with_date_without_episode': '%(seriesname)s - %(year)04d-%(month)02d-%(day)02d%(ext)s',
'filename_with_episode': '%(seriesname)s - s%(seasonnumber)02d%(episode)s - %(episodename)s%(ext)s',
'filename_with_episode_no_season': '%(seriesname)s - s00%(episode)s - %(episodename)s%(ext)s',
'filename_without_episode': '%(seriesname)s - %(seasonnumber)02d%(episode)s%(ext)s',
'filename_without_episode_no_season': '%(seriesname)s - s00%(episode)s%(ext)s',
})
try:
with open(cfg_filename) as f:
Config.update(json.load(f))
except FileNotFoundError:
pass
def new_name(filename):
ep = FileParser(filename).parse()
ep.populateFromTvdb(Tvdb(interactive=False, search_all_languages=False, language=Config['language'], dvdorder=True, cache=True))
return os.path.join(os.path.dirname(filename), ep.generateFilename())
def main():
try:
read_config(sys.argv[1], bool(sys.argv[2]), bool(sys.argv[3]))
except Exception:
sys.exit(1)
try:
for line in sys.stdin:
try:
print(new_name(line.rstrip('\n')))
except (BaseTvnamerException, OSError):
if Config['skip_file_on_error'] or Config['skip_behaviour'] == 'exit':
sys.exit(1)
else:
print(line)
except Exception:
sys.exit(1)
except KeyboardInterrupt:
pass
if __name__ == '__main__':
main()
#!/bin/bash
SCRIPT="$(realpath $0)"
COLOR_NC='\033[00m' # No Color
COLOR_WHITE='\033[01;37m'
COLOR_BLACK='\033[00;30m'
COLOR_BLUE='\033[00;34m'
COLOR_LIGHT_BLUE='\033[01;34m'
COLOR_GREEN='\033[00;32m'
COLOR_LIGHT_GREEN='\033[01;32m'
COLOR_CYAN='\033[00;36m'
COLOR_LIGHT_CYAN='\033[01;36m'
COLOR_RED='\033[00;31m'
COLOR_LIGHT_RED='\033[01;31m'
COLOR_PURPLE='\033[00;35m'
COLOR_LIGHT_PURPLE='\033[01;35m'
COLOR_BROWN='\033[00;33m'
COLOR_YELLOW='\033[01;33m'
COLOR_GRAY='\033[00;30m'
COLOR_LIGHT_GRAY='\033[00;37m'
COLOR_BOLD=$(tput bold) # not really a "color" but close enough
COLOR_RESET=$(tput sgr0)
TERM_TITLE='\033]2;'
END_TERM_TITLE='\007'
RESET_TERM_TITLE='\e]0;\a'
HOSTNAME="$(hostname)"
NEWLINE=$'\n'
RIP_ROOT_DIR="$HOME/tmp/rips"
RIP_TVNAMER="$(dirname "$SCRIPT")/rip-tvnamer.py"
RIP_TVNAMER_CONF="$(dirname "$SCRIPT")/rip-tvnamer.json"
source_conf() {
[ -f "$1" ] && source "$1"
}
source_conf ./rip.conf
source_conf "$HOME/.config/rip.conf"
source_conf "$(dirname "$0")/rip.conf"
usage() {
local usage_str
case "$mode" in
movie)
usage_str="Usage in movie mode: $progname 'title (year)' [dvdtitlespec] or $progname title [year [dvdtitlespec]]"
;;
tv)
usage_str="Usage in tv mode: $progname seriestitle season dvdtitlespecs..."
;;
*)
usage_str="Usage:
(tv) $progname seriestitle season dvdtitlespecs...
(movie) $progname 'title (year)' [dvdtitlespec]
(movie) $progname title year [dvdtitlespec]"
;;
esac
die "$usage_str"
}
stripcolors() {
sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g;s/\\\\033.{1,6}m//g"
}
log() {
local label="${1}"
shift
stripcolors <<< "[$label] $@" >> rip.log
return 0
}
die() {
echo -e "${COLOR_RED}${COLOR_BOLD}$@${COLOR_RESET}" >&2
log "die" "$@"
exit 1
}
logecho() {
echo -e "$@"
log "echo" "$@"
}
logdebug() {
[ -n "$debug" ] && log "debug" "$@"
return 0
}
notify_text() {
shift
curl --silent http://textbelt.com/text -d "number=$PHONE_NUMBER" -d "message=$* on $HOSTNAME" >>rip.log
echo >>rip.log
}
notify_pushbullet() {
local notification_title="$1"
shift
curl --silent --header "Access-Token: $PUSHBULLET_ACCESS_TOKEN" -X POST https://api.pushbullet.com/v2/pushes --header 'Content-Type: application/json' --data-binary "{\"type\": \"note\", \"title\": \"$notification_title\", \"body\": \"$* on $HOSTNAME\"}" >>rip.log
echo >>rip.log
}
notify_kdialog() {
local notification_title="$1"
shift
kdialog --passivepopup "$*" 4 --title "$notification_title"
}
mark_start() {
logecho "${COLOR_YELLOW}Starting at $(date)${COLOR_RESET}"
}
mark_stop() {
logecho "${COLOR_YELLOW}Ending at $(date)${COLOR_RESET}"
}
get_free_megabytes() {
local dfdir="$1"
until [ -f "$dfdir" -o -d "$dfdir" ]; do
dfdir="$(dirname "$dfdir")"
done
df --block-size=1M "$dfdir"
}
get_length() {
duration="$(ffprobe -show_entries format=duration -v error -of default=noprint_wrappers=1:nokey=1 -sexagesimal "$1")"
[[ "$duration" =~ ^([0-9]+):([0-5][0-9]):([0-5][0-9]\.[0-9]+)$ ]]
hours="${BASH_REMATCH[1]}"
minutes="${BASH_REMATCH[2]}"
seconds="${BASH_REMATCH[3]}"
if [[ "$hours" -gt 0 ]]; then
echo "${hours}h ${minutes}m"
else
echo "${minutes}m"
fi
}
output_check() {
local outdir="$(dirname "$outfile")"
# ensure that output directory exists
if [[ ! -d "$outdir" ]]; then
if [ -z "$dry" ]; then
logecho "Creating output directory $outdir"
mkdir -p "$outdir" || die "Failed to create output directory $outdir"
else
logecho "Not creating output directory $outdir (dry run)"
fi
fi
# print a warning if filesystem is running low on space
local dfoutput="$(get_free_megabytes "$outdir")"
local freespace="$(awk 'NR==2 {print $4}' <<<"$dfoutput")"
local mountpoint="$(awk 'NR==2 {print $1}' <<<"$dfoutput")"
if (( $freespace < 1500 )); then # allow 1.5G per disc
die "insufficient free space on partition $mountpoint"
elif (( $freespace < 3000 )); then
logecho "${COLOR_RED}${COLOR_BOLD}WARNING: ${COLOR_RED}free space on partition $mountpoint is almost exhausted${COLOR_RESET}"
elif (( $freespace < 6000 )); then
logecho "${COLOR_YELLOW}${COLOR_BOLD}WARNING: ${COLOR_YELLOW}free space on partition $mountpoint is getting low${COLOR_RESET}"
fi
}
set_terminal_title() {
echo -n -e "${TERM_TITLE}$(stripcolors <<< "$*")${END_TERM_TITLE}"
}
reset_terminal_title() {
# not sure if this really works...
# http://superuser.com/questions/339862/restore-mac-os-x-terminal-title-after-closing-a-ssh-connection
echo -n -e "${RESET_TERM_TITLE}"
}
# expects newline-separated numbers on stdin
# not guaranteed to work for negative inputs
# http://stackoverflow.com/questions/13708705/in-bash-how-to-convert-number-list-into-ranges-of-numbers
list_to_ranges() {
local num
while read num || [ -n "$last" ]; do
[ -n "$num" ] && let num="10#$num"
if [ -z "$last" ]; then
first="$num"
last="$num"
continue
fi
if [[ "$num" -eq "$(($last+1))" ]]; then
let last++
else
if [[ "$first" -eq "$last" ]]; then
echo "$first"
else
echo "$first-$last"
fi
first="$num"
last="$num"
fi
done
}
select_cpus() {
seq "$(grep -c processor /proc/cpuinfo)" | shuf -n "$1" | tr '\n' ',' | head -c -1
}
send_notifications() {
for m in $(<<< "$notification_modes" tr ' ' '\n' | sort -u); do # outer non-quoting here is intentional
notify_$m "Rip complete" "$notification_message"
done
}
run_handbrake() {
output_check
local cmdline=""
[ -n "$ncpus" ] && cmdline+="taskset -c '$(select_cpus $ncpus)' "
cmdline+="HandBrakeCLI --preset 'Normal' ${handbrake_opts} "
if [ "$title" == "0" ]; then
cmdline+="--main-feature "
else
cmdline+="--title '$title' "
fi
[ -n "$chapters" -a "$chapters" != "-" ] && cmdline+="--chapters ${chapters} "
cmdline+="-i '$device' -o \"${outfile}\"" # hopefully there are no double quotes or backslashes in $outfile
log "command" "$cmdline"
if [ -n "$dry" ]; then
echo "$cmdline"
logecho "Rip successful (dry run)"
else
eval "$cmdline" </dev/null 2>>rip.log || die "Ripping ${display_output} failed"
logecho "Rip successful: generated length ${COLOR_CYAN}${COLOR_BOLD}$(get_length "${outfile}")${COLOR_RESET}"
fi
}
search_year_omdb() {
local name="$1"
r="$(curl --silent 'http://www.omdbapi.com/' -G --data-urlencode "s=$name" --data-urlencode "apikey=$OMDB_APIKEY" | jq -re "select(.Search | .[].Title == \"$name\") | .Search | .[].Year")" || die "Movie lookup failed (OMDB API)"
echo "$r"
}
search_year_themoviedb() {
die "TheMovieDB not enabled"
}
search_year_theimdbapi() {
local name="$1"
r="$(curl --silent 'http://theimdbapi.org/api/find/movie' -G --data-urlencode "title=$name" | jq -re "select(.[].title == \"$name\") | .[].year")" || die "Movie lookup failed (The IMDB API)"
echo "$r"
}
rip_movie() {
local name="$1"
shift
if [[ "$name" =~ \([12][0-9]{3}\)$ ]]; then
year="${name: -5:4}"
name="${name%%*([[:space:]])\(????\)}"
elif [[ "$1" =~ ^[12][0-9]{3}$ ]]; then
year="$1"
shift
else
# get year from IMDB
local years
years="$(search_year_omdb "$name")"
case "${#years}" in
4)
year="$years" ;;
0)
die "Movie title '$name' not recognized" ;;
*)
echo "Select year:"
select year in $years; do
[ -n "$year" ] && break
done ;;
esac
fi
case "$#" in
0)
title="0"
;;
1)
# parses something of the form
# title
# title:chapter-chapter
# :chapter-chapter
logdebug "parsing title spec $1"
if [[ "$1" =~ ^[0-9]*:[0-9]+(-[0-9]+)?$ ]]; then
title="${1%:*}"
chapters="${1#*:}"
elif [[ "$1" =~ ^[0-9]+$ ]]; then
title="$1"
else
die "Invalid title/chapter spec: '$1'"
fi
;;
*)
usage
;;
esac
outfile="${RIP_ROOT_DIR}/movies/${name//:/} ($year).m4v" # colon is a common character in movie titles that is not allowed in NTFS filenames
[[ -f "$outfile" ]] && die "Not ripping existing file $outfile"
display_output="${COLOR_LIGHT_CYAN}$name ${COLOR_LIGHT_PURPLE}($year)"
set_terminal_title "Ripping $display_output"
if [ "$title" == "0" ]; then
display_title="main title"
else
display_title="title ${title}"
fi
logecho "${COLOR_BOLD}Ripping ${display_output} ${COLOR_WHITE}from ${display_title} to ${outfile}...${COLOR_RESET}"
run_handbrake
notification_message="Finished ripping $name ($year)"
}
# parses something of the form
# title
# title:chapter-chapter
# title[episode]
# title:chapter-chapter[episode]
# title[episode-episode]
# title:chapter-chapter[episode-episode]
# title-title
# title-title/increment
# title[episode]-title
# title[episode]-title/increment
# or a comma-separated sequence of the above
parse_titlespecs_tv() {
local title chapters first_episode last_episode first last step
for a in ${@//,/ }; do # don't use double quotes here so that comma-separated specs get interpreted as different words after the replacement
logdebug "title spec $a"
if [[ "$a" =~ ^([0-9]+)(:([0-9]+(-[0-9]+)?))?(\[([0-9]+)(-([0-9]+))?\])?$ ]]; then
title="${BASH_REMATCH[1]}"
chapters="${BASH_REMATCH[3]}"
first_episode="${BASH_REMATCH[6]}"
last_episode="${BASH_REMATCH[8]}"
(( 10#$title == 0 )) && die "Invalid title/chapter spec: '$a'"
echo "$title" "${chapters:=-}" "$first_episode" "$last_episode"
elif [[ "$a" =~ ^[0-9]+$ ]]; then
(( $a == 0 )) && die "Invalid title/chapter spec: '$a'"
echo "$a"
elif [[ "$a" =~ ^([0-9]+)-([0-9]+)(/([0-9]+))?$ ]]; then
first="${BASH_REMATCH[1]}"
last="${BASH_REMATCH[2]}"
step="${BASH_REMATCH[4]}"
(( 10#$first == 0 || 10#$last < 10#$first || 10#${step:-1} == 0 )) && die "Invalid title/chapter spec: '$a'"
# non-quoting of $step here is intentional; if it's empty, seq thinks it's only getting two arguments
seq "$first" $step "$last"
elif [[ "$a" =~ ^([0-9]+)\[([0-9]+)\]-([0-9]+)(/([0-9]+))?$ ]]; then
first="${BASH_REMATCH[1]}"
last="${BASH_REMATCH[3]}"
step="${BASH_REMATCH[5]}"
first_episode="${BASH_REMATCH[2]}"
[ -z "$first_episode" ] && first_episode="$starting_episode"
(( 10#$first == 0 || 10#$last < 10#$first || 10#${step:-1} == 0 )) && die "Invalid title/chapter spec: '$a'"
# non-quoting of $step here is intentional; if it's empty, seq thinks it's only getting two arguments
seq "$first" $step "$last" | while read n; do echo "$n" "-" $(((10#$n-10#${first})/$step+10#${first_episode})); done
else
die "Invalid title/chapter spec: '$a'"
fi
done
}
# Find a range of $1 consecutive episode numbers that are unused
# and echo the beginning of the range
find_free_episode_range() {
local episodes last_episode_in_any_file=0 range_length="$1" outdir="${2:-$PWD}" range
# Collect a newline-separated list of all the episode numbers
# among all the m4v files in $outdir
for f in "$outdir"/*.m4v; do
# If there are no m4v files in the directory, immediately echo 1 and return
# All episode numbers are free so there's no need for further checking
if ! [[ -f "$f" ]]; then
echo 1
return
fi
[[ "$(basename "$f")" =~ s[0-9]+e([0-9]+)(-e([0-9]+))?( - .+)?\.m4v$ ]]
first_episode_in_file="${BASH_REMATCH[1]}"
last_episode_in_file="${BASH_REMATCH[3]}"
let first_episode_in_file="10#$first_episode_in_file"
if [ -n "$last_episode_in_file" ]; then
let last_episode_in_file="10#$last_episode_in_file"
episodes="$episodes$NEWLINE$(seq "$first_episode_in_file" "$last_episode_in_file")"
[ "$last_episode_in_any_file" -gt "$last_episode_in_file" ] || last_episode_in_any_file="$last_episode_in_file"
else
episodes="$episodes$NEWLINE$first_episode_in_file"
[ "$last_episode_in_any_file" -gt "$first_episode_in_file" ] || last_episode_in_any_file="$first_episode_in_file"
fi
done
# Then append to that list a newline-separated sequence
# from 1 to the largest episode number
episodes="$episodes$NEWLINE$(seq $last_episode_in_any_file)"
# Sort and uniq-filter the resulting list to identify any numbers
# which only occur once - those are the numbers for which no
# episode yet exists
for range in $(sort <<<"$episodes" | uniq -u | list_to_ranges); do
# If only one free episode number is needed, return the first one
if [[ "$range_length" -eq 1 ]] && [[ "$range" =~ [0-9]+ ]]; then
echo "$range"
return
# If a range of free episode numbers is needed, check each range
# to see if it's long enough and return the first one that is
elif [[ "$range_length" -gt 1 ]] && [[ "$range" =~ [0-9]+-[0-9]+ ]]; then
if (( $range + $range_length > 0 )); then
echo "${range%%-*}"
return
fi
fi
done
# If no suitable free episode numbers were found that way, return
# one more than the largest existing episode number
echo "$((10#$last_episode_in_any_file + 1))"
}
ripexists_tv() {
local episoderangetwodigit seasontwodigit series_sanitized
# $outfile gets used again in rip_tv()
if [ -n "$last_episode" ]; then
printf -v episoderangetwodigit 'e%02d-e%02d' $first_episode $last_episode
else
printf -v episoderangetwodigit 'e%02d' $first_episode
fi
series_sanitized="${series//:/}"
if [[ "$season" =~ ^([Ss]pecials?|00?)$ ]]; then
season="0"
seasontwodigit="s00"
outfile="${RIP_ROOT_DIR}/tv/$series_sanitized/Specials/$series_sanitized - ${seasontwodigit}${episoderangetwodigit}.m4v"
else
printf -v seasontwodigit 's%02d' $season
outfile="${RIP_ROOT_DIR}/tv/$series_sanitized/Season $season/$series_sanitized - ${seasontwodigit}${episoderangetwodigit}.m4v"
fi
[ -n "$use_tvnamer" ] && tvnamer_transform_outfile
[ -f "$outfile" ]
}
# Checks the requirements for the Python script that invokes tvnamer
check_tvnamer_reqs() {
python3 - 2>/dev/null <<-EOF
import sys
try:
import json
from tvdb_api import Tvdb
from tvnamer.tvnamer_exceptions import BaseTvnamerException, DataRetrievalError
from tvnamer.utils import Config, FileParser
except ImportError:
sys.exit(1)
EOF
}
start_tvnamer() {
[ -n "$use_tvnamer" ] || return
[ -n "$tvnamer_started" ] && return
# Very important to use -u for unbuffered output
logdebug "Running tvnamer script"
log "command" "$RIP_TVNAMER" "${tvnamer_cfgfile:-$RIP_TVNAMER_CONF}" "$dry" "$debug"
coproc python3 -u "$RIP_TVNAMER" "${tvnamer_cfgfile:-$RIP_TVNAMER_CONF}" "$dry" "$debug"
tvnamer_stdout=${COPROC[0]}
tvnamer_stdin=${COPROC[1]}
tvnamer_pid=$COPROC_PID
tvnamer_started="1"
logdebug "tvnamer script started"
}
tvnamer_transform_outfile() {
[ -n "$use_tvnamer" ] || return
[ -n "$tvnamer_started" ] || die "tvnamer script not started"
echo "$outfile" >&"$tvnamer_stdin"
# 30 seconds should be more than long enough to get a response from TVDB
if ! read -t 30 -u "$tvnamer_stdout" tvdb_filename; then
logecho "Error determining new filename from TVDB"
return
fi
outfile="$tvdb_filename"
}
rip_tv() {
(( $# < 3 )) && usage
local starting_episode_option_set
[ -n "$starting_episode" ] && starting_episode_option_set=1
series="$1"
shift
season="$1"
shift
[[ "$season" =~ ^([0-9]+|[Ss]pecials?)$ ]] || usage
parsed_titlespecs="$(parse_titlespecs_tv "$@")" || exit 1
tempfile="$(mktemp)"
[ -n "$use_tvnamer" ] && start_tvnamer
trap "rm -f '$tempfile'; exit 1" SIGTERM SIGINT
while read title chapters first_episode last_episode; do
[ "$chapters" == "-" ] && chapters=
if [ -z "$first_episode" ]; then
# run this to get a dummy filename to get the right directory to put files in
use_tvnamer="" ripexists_tv
if [ -z "$starting_episode" ]; then
starting_episode="$(find_free_episode_range "$(wc -l <<<"$parsed_titlespecs" | cut -d' ' -f 1)" "$(dirname "$outfile")")"
fi
first_episode="$starting_episode"
# now run it again to get the correct output filename
ripexists_tv
else
[ -n "$starting_episode_option_set" ] && logecho "Ignoring first episode number provided through option (-e $starting_episode); starting at episode $first_episode instead"
starting_episode_option_set=
if ripexists_tv; then
logecho "Skipping existing episode $first_episode"
continue
fi
fi
if [ -n "$last_episode" ]; then
display_output="${COLOR_LIGHT_CYAN}$series ${COLOR_LIGHT_RED}S${season}${COLOR_LIGHT_GREEN}E${first_episode}-${last_episode}"
else
display_output="${COLOR_LIGHT_CYAN}$series ${COLOR_LIGHT_RED}S${season}${COLOR_LIGHT_GREEN}E${first_episode}"
last_episode="$first_episode"
fi
starting_episode="$first_episode"
set_terminal_title "Ripping $display_output"
logecho "${COLOR_BOLD}Ripping ${display_output} ${COLOR_WHITE}from title ${title} to ${outfile}...${COLOR_RESET}"
run_handbrake
seq "$first_episode" "$last_episode" >> "$tempfile"
let ++starting_episode
sleep "$delay"
logdebug "Slept for $delay seconds"
done <<< "$parsed_titlespecs" || exit 1
local plural
[ "$(wc -l $tempfile | cut -d' ' -f 1)" -gt 1 ] && plural=1
ripped_episodes="$(list_to_ranges < "$tempfile" | paste -sd ",")"
rm "$tempfile"
trap SIGTERM SIGINT
notification_message="Finished ripping $series season $season episode${plural:+s} $ripped_episodes"
}
main() {
shopt -s extglob
dry=""
debug=""
ncpus=""
device="/dev/sr0"
delay="0"
starting_episode=""
mode=""
use_tvnamer=""
notification_modes=""
handbrake_opts="--two-pass "
# option processing
processed_arguments="$(getopt --options "c:d:e:ht:nf:1" --longoptions "cpus:,device:,episode:,delay:,debug,dry-run,help,text,pushbullet,kdialog,notification:,movie,tv,mode:,no-dvdnav,one-pass,tvnamer" --name "$progname" -- "$@")"
logdebug "got arguments $processed_arguments"
eval set -- "$processed_arguments"
while true; do
case "$1" in
-h|--help)
usage
;;
--mode)
case "$2" in
"movie")
mode="movie" ;;
"tv")
mode="tv" ;;
esac
shift 2
;;
--movie)
mode="movie"
shift
;;
--tv)
mode="tv"
shift
;;
--text)
notification_modes+=" text"
shift
;;
--pushbullet)
notification_modes+=" pushbullet"
shift
;;
--kdialog)
notification_modes+=" kdialog"
shift
;;
-f|--notification)
notification_modes+=" ${2//,/ }"
shift 2
;;
--no-dvdnav)
handbrake_opts+="--no-dvdnav "
shift
;;
-1|--one-pass)
handbrake_opts="${handbrake_opts/--two-pass/}"
shift
;;
-t|--delay)
[[ "$2" =~ ^[0-9]+$ ]] && delay="$2"
shift 2
;;
-d|--device)
if [[ "$2" == "/*" ]]; then # (this is a shell glob match)
device="$2"
else
device="/dev/$2"
fi
[ -r "$device" ] || die "unreadable device $device"
shift 2
;;
-c|--cpus)
[[ "$2" =~ ^[0-9]+$ ]] && ncpus="$2"
shift 2
;;
-e|--episode)
[[ "$2" =~ ^[0-9]+$ ]] && starting_episode="$2"
shift 2
;;
--tvnamer)
check_tvnamer_reqs || die "tvnamer not available"
use_tvnamer="1"
shift
;;
--debug)
debug="1"
shift
;;
-n|--dry-run)
dry="1"
shift
;;
--)
shift
break
;;
*)
die "Error processing arguments - remaining args $@"
esac
done
# if a mode is not specified:
# if we have at least 3 arguments (series, season, title specs), we're in TV mode
# if we have only 1 or 2 arguments (name, optional title spec), we're in movie mode
if [ -z "$mode" ]; then
if (( $# < 3 )); then
mode="movie"
else
mode="tv"
fi
fi
mark_start
case "$mode" in
movie)
rip_movie "$@"
;;
tv)
rip_tv "$@"
;;
*)
die "invalid mode"
;;
esac
mark_stop
reset_terminal_title
send_notifications
}
getopt -T >/dev/null
[ "$?" == 4 ] || die "requires GNU getopt"
progname="$0"
[ "$#" -gt 0 ] || die "no arguments"
TIMEFORMAT="${COLOR_BOLD}Elapsed time: %0lE${COLOR_RESET}"
time main "$@"
exit 0
#kate: space-indent off; indent-mode normal;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment