mirror of
https://github.com/ksyasuda/aniwrapper.git
synced 2024-11-22 03:19:53 -08:00
ce75838882
getting list of active elements for rofi was broken due to bad not actually incrementing the loop each iteration
830 lines
22 KiB
Bash
Executable File
830 lines
22 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# Set config directory if not already set
|
|
if [[ -z "$XDG_CONFIG_HOME" ]]; then
|
|
XDG_CONFIG_HOME="$HOME/.config"
|
|
fi
|
|
|
|
VERBOSE=0
|
|
|
|
# BASE_URL="https://www2.gogoanime.cm/"
|
|
BASE_URL=$(curl -s -L -o /dev/null -w "%{url_effective}\n" https://gogoanime.cm)
|
|
CFG_DIR="$XDG_CONFIG_HOME/aniwrapper"
|
|
ROFI_CFG="meh.rasi"
|
|
ANIWRAPPER_ICON_PATH="$CFG_DIR/icons/icon-64.png"
|
|
MAISAN_ICON_PATH="$CFG_DIR/icons/MYsan.png"
|
|
|
|
HISTORY_DB="$XDG_CONFIG_HOME/aniwrapper/history.sqlite3"
|
|
|
|
# dependencies: grep, sed, curl, video_player, rofi, sqlite3
|
|
# video_player ( needs to be able to play urls )
|
|
player_fn="mpv"
|
|
|
|
prog="ani-cli"
|
|
logfile="${XDG_CACHE_HOME:-$HOME/.cache}/ani-hsts"
|
|
|
|
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"
|
|
|
|
help_text() {
|
|
while IFS= read -r line; do
|
|
printf "%s\n" "$line"
|
|
done <<-EOF
|
|
USAGE: $prog <query>
|
|
-h show this help text
|
|
-d download episode
|
|
-H continue where you left off
|
|
EOF
|
|
}
|
|
|
|
die() {
|
|
printf "$c_red%s$c_reset\n" "$*" >&2
|
|
exit 1
|
|
}
|
|
|
|
err() {
|
|
printf "$c_red%s$c_reset\n" "$*" >&2
|
|
}
|
|
|
|
log() {
|
|
# prints passed in args to stdout if $VERBOSE is set to 1
|
|
[ "$VERBOSE" -eq 1 ] && printf "%s\n" "$*" >&2
|
|
}
|
|
|
|
search_anime() {
|
|
# get anime name along with its id
|
|
log "NUM ARGS: $#"
|
|
if [[ $# -gt 1 ]]; then
|
|
# if multi-word query, concatenate into one string and replace spaces with '-'
|
|
search="$*"
|
|
search="${search// /-}"
|
|
else
|
|
# if one word, remove leading or trailing whitespace
|
|
search="${1// /}"
|
|
fi
|
|
# search=${1// /-}
|
|
log "Search Query: $search"
|
|
titlepattern='<a href="/category/'
|
|
curl -s "$BASE_URL//search.html" \
|
|
-G \
|
|
-d "keyword=$search" |
|
|
sed -n -E '
|
|
s_^[[:space:]]*<a href="/category/([^"]*)" title="([^"]*)".*_\1_p
|
|
'
|
|
}
|
|
|
|
search_eps() {
|
|
# get available episodes for anime_id
|
|
anime_id=$1
|
|
|
|
curl -s "$BASE_URL/category/$anime_id" |
|
|
sed -n -E '
|
|
/^[[:space:]]*<a href="#" class="active" ep_start/{
|
|
s/.* '\''([0-9]*)'\'' ep_end = '\''([0-9]*)'\''.*/\2/p
|
|
q
|
|
}
|
|
'
|
|
}
|
|
|
|
check_input() {
|
|
[ "$ep_choice_start" -eq "$ep_choice_start" ] 2>/dev/null || die "Invalid number entered"
|
|
episodes=$ep_choice_start
|
|
if [ -n "$ep_choice_end" ]; then
|
|
[ "$ep_choice_end" -eq "$ep_choice_end" ] 2>/dev/null || die "Invalid number entered"
|
|
# create list of episodes to download/watch
|
|
episodes=$(seq $ep_choice_start $ep_choice_end)
|
|
fi
|
|
}
|
|
|
|
get_embedded_video_link() {
|
|
# get the download page url
|
|
anime_id=$1
|
|
ep_no=$2
|
|
|
|
# credits to fork: https://github.com/Dink4n/ani-cli for the fix
|
|
# dub prefix takes the value "-dub" when dub is needed else is empty
|
|
curl -s "$BASE_URL/$anime_id${dub_prefix}-episode-$ep_no" |
|
|
sed -n -E '
|
|
/^[[:space:]]*<a href="#" rel="100"/{
|
|
s/.*data-video="([^"]*)".*/https:\1/p
|
|
q
|
|
}'
|
|
}
|
|
|
|
get_links() {
|
|
embedded_video_url=$(get_embedded_video_link "$anime_id" "$episode")
|
|
episode_id=$(echo "$embedded_video_url" | grep -oE "id.+?&")
|
|
video_url="https://gogoplay1.com/download?${episode_id}"
|
|
}
|
|
|
|
get_video_quality() {
|
|
get_links
|
|
video_quality=$(curl -s get_links "$video_url" | grep -oE "(http|https):\/\/.*com\/cdn.*expiry=[0-9]*"| sort -V | sed 's/amp;//')
|
|
case $quality in
|
|
best)
|
|
play_link=$(echo "$video_quality" | sort -V | tail -n 1)
|
|
;;
|
|
worst)
|
|
play_link=$(echo "$video_quality" | sort -V | head -n 1)
|
|
;;
|
|
*)
|
|
play_link=$(echo "$video_quality" | grep -oE "(http|https):\/\/.*com\/cdn.*"${quality}".*expiry=[0-9]*")
|
|
if [ -z "$play_link" ]; then
|
|
printf "$c_red%s$c_reset\n" "Current video quality is not available (defaulting to highest quality)" >&2
|
|
quality=best
|
|
play_link=$(echo "$video_quality" | sort -V | tail -n 1)
|
|
fi
|
|
printf '%s' "$play_link"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
dep_ch() {
|
|
for dep; do
|
|
if ! command -v "$dep" >/dev/null; then
|
|
die "Program \"$dep\" not found. Please install it."
|
|
fi
|
|
done
|
|
}
|
|
|
|
check_anime_name() {
|
|
# Check to make sure passed in name is not empty
|
|
log "VAR: $1"
|
|
if [[ "$1" == "" ]] || [[ "$1" == " " ]] || [[ "$1" == "\n" ]]; then
|
|
log "Passed in name is nothing"
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
run_stmt() {
|
|
printf "%s\n" "$1" | sqlite3 -noheader "$HISTORY_DB"
|
|
}
|
|
|
|
#####################
|
|
## Database Code ##
|
|
#####################
|
|
|
|
check_db() {
|
|
# Return number of matches for anime/episode in db
|
|
# args:
|
|
# $1: anime name: str
|
|
# $2: either 'search' or 'watch' for which db to query
|
|
if [[ "$2" == "search" ]]; then
|
|
stmt="SELECT DISTINCT COUNT(*) \
|
|
FROM search_history \
|
|
WHERE anime_name = '$1';"
|
|
res=$(run_stmt "$stmt")
|
|
return "$res"
|
|
else
|
|
stmt="SELECT DISTINCT COUNT(*) \
|
|
FROM watch_history \
|
|
WHERE anime_name = '$1' \
|
|
AND episode_number = $2;"
|
|
res=$(run_stmt "$stmt")
|
|
return "$res"
|
|
fi
|
|
}
|
|
|
|
# updates search/watch date for passed in anime
|
|
update_date() {
|
|
datetime=$(date +'%Y-%m-%d %H:%M:%S')
|
|
stmt=""
|
|
if [[ "$2" == "search" ]]; then
|
|
stmt="UPDATE search_history SET search_date = '$datetime' \
|
|
WHERE anime_name = '$1';"
|
|
else
|
|
stmt="UPDATE watch_history SET watch_date = '$datetime' \
|
|
WHERE anime_name = '$1' \
|
|
AND episode_number = $2;"
|
|
fi
|
|
run_stmt "$stmt"
|
|
}
|
|
|
|
insert_history() {
|
|
# inserts into search/watch history db
|
|
# check the anime_name/id
|
|
|
|
if ! check_anime_name "$1"; then
|
|
log "ERROR: Anime name is none... exiting"
|
|
return 1
|
|
fi
|
|
datetime=$(date +'%Y-%m-%d %H:%M:%S')
|
|
check_db "$@"
|
|
res="$?"
|
|
if [[ "$res" -gt 0 ]]; then
|
|
if [[ "$2" == "search" ]]; then
|
|
log "Already in search db... Updating search_date"
|
|
else
|
|
log "Already in search db... Updating watch_date"
|
|
fi
|
|
update_date "$@"
|
|
else
|
|
if [[ "$2" == "search" ]]; then
|
|
stmt="INSERT INTO search_history(anime_name, search_date) \
|
|
VALUES('$1', '$datetime');"
|
|
run_stmt "$stmt"
|
|
else
|
|
stmt="INSERT INTO \
|
|
watch_history(anime_name, episode_number, watch_date) \
|
|
VALUES('$1', '$2', '$datetime');"
|
|
run_stmt "$stmt"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
sync_search_history() {
|
|
cnt=0
|
|
while read -r line; do
|
|
anime_name=$(awk -F '|' '{print $2}' <<<"$line")
|
|
res=$(sqlite3 -noheader "$HISTORY_DB" "SELECT COUNT(*) FROM search_history WHERE anime_name = '$anime_name'")
|
|
if [[ "$res" -eq 0 ]]; then
|
|
search_date=$(awk -F '|' '{print $3}' <<<"$line")
|
|
log "Adding ($anime_name|$search_date) to search history..."
|
|
if ! sqlite3 "$HISTORY_DB" "INSERT INTO search_history(anime_name, search_date) VALUES('$anime_name', '$search_date')"; then
|
|
err "Error inserting row $line"
|
|
fi
|
|
((++cnt))
|
|
fi
|
|
done <<<"$(sqlite3 -noheader "$temp_db" "SELECT DISTINCT * FROM search_history")"
|
|
log "Inserted $cnt rows into search_history table"
|
|
}
|
|
|
|
sync_watch_history() {
|
|
cnt=0
|
|
while read -r line; do
|
|
# anime_name=$(awk -F '|' '{print $2}' <<<"$line")
|
|
anime_name="${line/ //}"
|
|
log "ANIME: $anime_name"
|
|
episodes=$(sqlite3 -noheader "$temp_db" "SELECT episode_number, watch_date FROM watch_history WHERE anime_name = '$anime_name'")
|
|
# for each episode of $anime_name on the remote machine, check local
|
|
while read -r ep; do
|
|
episode_num=$(awk -F '|' '{print $1}' <<<"$ep")
|
|
# TODO: Fix inserting duplicate rows
|
|
run_stmt "SELECT COUNT(*) FROM watch_history WHERE anime_name = '$anime_name' AND episode_number = $episode_num"
|
|
num=$?
|
|
log "EP: $ep"
|
|
if [[ "$num" -eq 0 ]]; then
|
|
log "NOT IN DB"
|
|
watch_date=$(awk -F '|' '{print $NF}' <<<"$ep")
|
|
log "Adding ($anime_name|$episode_num|$watch_date) to watch history..."
|
|
if ! sqlite3 "$HISTORY_DB" "INSERT INTO watch_history(anime_name, episode_number, watch_date) VALUES('$anime_name', '$episode_num', '$watch_date')"; then
|
|
err "Error inserting row $ep"
|
|
fi
|
|
((++cnt))
|
|
else
|
|
log "Episode: $episode_num found in the db... skipping"
|
|
fi
|
|
done <<<"${episodes[@]}"
|
|
done <<<"$(sqlite3 -noheader "$temp_db" "SELECT DISTINCT anime_name FROM watch_history")"
|
|
log "Inserted $cnt rows into watch_history table"
|
|
}
|
|
|
|
#####################
|
|
## END of db code ##
|
|
#####################
|
|
|
|
# get query
|
|
get_search_query() {
|
|
# Query the anime to stream/download
|
|
|
|
# Get search history
|
|
# Construct string "<id>. <anime_name>"
|
|
stmt="SELECT DISTINCT id || '. ' || anime_name \
|
|
FROM search_history \
|
|
ORDER BY id DESC;"
|
|
hist=$(run_stmt "$stmt")
|
|
|
|
msg="Choose from list of searched anime below, or enter a unique name of an anime to search for"
|
|
span="<span foreground='peachpuff' style='italic' size='small' weight='light'>$msg</span>"
|
|
if [ -z "$*" ] && [ "$is_rofi" -eq 1 ]; then
|
|
query=$(rofi -dmenu -l 12 -p "Search Anime:" \
|
|
-mesg "$span" \
|
|
-config "$CFG_DIR/${ROFI_CFG}" <<< "${hist[@]}")
|
|
# Remove the id from the query
|
|
query="${query//[1-9]*\. /}"
|
|
# fixes '-' at end of selected anime, but removes spaces from queries
|
|
# works with trailing '-' so remove for now
|
|
# query="${query// /}"
|
|
log "Query: $query"
|
|
elif [ "$is_rofi" -eq 0 ]; then
|
|
printf "Search Anime: "
|
|
read -r query
|
|
else
|
|
query=$*
|
|
fi
|
|
}
|
|
|
|
# create history file
|
|
[ -f "$logfile" ] || : >"$logfile"
|
|
|
|
#####################
|
|
## Anime selection ##
|
|
#####################
|
|
|
|
anime_selection() {
|
|
# Select anime from query results
|
|
search_results=$*
|
|
if [ "$is_rofi" -eq 1 ]; then
|
|
count=1
|
|
menu=()
|
|
res=()
|
|
while read -r anime_id; do
|
|
menu+="$count. $anime_id\n"
|
|
idx=$((count - 1))
|
|
res["$idx"]="$anime_id"
|
|
count=$((count + 1))
|
|
done <<-EOF
|
|
$search_results
|
|
EOF
|
|
|
|
searched=""
|
|
cnt=0
|
|
# Get the comma separated list of indexes of anime that has been searched before
|
|
for anime in "${res[@]}"; do
|
|
log "ANIME: $anime"
|
|
check_db "$anime" "search"
|
|
if [[ $? -gt 0 ]]; then
|
|
log "SEARCHED BEFORE"
|
|
if [ -z "$searched" ]; then
|
|
searched="$cnt"
|
|
else
|
|
searched="$searched, $cnt"
|
|
fi
|
|
fi
|
|
((++cnt))
|
|
done
|
|
|
|
log "SEARCHED: $searched"
|
|
|
|
# get the anime from indexed list
|
|
msg="<span foreground='peachpuff' style='italic' size='small' weight='normal'>Query: $query</span>"
|
|
user_input=$(printf "${menu[@]}" |
|
|
rofi -dmenu -config "$CFG_DIR/${ROFI_CFG}" \
|
|
-a "$searched" \
|
|
-l 12 -i -p "Enter number:" \
|
|
-mesg "$msg")
|
|
[ -z "$user_input" ] && return 1
|
|
|
|
choice=$(printf '%s\n' "$user_input" | awk '{print $1}')
|
|
# Remove period after number
|
|
choice="${choice::-1}"
|
|
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 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))
|
|
done <<< "$search_results"
|
|
|
|
# User input
|
|
printf "$c_blue%s$c_green" "Enter number: "
|
|
read choice
|
|
printf "$c_reset"
|
|
name="$anime_id"
|
|
fi
|
|
|
|
log "CHOICE: $choice"
|
|
|
|
if [ "$is_rofi" -eq 1 ]; then
|
|
log "NAME: $name"
|
|
# check both choice and name are set
|
|
if [[ ! "$choice" ]] || [[ ! "$name" ]]; then
|
|
die "Invalid choice... committing seppuku"
|
|
fi
|
|
fi
|
|
# Check if input is a number
|
|
[ "$choice" -eq "$choice" ] 2>/dev/null || die "Invalid number entered"
|
|
|
|
# Select respective anime_id
|
|
count=1
|
|
while read -r anime_id; do
|
|
if [ "$count" -eq "$choice" ]; then
|
|
selection_id=$anime_id
|
|
break
|
|
fi
|
|
count=$((count + 1))
|
|
done <<-EOF
|
|
$search_results
|
|
EOF
|
|
|
|
[ -z "$name" ] && name="$anime_id"
|
|
log "NAME: $name"
|
|
insert_history "$name" "search"
|
|
|
|
printf "$c_reset"
|
|
|
|
[ -z "$selection_id" ] && die "Invalid number entered"
|
|
|
|
read -r last_ep_number <<-EOF
|
|
$(search_eps "$selection_id")
|
|
EOF
|
|
}
|
|
|
|
##################
|
|
## Ep selection ##
|
|
##################
|
|
|
|
episode_selection() {
|
|
ep_choice_start="1"
|
|
if [ "$is_rofi" -eq 1 ]; then
|
|
# select episode number for anime
|
|
log "Anime ID: $anime_id"
|
|
stmt="SELECT DISTINCT episode_number \
|
|
FROM watch_history \
|
|
WHERE anime_name = '$anime_id';"
|
|
hist=$(run_stmt "$stmt")
|
|
log "HISTORY: ${hist[*]}"
|
|
|
|
# Get Watch History for $anime_id as comma separated list
|
|
watch_history=""
|
|
for i in $hist; do
|
|
if [[ "$watch_history" == "" ]]; then
|
|
watch_history="$((--i))"
|
|
else
|
|
watch_history="$watch_history, $((--i))"
|
|
fi
|
|
done
|
|
|
|
log "WATCH HISTORY: %s\n" "$watch_history"
|
|
# get user choice and set the start and end
|
|
msg='<span foreground="peachpuff" style="italic" size="small" weight="light">Range of episodes can be provided as: START_EPISODE - END_EPISODE</span>'
|
|
choice=$(
|
|
seq 1 "$last_ep_number" |
|
|
rofi -dmenu -l 12 \
|
|
-a "$watch_history" \
|
|
-p "Select Episode [1, $last_ep_number]:" \
|
|
-mesg "$msg" \
|
|
-config "$CFG_DIR/${ROFI_CFG}"
|
|
)
|
|
ep_choice_start=$(printf '%s\n' "${choice}" | awk '{print $1}')
|
|
ep_choice_end=$(printf '%s\n' "${choice}" | awk '{print $NF}')
|
|
log "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"
|
|
|
|
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"
|
|
fi
|
|
if [[ -z "$ep_choice_start" ]] && [[ -z "$ep_choice_end" ]]; then
|
|
die "No episode range entered"
|
|
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
|
|
|
|
# read ep_choice_start ep_choice_end
|
|
printf "$c_reset"
|
|
|
|
}
|
|
|
|
open_episode() {
|
|
anime_id=$1
|
|
episode=$2
|
|
ddir="$3"
|
|
|
|
if [[ ! "$is_playlist" ]]; then
|
|
# clear the screen
|
|
printf '\x1B[2J\x1B[1;1H'
|
|
if [[ $episode -lt 1 ]] || [[ $episode -gt $last_ep_number ]]; then
|
|
err "Episode out of range"
|
|
stmt="SELECT DISTINCT episode_number \
|
|
FROM watch_history \
|
|
WHERE anime_name = '$anime_id' \
|
|
ORDER BY episode_number ASC;"
|
|
hist=$(run_stmt "$stmt")
|
|
log "HISTORY: ${hist[*]}"
|
|
episode=$(printf "%s\n" "${hist[@]}" |
|
|
rofi -dmenu -l 12 -p "Choose Episode:" \
|
|
-config "$CFG_DIR/${ROFI_CFG}")
|
|
printf "$c_reset"
|
|
fi
|
|
fi
|
|
|
|
log "Getting data for episode $episode"
|
|
|
|
# Don't update watch history if downloading episode
|
|
if [ "$is_download" -eq 0 ]; then
|
|
insert_history "$anime_id" "$episode"
|
|
fi
|
|
|
|
get_video_quality
|
|
status_code=$(curl -s -I get_video_quality "$play_link" | head -n 1|cut -d ' ' -f2)
|
|
log "Status code: $status_code"
|
|
|
|
if [ "$is_download" -eq 0 ]; then
|
|
if echo "$status_code" | grep -vE "^2.*"; then
|
|
printf "${c_red}\nCannot reach servers!"
|
|
else
|
|
setsid -f $player_fn get_video_quality "$play_link" > /dev/null 2>&1
|
|
printf "${c_green}\nVideo playing"
|
|
fi
|
|
else
|
|
log "Downloading episode $episode ..."
|
|
log "$video_url"
|
|
# add 0 padding to the episode name
|
|
episode=$(printf "%03d" "$episode")
|
|
{
|
|
cd "${ddir/ //}" || die "Could not enter directory $ddir"
|
|
mkdir -p "$anime_id" || die "Could not create directory"
|
|
cd "$anime_id" || die "Could not enter subdirectory $ddir/$anime_id"
|
|
# ffmpeg -i "$play_link" -c copy "${anime_id}-${episode}.mkv" >/dev/null 2>&1 &&
|
|
if command -v "notify-send" >/dev/null; then
|
|
ffmpeg -i "$play_link" -c copy "${episode}.mkv" >/dev/null 2>&1 &&
|
|
notify-send -i "$ANIWRAPPER_ICON_PATH" "Download complete for ${anime_id//-/ } - Episode: $episode" ||
|
|
notify-send -i "$MAISAN_ICON_PATH" "Download failed for ${anime_id//-/ } - Episode: $episode. Please retry or check your internet connection"
|
|
else
|
|
ffmpeg -i "$play_link" -c copy "${episode}.mkv" >/dev/null 2>&1 &&
|
|
printf "${c_green}Downloaded complete for %s - Episode: %s${c_reset}\n" "${anime_id//-/ }" "$episode" ||
|
|
printf "${c_red}Download failed for %s - Episode: %s, please retry or check your internet connection${c_reset}\n" "${anime_id//-/ }" "$episode"
|
|
fi
|
|
# printf "${c_green}Downloaded episode: %s${c_reset}\n" "$episode" ||
|
|
# printf "${c_red}Download failed episode: %s , please retry or check your internet connection${c_reset}\n" "$episode"
|
|
}
|
|
fi
|
|
}
|
|
|
|
############
|
|
# Start Up #
|
|
############
|
|
|
|
# to clear the colors when exited using SIGINT
|
|
trap "printf '$c_reset'" INT HUP
|
|
|
|
dep_ch "$player_fn" "curl" "sed" "grep" "sqlite3" "rofi"
|
|
|
|
# option parsing
|
|
is_rofi=1
|
|
is_download=0
|
|
scrape=query
|
|
download_dir="."
|
|
is_playlist=0
|
|
playlist_remove=0
|
|
playlist_add=0
|
|
quality=best
|
|
while getopts 'hd:Hpa:P:svq:c' OPT; do
|
|
case "$OPT" in
|
|
h)
|
|
help_text
|
|
exit 0
|
|
;;
|
|
d)
|
|
is_download=1
|
|
download_dir="$OPTARG"
|
|
log "DOWNLOAD DIR: $download_dir"
|
|
;;
|
|
H)
|
|
scrape=history
|
|
;;
|
|
p)
|
|
scrape=playlist
|
|
is_playlist=1
|
|
;;
|
|
a)
|
|
is_add=1
|
|
scrape=add
|
|
playlist_file="${OPTARG/ //}"
|
|
;;
|
|
P)
|
|
is_playlist=1
|
|
# remove spaces from $OPTARG
|
|
playlist_file="${OPTARG/ //}"
|
|
[ -z "$playlist_file" ] && die "Enter in path to playlist"
|
|
log "$playlist_file"
|
|
$player_fn "$playlist_file"
|
|
exit 0
|
|
;;
|
|
s)
|
|
scrape=sync
|
|
;;
|
|
v)
|
|
VERBOSE=1
|
|
;;
|
|
q)
|
|
quality="$OPTARG"
|
|
log "passed in quality: $quality"
|
|
;;
|
|
c)
|
|
is_rofi=0
|
|
;;
|
|
*)
|
|
printf "%s\n" "Invalid option"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
shift $((OPTIND - 1))
|
|
|
|
########
|
|
# main #
|
|
########
|
|
|
|
case $scrape in
|
|
query)
|
|
get_search_query "$*"
|
|
searched=0
|
|
if [ $# -eq 1 ]; then
|
|
# check if anime has been searched before
|
|
anime_id="${query// /}"
|
|
log "Checking if anime: $anime_id has been searched before..."
|
|
check_db "$anime_id" "search"
|
|
searched="$?"
|
|
log "Searched before: $searched"
|
|
fi
|
|
if [ "$searched" -eq 0 ]; then
|
|
search_results=$(search_anime $query)
|
|
[ -z "$search_results" ] && die "No search results found"
|
|
if ! anime_selection "$search_results"; then
|
|
die "No anime selection found"
|
|
fi
|
|
else
|
|
# if the query is a previous search
|
|
# skip search_anime function and assign $query
|
|
anime_id="${query// /}"
|
|
selection_id="$anime_id"
|
|
insert_history "$anime_id" "search"
|
|
read -r last_ep_number <<< "$(search_eps "$selection_id")"
|
|
fi
|
|
episode_selection
|
|
;;
|
|
history)
|
|
stmt="SELECT DISTINCT anime_name FROM watch_history ORDER BY watch_date DESC"
|
|
search_results=$(printf "%s\n" "$stmt" | sqlite3 -noheader "$HISTORY_DB")
|
|
[ -z "$search_results" ] && die "History is empty"
|
|
if ! anime_selection "${search_results[@]}"; then
|
|
die "No anime selection found"
|
|
fi
|
|
log "SELECTION: $selection_id"
|
|
|
|
stmt="SELECT episode_number \
|
|
FROM watch_history \
|
|
WHERE anime_name = '$selection_id' \
|
|
ORDER BY watch_date DESC \
|
|
LIMIT 1"
|
|
ep_choice_start=$(run_stmt "$stmt")
|
|
log "Most recently watched episode: $ep_choice_start"
|
|
;;
|
|
playlist)
|
|
lines=$(wc -l <"$playlist_file")
|
|
log "Num lines in playlist: " "$lines"
|
|
if [[ "$lines" -eq 0 ]]; then
|
|
get_search_query "$*"
|
|
search_results=$(search_anime "$query")
|
|
[ -z "$search_results" ] && die "No search results found"
|
|
if ! anime_selection "$search_results"; then
|
|
die "No anime selection found"
|
|
fi
|
|
episode_selection
|
|
else
|
|
line=($(sed '1q;d' "$playlist_file"))
|
|
if [[ "${#line[@]}" -ne 2 ]]; then
|
|
die "Something went wrong with the playlist file... exiting"
|
|
fi
|
|
selection_id="${line[0]}"
|
|
episodes=("$selection_id")
|
|
ep_choice_start="${line[1]}"
|
|
ep_choice_end=""
|
|
read -r last_ep_number <<-EOF
|
|
$(search_eps "$selection_id")
|
|
EOF
|
|
[ "$VERBOSE" -eq 1 ] && printf "Anime: %s Episode: %d\n" "$episodes" "$ep_choice_start"
|
|
[ "$VERBOSE" -eq 1 ] && printf "Episodes: %s\n" "${episodes[@]}"
|
|
fi
|
|
;;
|
|
add)
|
|
get_search_query "$*"
|
|
search_results=$(search_anime "$query")
|
|
[ -z "$search_results" ] && die "No search results found"
|
|
anime_selection "$search_results"
|
|
[ $? -ne 0 ] && die "No anime selection found"
|
|
episode_selection
|
|
;;
|
|
sync)
|
|
printf "%s" "Enter username for remote user: "
|
|
read -r username
|
|
printf "%s" "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): "
|
|
read -r port
|
|
if [[ "${port/ //}" == "" ]]; then
|
|
PORT=22
|
|
else
|
|
PORT="$port"
|
|
fi
|
|
|
|
printf "%s" "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"
|
|
temp_db="/tmp/aniwrapper_tmp_history.sqlite3"
|
|
|
|
if [[ -z "$key_path" ]]; then
|
|
scp -P "$PORT" "$connection_str:$XDG_CONFIG_HOME/aniwrapper/history.sqlite3" "$temp_db"
|
|
else
|
|
scp -P "$PORT" -i "$key_path" "$connection_str:$XDG_CONFIG_HOME/aniwrapper/history.sqlite3" "$temp_db"
|
|
fi
|
|
if [[ "$?" -ne 0 ]]; then
|
|
die "Error getting database file from remote host"
|
|
fi
|
|
sync_search_history && sync_watch_history
|
|
exit 0
|
|
;;
|
|
esac
|
|
|
|
{ # checking input
|
|
[ "$ep_choice_start" -eq "$ep_choice_start" ] 2>/dev/null || die "Invalid number entered"
|
|
episodes=$ep_choice_start
|
|
|
|
if [ -n "$ep_choice_end" ]; then
|
|
[ "$ep_choice_end" -eq "$ep_choice_end" ] 2>/dev/null || die "Invalid number entered"
|
|
# create list of episodes to download/watch
|
|
episodes=$(seq $ep_choice_start $ep_choice_end)
|
|
fi
|
|
}
|
|
|
|
# plays selected episode(s)
|
|
for ep in $episodes; do
|
|
if [[ "$is_add" -eq 1 ]]; then
|
|
log "ID: $selection_id"
|
|
log "EPISODES: $episodes"
|
|
printf "%s\n" "$selection_id $ep" >>"$playlist_file"
|
|
log "Added to playlist file"
|
|
else
|
|
open_episode "$selection_id" "$ep" "$download_dir"
|
|
if [[ "$is_playlist" -eq 1 ]]; then
|
|
sed -i '1d' "$playlist_file"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
if [[ "$is_add" -eq 1 ]]; then
|
|
log "Finished adding to playlist file... exiting"
|
|
exit 0
|
|
elif [[ "$is_download" -eq 1 ]]; then
|
|
log "Finished downloading episodes: $episodes for $selection_id... exiting"
|
|
exit 0
|
|
fi
|
|
|
|
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
|
|
printf "$c_blue[${c_cyan}%s$c_blue] $c_yellow%s$c_reset\n" "n" "next episode"
|
|
printf "$c_blue[${c_cyan}%s$c_blue] $c_magenta%s$c_reset\n" "p" "previous episode"
|
|
printf "$c_blue[${c_cyan}%s$c_blue] $c_yellow%s$c_reset\n" "s" "select episode"
|
|
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_red%s$c_reset\n" "q" "exit"
|
|
printf "${c_blue}Enter choice:${c_green} "
|
|
printf "$c_reset"
|
|
read -r choice
|
|
|
|
printf "$c_reset"
|
|
case $choice in
|
|
n)
|
|
episode=$((episode + 1))
|
|
;;
|
|
p)
|
|
episode=$((episode - 1))
|
|
;;
|
|
|
|
s)
|
|
printf "${c_blue}Choose episode $c_cyan[1-%d]$c_reset:$c_green " "$last_ep_number"
|
|
read -r episode
|
|
printf "$c_reset"
|
|
[ "$episode" -eq "$episode" ] 2>/dev/null || die "Invalid number entered"
|
|
;;
|
|
|
|
r) ;;
|
|
|
|
q)
|
|
break
|
|
;;
|
|
|
|
*)
|
|
die "invalid choice"
|
|
;;
|
|
esac
|
|
open_episode "$selection_id" "$episode" "$download_dir"
|
|
done
|