Compare commits

..

5 Commits

Author SHA1 Message Date
ksyasuda
b272fc3994 make videos open in background in play from file 2022-02-07 03:20:29 -08:00
ksyasuda
c6d5c6a1bd make logging statements use inf function 2022-02-07 02:09:23 -08:00
ksyasuda
593b66edea remove support for playing mp3 files in play from file 2022-02-07 02:09:09 -08:00
ksyasuda
cdfe2674d7 port over the new ani-cli command-line menu code 2022-02-07 01:40:40 -08:00
ksyasuda
7d08c212fa update error handling for episode selection 2022-02-06 21:08:27 -08:00
2 changed files with 138 additions and 134 deletions

249
ani-cli
View File

@ -11,32 +11,63 @@ DPI=96
IS_ROFI=1
VERBOSE=0
SILENT=0
player_fn="mpv"
playable="\.mp4|\.mkv|\.ts|\.mp3|\.webm"
c_red="\033[1;31m"
c_green="\033[1;32m"
c_yellow="\033[1;33m"
c_blue="\033[1;34m"
c_magenta="\033[1;35m"
c_cyan="\033[1;36m"
c_reset="\033[0m"
PLAYER_FN="mpv"
die() {
((SILENT != 1)) && printf "$c_red%s$c_reset\n" "$*" >&2
((SILENT != 1)) && printf "\033[1;31m%s\033[0m\n" "$*" >&2
exit 1
}
# display an error message to stderr (in red)
err() {
((SILENT != 1)) && printf "$c_red%s$c_reset\n" "$*" >&2
((SILENT != 1)) && printf "\033[1;31m%s\033[0m\n" "$*" >&2
}
# prints passed in args to stdout if $VERBOSE is set to 1
lg() {
((VERBOSE == 1)) && printf "%s\n" "$*" >&2
((VERBOSE == 1)) && printf "\033[1;35m%s\033[0m\n" "$*" >&2
}
# display an informational message (first argument in green, second in magenta)
inf() {
printf "\033[1;32m%s \033[1;35m%s\033[0m\n" "$1" "$2"
}
# prompts the user with message in $1-2 ($1 in blue, $2 in magenta) and saves the input to the variables in $REPLY and $REPLY2
prompt() {
printf "\033[1;34m%s\033[1;35m%s\033[1;34m: \033[0m" "$1" "$2"
}
# displays an even (cyan) line of a menu line with $2 as an indicator in [] and $1 as the option
menu_line_even() {
printf "\033[1;34m[\033[1;36m%s\033[1;34m] \033[1;36m%s\033[0m\n" "$2" "$1"
}
# displays an odd (yellow) line of a menu line with $2 as an indicator in [] and $1 as the option
menu_line_odd() {
printf "\033[1;34m[\033[1;33m%s\033[1;34m] \033[1;33m%s\033[0m\n" "$2" "$1"
}
menu_line_alternate() {
menu_line_parity=${menu_line_parity:-0}
if [ "$menu_line_parity" -eq 0 ]; then
menu_line_odd "$1" "$2"
menu_line_parity=1
else
menu_line_even "$1" "$2"
menu_line_parity=0
fi
}
# displays a warning (red) line of a menu line with $2 as an indicator in [] and $1 as the option
menu_line_strong() {
printf "\033[1;34m[\033[1;31m%s\033[1;34m] \033[1;31m%s\033[0m\n" "$2" "$1"
}
check_input() {
if [[ -z "$ep_choice_start" ]] && [[ -z "$ep_choice_end" ]]; then
die "No episode(s) selected"
fi
[ "$ep_choice_start" -eq "$ep_choice_start" ] 2> /dev/null || die "Invalid number entered: $ep_choice_start"
episodes=$ep_choice_start
if [ -n "$ep_choice_end" ]; then
@ -121,7 +152,7 @@ notification() {
if command -v "notify-send" > /dev/null; then
notify-send -i "$ANIWRAPPER_ICON_PATH" "$msg"
else
lg "$msg"
inf "$msg"
fi
}
@ -176,15 +207,12 @@ update_date() {
stmt=""
case "$1" in
directory)
lg "UPDATING FILE_HISTORY for with directory: directory='$2', filename='DIRECTORY', search_date='$datetime'"
stmt="UPDATE file_history SET watch_date = '$datetime' WHERE directory = '$2' and filename = '$3';"
;;
file)
lg "UPDATING FILE_HISTORY: directory='$2', filename='$3', watch_date='$datetime'"
stmt="UPDATE file_history SET watch_date = '$datetime' WHERE directory = '$2' and filename = '$3';"
;;
search)
lg "UPDATING SEARCH_HISTORY: anime_name='$2', search_date='$datetime'"
stmt="UPDATE search_history SET search_date = '$datetime' WHERE anime_name = '$2';"
;;
sync)
@ -192,20 +220,18 @@ update_date() {
[ -z "$temp_dt" ] && return 1
hist_dt=$(run_stmt "SELECT watch_date FROM watch_history WHERE anime_name='$2' AND episode_number='$3';")
hist_dt="${hist_dt// /:}"
lg "Checking if update is needed..."
if ! check_date "$hist_dt" "$temp_dt"; then
lg "Passed in date is older or same than current date... doing nothing"
return 1
fi
lg "UPDATING WATCH_HISTORY from sync. watch_date -> $temp_dt"
stmt="UPDATE watch_history SET watch_date = '$temp_dt' WHERE anime_name = '$2' AND episode_number = $3;"
;;
watch)
lg "UPDATING WATCH_HISTORY: anime_name='$2', episode_number='$3' watch_date='$datetime'"
stmt="UPDATE watch_history SET watch_date = '$datetime' WHERE anime_name = '$2' AND episode_number = $3;"
;;
esac
wait # in case there's another insert/update still running in background?
lg "UPDATE STMT -> $stmt"
run_stmt "$stmt"
}
@ -288,30 +314,25 @@ sync_watch_history() {
### Play from file###
#####################
# opens the passed in file with $player_fn
# opens the passed in file with $PLAYER_FN
play_file() {
lg "Checking if file is playable"
if [[ "$1" =~ ($playable)$ ]]; then
if [[ "$1" =~ (\.mp4|\.mkv|\.ts|\.webm)$ ]]; then
filename="${1##*/}"
directory="${1%/*}"
insert_history "file" "$directory" "$filename" &
if [[ "$1" =~ .mp3 ]]; then
notification "Playing $1"
case "$player_fn" in
mpv)
nohup "$player_fn" --no-video "$1" > /dev/null 2>&1
;;
mplayer)
nohup "$player_fn" -novideo "$1" > /dev/null 2>&1
;;
*)
nohup "$player_fn" "$1" > /dev/null 2>&1
;;
esac
else
notification "Playing $1"
nohup "$player_fn" "$1" > /dev/null 2>&1 &
fi
notification "Playing $1"
case "$PLAYER_FN" in
mpv)
nohup "$PLAYER_FN" --force-media-title="aniwrapper: play-from-file - $1" "$1" > /dev/null 2>&1 &
;;
mplayer)
nohup "$PLAYER_FN" -title "aniwrapper: play-from-file - $1" "$1" > /dev/null 2>&1 &
;;
*)
nohup "$PLAYER_FN" "$1" > /dev/null 2>&1 &
;;
esac
return $?
else
die "File: $1 is not playable... Quitting"
@ -420,16 +441,14 @@ get_search_query() {
-mesg "$(generate_span "$msg")" \
-config "$ROFI_CFG" < <(run_stmt "$stmt"))
query="${query//[1-9]*\. /}"
lg "Query: $query"
elif [ "$IS_ROFI" -eq 0 ]; then
printf "Search Anime: "
prompt "Search Anime"
read -r query
fi
}
# get anime name along with its id
search_anime() {
lg "NUM ARGS: $#"
if [[ $# -gt 1 ]]; then
# if multi-word query, concatenate into one string and replace spaces with '-'
search="$*"
@ -470,9 +489,7 @@ anime_selection() {
while read -r anime_id; do
menu+="$((cnt + 1)). $anime_id\n"
res["$cnt"]="$anime_id"
lg "ANIME: $anime_id"
if ! check_db "search" "$anime_id"; then
lg "$anime_id HAS BEEN SEARCHED BEFORE"
[ -z "$searched" ] && searched="$cnt" || searched="$searched, $cnt"
fi
((++cnt))
@ -481,8 +498,6 @@ anime_selection() {
EOF
menu+="$((++cnt)). Quit"
lg "searched indexes: $searched"
# get the anime from indexed list
msg="$(generate_span "Query: $query")"
user_input=$(printf "${menu[@]}" |
@ -493,7 +508,6 @@ anime_selection() {
-mesg "$msg" -only-match)
[ -z "$user_input" ] && return 1
if [ "$(awk '{ print $NF }' <<< "$user_input")" = "Quit" ]; then
lg "QUITTING"
return 1
fi
@ -501,22 +515,13 @@ anime_selection() {
choice="${choice::-1}" # Remove period after number
name=$(printf '%s\n' "$user_input" | awk '{print $NF}')
else
menu_format_string='[%d] %s\n'
menu_format_string_c1="$c_blue[$c_cyan%d$c_blue] $c_reset%s\n"
menu_format_string_c2="$c_blue[$c_cyan%d$c_blue] $c_yellow%s$c_reset\n"
count=1
while read -r anime_id; do
# alternating colors for menu
[ $((count % 2)) -eq 0 ] &&
menu_format_string=$menu_format_string_c1 ||
menu_format_string=$menu_format_string_c2
printf "$menu_format_string" "$count" "$anime_id"
count=$((count + 1))
menu_line_alternate "$anime_id" "$count"
: count=$((count += 1))
done <<< "$search_results"
printf "$c_blue%s$c_green" "Enter number: "
read choice
printf "$c_reset"
prompt "Enter choice: "
read -r choice
name="$anime_id"
fi
@ -530,23 +535,19 @@ anime_selection() {
break
fi
count=$((count + 1))
done <<- EOF
$search_results
EOF
done <<< "$search_results"
printf "$c_reset"
[ -z "$name" ] && name="$anime_id"
[ -z "$selection_id" ] && die "Invalid number entered"
[ -z "$name" ] && name="$anime_id"
insert_history "search" "$name" &
read -r last_ep_number <<- EOF
$(search_eps "$selection_id")
EOF
read -r last_ep_number < <(search_eps "$selection_id")
}
episode_selection() {
ep_choice_start="1"
ep_choice_start=1 first_ep_number=0
result=$(get_dpage_link "$anime_id" "$first_ep_number")
[ -z "$result" ] && first_ep_number=1
if [ "$IS_ROFI" -eq 1 ]; then
lg "Anime ID: $anime_id"
stmt="SELECT DISTINCT episode_number FROM watch_history WHERE anime_name = '$anime_id';"
@ -567,24 +568,25 @@ episode_selection() {
msg2="Range of episodes can be provided as: START_EPISODE - END_EPISODE"
[ "$is_download" -eq 1 ] && msg=$(printf "%s\n%s" "$(generate_span "$msg1")" "$(generate_span "$msg2")") || msg=$(printf "%s\n" "$(generate_span "$msg1")")
choice=$(
seq 1 "$last_ep_number" |
seq "$first_ep_number" "$last_ep_number" |
rofi -dpi "$DPI" -dmenu -l 12 \
-theme-str 'window {width: 45%;}' \
-a "$watch_history" \
-p "Select Episode [1, $last_ep_number]:" \
-p "Select Episode [$first_ep_number, $last_ep_number]:" \
-mesg "$msg" \
-config "$ROFI_CFG"
)
ep_choice_start=$(printf '%s\n' "${choice}" | awk '{print $1}')
ep_choice_end=$(printf '%s\n' "${choice}" | awk '{print $NF}')
lg "START: $ep_choice_start | END: $ep_choice_end"
elif [ $last_ep_number -gt 1 ]; then
[ $is_download -eq 1 ] &&
printf "Range of episodes can be specified: start_number end_number\n"
elif [ "$last_ep_number" -gt 1 ]; then
[ "$is_download" -eq 1 ] &&
inf "Range of episodes can be specified: start_number end_number"
printf "${c_blue}Choose episode $c_cyan[1-%d]$c_reset:$c_green " $last_ep_number
read ep_choice_start ep_choice_end
printf "$c_reset"
# printf "${c_blue}Choose episode $c_cyan[1-%d]$c_reset:$c_green " $last_ep_number
prompt "Choose episode " "[$first_ep_number-$last_ep_number]"
read -r ep_choice_start ep_choice_end
[ -z "$ep_choice_end" ] && ep_choice_end="$ep_choice_start"
fi
if [ "$(echo "$ep_choice_start" | awk '{ printf substr($0, 1, 1) }')" = "h" ]; then
lg "IS A HALF EPISODE"
@ -592,15 +594,14 @@ episode_selection() {
ep_choice_start=$(echo "$ep_choice_start" | awk '{ printf substr($0, 2) }')
ep_choice_end=$ep_choice_start
fi
if [[ -z "$ep_choice_start" ]] && [[ -z "$ep_choice_end" ]]; then
die "No episode range entered"
if (((ep_choice_start <= 0 || ep_choice_start > last_ep_number) || ep_choice_end < ep_choice_start || ep_choice_end > last_ep_number)); then
die "Invalid episode/range entered: ep_start -> $ep_choice_start | ep_end -> $ep_choice_end"
fi
# if only one episode was entered, set ep_choice_end to empty string so only selected episode plays
# otherwise plays from ep 1 - ep_choice_start
if [[ "$ep_choice_start" -eq "$ep_choice_end" ]]; then
ep_choice_end=""
fi
printf "$c_reset"
}
open_episode() {
@ -613,15 +614,15 @@ open_episode() {
episode=$episode"-5"
fi
lg "Getting data for episode $episode"
# Don't update watch history if downloading episode
if [ "$is_download" -eq 0 ]; then
insert_history "watch" "$anime_id" "$episode" &
fi
(("$is_download" == 0)) && insert_history "watch" "$anime_id" "$episode" &
lg "Getting data for episode $episode"
dpage_link=$(get_dpage_link "$anime_id" "$episode")
video_url=$(get_video_quality "$dpage_link")
if [ -z "$video_url" ]; then
die "Video URL not found"
fi
lg "Download link: $dpage_link"
lg "Video url: $video_url"
@ -630,38 +631,32 @@ open_episode() {
half_ep=0
fi
if [ -z "$video_url" ]; then
die "Video URL not found"
fi
if [ "$is_download" -eq 0 ]; then
kill "$PID" > /dev/null 2>&1
case "$player_fn" in
case "$PLAYER_FN" in
mpv)
nohup "$player_fn" --referrer="$dpage_link" "$video_url" > /dev/null 2>&1 &
nohup "$PLAYER_FN" --referrer="$dpage_link" "$video_url" --force-media-title="aniwrapper: $anime_id E$(printf "%03d" "$episode")" > /dev/null 2>&1 &
;;
mplayer)
nohup "$player_fn" -referrer "$dpage_link" "$video_url" > /dev/null 2>&1 &
nohup "$PLAYER_FN" -referrer "$dpage_link" "$video_url" -title "aniwrapper: $anime_id E$(printf "%03d" "$episode")" > /dev/null 2>&1 &
;;
vlc)
nohup "$player_fn" --play-and-exit --http-referrer="$dpage_link" "$video_url" > /dev/null 2>&1 &
nohup "$PLAYER_FN" --play-and-exit --http-referrer="$dpage_link" "$video_url" > /dev/null 2>&1 &
;;
*)
# try to open with just the video url
nohup "$player_fn" "$video_url" > /dev/null 2>&1 &
nohup "$PLAYER_FN" "$video_url" > /dev/null 2>&1 & # try to open with just the video url
;;
esac
PID=$!
if command -v "notify-send" > /dev/null; then
((SILENT != 1)) && notify-send -i "$ANIWRAPPER_ICON_PATH" "Playing $anime_id - Episode $episode"
else
((SILENT != 1)) && printf "${c_green}\nVideo playing"
((SILENT != 1)) && inf "Playing $anime_id - Episode $episode"
fi
else
lg "Downloading episode $episode ..."
dl_dir="${ddir// /}/$anime_id"
# add 0 padding to the episode name
episode=$(printf "%03d" "$episode")
episode=$(printf "%03d" "$episode") # add 0 padding to the episode name
{
mkdir -p "$dl_dir" || die "Could not create directory"
if command -v "notify-send" > /dev/null; then
@ -701,17 +696,15 @@ stream() {
die "No anime selection found"
fi
else
# skip search_anime function and assign $query if previously searched
selection_id="$anime_id"
insert_history "search" "$anime_id" &
read -r last_ep_number < <(search_eps "$anime_id")
fi
lg "LAST EP NUMBER -> $last_ep_number"
episode_selection
}
parse_args() {
# to clear the colors when exited using SIGINT
trap "printf '$c_reset'" INT HUP
scrape=query
quality=best
is_download=0
@ -806,13 +799,13 @@ parse_args() {
SILENT=1
;;
p)
player_fn="$OPTARG"
if ! command -v "$player_fn" > /dev/null; then
die "ERROR: $player_fn does not exist"
PLAYER_FN="$OPTARG"
if ! command -v "$PLAYER_FN" > /dev/null; then
die "ERROR: $PLAYER_FN does not exist"
fi
;;
*)
printf "%s\n" "Invalid option"
inf "Invalid option"
exit 1
;;
esac
@ -843,20 +836,20 @@ main() {
lg "Most recently watched episode: $ep_choice_start"
;;
sync)
printf "%s" "Enter username for remote user: "
prompt "Enter username for remote user: "
read -r username
printf "%s" "Enter host for remote user: "
prompt "Enter host for remote user: "
read -r host
connection_str="$username@$host"
printf "%s" "Enter port to connect to remote host with or leave blank for default (22): "
prompt "Enter port to connect to remote host with or leave blank for default (22): "
read -r port
[ -z "$port" ] && PORT=22 || PORT="$port"
printf "%s" "Enter path to private key (leave blank if unsure or not needed): "
prompt "Enter path to private key (leave blank if unsure or not needed): "
read -r key_path
printf "%s\n" "Syncing database with: $connection_str on port $PORT"
lg "Syncing database with: $connection_str on port $PORT"
temp_db="/tmp/aniwrapper_tmp_history.sqlite3"
if [[ -z "$key_path" ]]; then
@ -902,24 +895,22 @@ main() {
episode=${ep_choice_end:-$ep_choice_start}
choice=''
while :; do
printf "\n${c_green}Currently playing %s episode ${c_cyan}%d/%d\n" "$selection_id" $episode $last_ep_number
if [ "$episode" -ne "$last_ep_number" ]; then
printf "$c_blue[${c_cyan}%s$c_blue] $c_yellow%s$c_reset\n" "n" "next episode"
inf "Currently playing $selection_id episode" "$episode/$last_ep_number"
if ((episode != last_ep_number)); then
menu_line_alternate "next episode" "n"
fi
if [ "$episode" -ne "1" ]; then
printf "$c_blue[${c_cyan}%s$c_blue] $c_magenta%s$c_reset\n" "p" "previous episode"
if ((episode != first_ep_number)); then
menu_line_alternate "previous episode" "p"
fi
if [ "$last_ep_number" -ne "1" ]; then
printf "$c_blue[${c_cyan}%s$c_blue] $c_yellow%s$c_reset\n" "s" "select episode"
if ((first_ep_number != last_ep_number)); then
menu_line_alternate "select episode" "s"
fi
printf "$c_blue[${c_cyan}%s$c_blue] $c_magenta%s$c_reset\n" "r" "replay current episode"
printf "$c_blue[${c_cyan}%s$c_blue] $c_yellow%s$c_reset\n" "a" "search for another anime"
printf "$c_blue[${c_cyan}%s$c_blue] $c_magenta%s$c_reset\n" "Q" "change video quality (current: $quality)"
printf "$c_blue[${c_cyan}%s$c_blue] $c_red%s$c_reset\n" "q" "exit"
printf "${c_blue}Enter choice:${c_green} "
menu_line_alternate "replay current episode" "r"
menu_line_alternate "search for another anime" "a"
menu_line_alternate "select quality (current: $quality)" "Q"
menu_line_strong "exit" "q"
prompt "Enter choice"
read -r choice
printf "$c_reset"
case $choice in
n)
episode=$((episode + 1))
@ -970,11 +961,11 @@ main() {
quality=$(awk '{ print $2 }' <<< "$choice")
else
qualities="best|1080p|720p|480p|360p|worst"
printf "${c_blue}Choose quality: [$qualities]:$c_reset "
prompt "Choose quality: [$qualities]"
read -r quality
while [[ ! "$quality" =~ ($qualities) ]]; do
lg "$quality not a valid quality"
printf "${c_blue}Choose quality: [$qualities]:$c_reset "
prompt "Choose quality: [$qualities]"
read -r quality
done
fi
@ -994,7 +985,7 @@ main() {
fi
}
dep_ch "$player_fn" "curl" "sed" "grep" "sqlite3" "rofi" "git" "aria2c"
dep_ch "$PLAYER_FN" "curl" "sed" "grep" "sqlite3" "rofi" "git" "aria2c"
parse_args "$@"
shift $((OPTIND - 1))
main "$@"

View File

@ -61,10 +61,20 @@ Options:
lg() {
if ((VERBOSE == 1)); then
printf "%s\n" "$*"
inf "$*"
fi
}
# display an informational message (first argument in green, second in magenta)
inf() {
printf "\033[1;32m%s \033[1;35m%s\033[0m\n" "$1" "$2"
}
# prompts the user with message in $1-2 ($1 in blue, $2 in magenta) and saves the input to the variables in $REPLY and $REPLY2
prompt() {
printf "\033[1;34m%s\033[1;35m%s\033[1;34m: \033[0m" "$1" "$2"
}
seppuku() {
printf "%s\n" "$*"
exit 1
@ -110,11 +120,11 @@ get_quality() {
QUALITY=$(awk '{print $2}' <<< "$selection")
else
qualities="best|1080p|720p|480p|360p|worst"
printf "%s" "Choose quality: [$qualities]: "
prompt "Choose quality " "[$qualities]"
read -r QUALITY
while [[ ! "$QUALITY" =~ ($qualities) ]]; do
lg "$QUALITY not a valid quality -> [$qualities]"
printf "%s" "Choose quality: [$qualities]: "
prompt "Choose quality " "[$qualities]"
read -r QUALITY
done
fi
@ -250,7 +260,7 @@ get_player() {
while IFS='|' read -ra players; do
printf "%s\n" "${players[@]}"
done <<< "$SUPPORTED_PLAYERS"
printf "%s" "Enter player: "
prompt "Enter player"
read -r PLAYER_FN
fi
[ -z "$PLAYER_FN" ] && PLAYER_FN=mpv
@ -272,7 +282,7 @@ check_flags() {
run -c "$@"
exit $?
elif ((IS_ROFI == 0 && IS_DOWNLOAD == 1)); then
printf "%s" "Enter download dir: "
prompt "Enter download directory"
read -r dl_dir
lg "Download dir: $dl_dir"
if [ ! -d "$dl_dir" ]; then
@ -298,6 +308,9 @@ get_dl_dir() {
)
# if dl_dir is none set to current directory
[ "$dl_dir" == "" ] && dl_dir="$DEFAULT_DOWNLOAD"
if [ ! -d "$dl_dir" ]; then
mkdir -p "$dl_dir" || seppuku "Error creating directory: $dl_dir"
fi
}
########