diff --git a/ani-cli b/ani-cli deleted file mode 100755 index 3be018c..0000000 --- a/ani-cli +++ /dev/null @@ -1,625 +0,0 @@ -#!/bin/sh - -version_number="5.0.0" - -# UI - -# shellcheck disable=SC2086 -# $1 = prompt, $2 = multi select flag (for fzf/rofi), $3 = extra flags by user -menu() { - case "$menu_program" in - fzf) fzf --reverse --cycle --prompt "$1" $2 $3 ;; - rofi) rofi -sort -dmenu -i -p "$1" $2 $3 ;; - dmenu) dmenu -l 20 -p "$1" $3 ;; - *) "$menu_program" $3 "$1" ;; - esac -} - -# provide menu. input format is either (ep_list) or (number \t anime_id \t anime_name) -nth() { - _stdin=$(cat -) - [ -z "$_stdin" ] && return 1 - _line_count="$(printf "%s\n" "$_stdin" | wc -l | tr -d "[:space:]")" - [ "$_line_count" -eq 1 ] && printf "%s" "$_stdin" | cut -f 2,3 && return 0 - _prompt="$1" - [ $# -ne 1 ] && _multi_flag="$2" - _line=$(printf "%s" "$_stdin" | cut -f 1,3 | tr '\t' ' ' | menu "$_prompt" "$_multi_flag" "$menu_extra_flags" | cut -d " " -f 1) - _line_start=$(printf "%s" "$_line" | head -n 1) - _line_end=$(printf "%s" "$_line" | tail -n 1) - [ -n "$_line" ] || return 1 - if [ "$_line_start" = "$_line_end" ]; then - printf "%s" "$_stdin" | grep -E '^'"${_line}"'($|[[:space:]])' | cut -f 2,3 || return 1 - else - printf "%s" "$_stdin" | sed -n '/^'"${_line_start}"'$/,/^'"${_line_end}$"'/p' || return 1 - fi -} - -die() { - printf "\33[2K\r\033[1;31m%s\033[0m\n" "$*" >&2 - exit 1 -} - -info() { - printf "\33[2K\r\033[1;34m%s\033[0m\n" "$*" -} - -help_info() { - printf " - Usage: - %s [options] [query] - %s [query] [options] - %s [options] [query] [options] - - Options: - -c, --continue - Continue watching from history - -d, --download - Download the video instead of playing it - -D, --delete - Delete history - -l, --logview - Show logs - -s, --syncplay - Use Syncplay to watch with friends - -S, --select-nth - Select nth entry - -q, --quality - Specify the video quality - -v, --vlc - Use VLC to play the video - -V, --version - Show the version of the script - -h, --help - Show this help message and exit - -e, --episode, -r, --range - Specify the number of episodes to watch - --dub - Play dubbed version - --rofi - Use rofi instead of fzf for the interactive menu - --dmenu - Use dmenu instead of fzf for the interactive menu - --skip - Use ani-skip to skip the intro of the episode (mpv only) - --no-detach - Don't detach the player (useful for in-terminal playback, mpv only) - --exit-after-play - Exit the player, and return the player exit code (useful for non interactive scenarios) - -N, --nextep-countdown - Display a countdown to the next episode - -U, --update - Update the script - Some example usages: - %s -q 720p banana fish - %s --skip -S 2 one piece - %s -d -e 2 cyberpunk edgerunners - %s --vlc cyberpunk edgerunners -q 1080p -e 4 - %s blue lock -e 5-6 - %s -e \"5 6\" blue lock - \n" "${0##*/}" "${0##*/}" "${0##*/}" "${0##*/}" "${0##*/}" "${0##*/}" "${0##*/}" "${0##*/}" "${0##*/}" - exit 0 -} - -version_info() { - printf "%s\n" "$version_number" - exit 0 -} - -# Bookkeeping - -update_script() { - info "[branch:$branch] Checking for Update.." - update="$($curl_exe --fail-with-body -sL -A "$agent" "https://raw.githubusercontent.com/pystardust/ani-cli/$branch/ani-cli")" || die "[branch:$branch] Connection error: $update" - new_version="$(printf "%s" "$update" | sed -nE 's|^version_number="([^"]+)"$|\1|p')" - [ -z "$new_version" ] && die "[branch:$branch] Invalid response." - printf "%s" "$update" | grep -q "^version_number" || die "[branch:$branch] Invalid response." - update="$(printf "%s\n" "$update" | diff -u "$0" -)" - if [ -z "$update" ]; then - info "[branch:$branch] Script is up to date :) ($version_number)" - else - if printf "%s\n" "$update" | patch "$0" -; then - info "[branch:$branch] Updated: $version_number -> $new_version" - else - die "[branch:$branch] Failed to update. Read the above line!" - fi - fi - exit 0 -} - -# checks if dependencies are present -dep_ch() { - command -v "$1" >/dev/null || die "Program $1 not found. Please install it." -} - -# checks for deps in order and returns the first available. format is "prog_a,prog_b,prog_c" -dep_ch_failover() { - [ -z "$1" ] && return 1 - prog=$(printf "%s" "$1" | cut -d "," -f 1) - rest=$(printf "%s" "$1" | cut -s -d "," -f 2-) - command -v "$prog" >/dev/null 2>&1 && printf "%s" "$prog" && return 0 - [ -e "$prog" ] && printf "%s" "$prog" && return 0 - dep_ch_failover "$rest" -} - -cleanup() { - tput sgr0 # clears colors - rm -f "${histfile}.new" # remove temp logfile -} - -# SCRAPING - -#shellcheck disable=SC2086 -anidb_curl() { - $curl_exe -sL -A "$agent" --max-time 10 $cipher_flag "$@" -} - -# search the query and give results. format is (id \t name) -anidb_search() { - #shellcheck disable=SC2059 - _page="$(anidb_curl "$(printf "$search_api" "$1")" | tr '\n' ' ' | sed 's|Seasons,/>Details
]*title="([^"]+)".*|\1\t\2|p' | sed -e "s|'|'|g")" - [ -n "$seasons" ] && seasons_option="\nchange_season" -} - -# get the episodes list of the selected anime. format is (id \t ep_no) -anidb_episodes() { - #shellcheck disable=SC2059 - _page="$(anidb_curl "$(printf "$episodes_api" "${1##*-}")")" - printf "%s" "$_page" | sed 's|},{|}\n{|g' | sed -nE 's|.*"id":([0-9]+).*"number":([0-9]+).*|\1\t\2|p' -} - -# extract the individual m3u8 links from response of embed urls -anidb_m3u8() { - _ep_id=$(printf "%s" "$episode_maps" | sed -nE "s|^([0-9]+)\t${1}$|\1|p") - _lang="jpn" - [ "$2" = "dub" ] && _lang="eng" - #shellcheck disable=SC2059 - _page="$(anidb_curl "$(printf "$m3u8_api" "${_ep_id}")")" - _embed="$(printf "%s" "$_page" | sed 's|},{|}\n{|g' | sed -nE 's|.*'"${_lang}"'.*embed_url":"([^"]+)".*|\1|p' | sed 's|\\/|/|g' | head -n 1)" - [ -z "$_embed" ] && return 1 - _embed_page="$(anidb_curl "$_embed")" - _m3u8_master="$(printf "%s" "$_embed_page" | sed -nE "s|.*file: '([^']*)'.*|\1|p" | head -n 1)" - anidb_curl "${_m3u8_master}" | sed 's|^#EXT-X-STREAM.*x||g; s|,.*|p|g; /^#/d; $!N; s|\n| >|;/EXT-X-I-FRAME/d' -} - -# select the quality according to the setting -select_quality() { - case "$1" in - best) _result=$(printf "%s" "$links" | head -n 1) ;; - worst) _result=$(printf "%s" "$links" | grep -E '^[0-9]{3,4}' | tail -n 1) ;; - *) _result=$(printf "%s" "$links" | grep -m 1 "$1") ;; - esac - [ -z "$_result" ] && printf "\33[2K\r\033[1;33m%s\033[0m\n" "$1 not found, defaulting to best" >&2 && _result=$(printf "%s" "$links" | head -n 1) - - video_link=$(printf "%s" "$_result" | cut -d ">" -f 2) -} - -# gets embed url, collects direct links and selects one with desired quality into $episode -get_video_link() { - links=$(anidb_m3u8 "$ep_no" "$mode" | sort -g -r -s) - [ -z "$links" ] && die "No sources found for $mode!" - info "anidb.app links fetched" - select_quality "$quality" - # should never trigger but just in case - if printf "%s" "$ep_list" | grep -q "^$ep_no$"; then - [ -z "$video_link" ] && die "Episode is released, but no valid sources!" - else - [ -z "$video_link" ] && die "Episode not released!" - fi -} - -# provide countdown for the next episode release both sub and dub -time_until_next_ep() { - animeschedule="https://animeschedule.net" - _query="$(printf "%s" "$*" | tr ' ' '+')" - $curl_exe -s -G "$animeschedule/api/v3/anime" --data "q=${_query}" | sed 's|},{"id"|\n|g' | while read -r _entry; do - _route=$(printf "%s" "$_entry" | sed -nE 's|.*"route":"([^"]*)",.*|\1|p') - _eng_title=$(printf '%s' "$_entry" | sed -nE 's|.*"english":"([^"]*)".*|\1|p') - [ -z "$_eng_title" ] && _eng_title=$(printf '%s' "$_entry" | sed -nE 's|.*,"title":"([^"]*)".*|\1|p') - [ -z "$_eng_title" ] && _eng_title="N/A" - _jpn_title=$(printf '%s' "$_entry" | sed -nE 's|.*"romaji":"([^"]*)".*|\1|p') - [ -z "$_jpn_title" ] && _jpn_title="N/A" - _status=$(printf '%s' "$_entry" | sed -nE 's|.*"status":"([^"]*)".*|\1|p') - [ -z "$_status" ] && _status="Unknown" - - case "$_status" in - Ongoing) _color="33" ;; - Finished) _color="32" ;; - *) _color="36" ;; - esac - - printf "Eng: %s\n" "$_eng_title" - printf "Jpn: %s\n" "$_jpn_title" - printf "Status: \033[1;%sm%s\033[0m\n" "$_color" "$_status" - - if [ "$_status" != "Finished" ]; then - _page="$($curl_exe -s "$animeschedule/anime/$_route")" - _sub_ep=$(printf "%s" "$_page" | sed -nE 's|.*release-time-type-subs"[^>]*>Episode ([0-9]+).*|\1|p' | head -n 1) - _dub_ep=$(printf "%s" "$_page" | sed -nE 's|.*release-time-type-dub"[^>]*>Episode ([0-9]+).*|\1|p' | head -n 1) - _sub_countdown=$(printf "%s" "$_page" | sed -nE 's|.*class="countdown-time" datetime="([^"]*)".*|\1|p' | head -n 1) - _dub_countdown=$(printf "%s" "$_page" | sed -nE 's|.*class="countdown-time countdown-time-dub" datetime="([^"]*)".*|\1|p' | head -n 1) - - [ -n "$_sub_ep" ] && [ -n "$_sub_countdown" ] && - printf "Next Sub: Episode %s in \033[1;%sm%s\033[0m\n" "$_sub_ep" "$_color" "$_sub_countdown" || printf "Next Sub: N/A\n" - [ -n "$_dub_ep" ] && [ -n "$_dub_countdown" ] && - printf "Next Dub: Episode %s in \033[1;%sm%s\033[0m\n" "$_dub_ep" "$_color" "$_dub_countdown" || printf "Next Dub: N/A\n" - fi - printf "\n" - done - exit 0 -} - -# HISTORY - -backup_old_hist() { - backupfile="${histfile}.v4" - while IFS=" " read -r ep_no anime_id anime_title; do - case "$anime_id" in - *-*) printf "%s\t%s\t%s\n" "$ep_no" "$anime_id" "$anime_title" >>"${histfile}.new" ;; - *) printf "%s\t%s\t%s\n" "$ep_no" "$anime_id" "$anime_title" >>"$backupfile" ;; - esac - done <"$histfile" - mv "${histfile}.new" "$histfile" -} - -process_hist_entry() { - ep_list=$(anidb_episodes "$anime_id" | cut -f 2) - ep_no=$(printf "%s" "$ep_list" | sed -n "/^${ep_no}$/{n;p;}") 2>/dev/null - [ -n "$ep_no" ] && printf "%s\t%s - episode %s\n" "$anime_id" "$anime_title" "$ep_no" -} - -update_history() { - if grep -q " ${anime_id} " "$histfile"; then - # escape sed special chars in replacement: & and \ and delimiter | - safe_title=$(printf "%s" "$anime_title" | sed 's|[&\|]|\\&|g') - sed -E "s|^[^ ]+ ${anime_id} [^ ]+$|${ep_no} ${anime_id} ${safe_title}|" "$histfile" >"${histfile}.new" - else - cp "$histfile" "${histfile}.new" - printf "%s\t%s\t%s\n" "$ep_no" "$anime_id" "$anime_title" >>"${histfile}.new" - fi - mv "${histfile}.new" "$histfile" -} - -# PLAYING - -# shellcheck disable=SC2086 -# $1 = video link, $2 = video name, $3 = extra flags -download() { - command -v "yt-dlp" >/dev/null && yt-dlp "$1" --no-skip-unavailable-fragments --fragment-retries infinite -N 16 -o "$download_dir/$2.mp4" $3 && return 0 - ffmpeg -extension_picky 0 -loglevel error -stats -i "$1" -c copy "$download_dir/$2.mp4" $3 -} - -play_episode() { - [ "$log_episode" = 1 ] && [ "$player_function" != "debug" ] && [ "$player_function" != "download" ] && command -v logger >/dev/null && logger -t ani-cli "${anime_title} ${ep_no}" - [ "$skip_intro" = 1 ] && skip_flag="$(ani-skip -i "$mal_id" -e "$canon_ep_no")" - [ -z "$video_link" ] && get_video_link - # wait for the previous player to close (in range selection) - wait - # shellcheck disable=SC2086 - case "$player_function" in - debug) printf "All links:\n%s\nSelected link:\n%s\n" "$links" "$video_link" ;; - android_mpv) nohup am start --user 0 -a android.intent.action.VIEW -d "$video_link" -n is.xyz.mpv/.MPVActivity -e "title" "${anime_title} Episode ${ep_no}" $player_extra_flags >/dev/null 2>&1 & ;; - android_vlc) nohup am start --user 0 -a android.intent.action.VIEW -d "$video_link" -n org.videolan.vlc/org.videolan.vlc.gui.video.VideoPlayerActivity -e "title" "${anime_title} Episode ${ep_no}" $player_extra_flags >/dev/null 2>&1 & ;; - "$HOME"/.local/share/flatpak/app/io.mpv/Mpv/) flatpak run io.mpv.Mpv $skip_flag $player_extra_flags --force-media-title="${anime_title} Episode ${ep_no}" "$video_link" >/dev/null 2>&1 & ;; - *mpv*) - if [ "$no_detach" = 0 ]; then - nohup $player_function $skip_flag $player_extra_flags --force-media-title="${anime_title} Episode ${ep_no}" "$video_link" >/dev/null 2>&1 & - else - $player_function $skip_flag $player_extra_flags --force-media-title="${anime_title} Episode ${ep_no}" "$video_link" - mpv_exitcode=$? - [ "$exit_after_play" = 1 ] && [ -z "$_range" ] && exit "$mpv_exitcode" - fi - ;; - *iina*) - if pgrep -f "IINA" >/dev/null 2>&1; then - # omit --keep-running when an IINA instance exists to prevent hanging - nohup $player_function $player_extra_flags --no-stdin --mpv-force-media-title="${anime_title} Episode ${ep_no}" "$video_link" >/dev/null 2>&1 & - else - nohup $player_function $player_extra_flags --no-stdin --keep-running --mpv-force-media-title="${anime_title} Episode ${ep_no}" "$video_link" >/dev/null 2>&1 & - fi - ;; - *vlc*) nohup $player_function $player_extra_flags --play-and-exit --meta-title="${anime_title} Episode ${ep_no}" "$video_link" >/dev/null 2>&1 & ;; - *yncpla*) nohup $player_function $player_extra_flags "$video_link" -- --force-media-title="${anime_title} Episode ${ep_no}" >/dev/null 2>&1 & ;; - download) "$player_function" "$video_link" "${anime_title} Episode ${ep_no}" $player_extra_flags ;; - catt) nohup catt cast $player_extra_flags "$video_link" >/dev/null 2>&1 & ;; - iSH) - printf "\033]8;;vlc://%s\a~~~~~~~~~~~~~~~~~~~~\n~ Tap to open VLC ~\n~~~~~~~~~~~~~~~~~~~~\033]8;;\a\n" "$video_link" - sleep 5 - ;; - *) nohup $player_function $player_extra_flags "$video_link" >/dev/null 2>&1 & ;; - esac - replay="$video_link" - unset video_link - update_history - [ "$menu_program" != "fzf" ] && wait -} - -play() { - _start=$(printf "%s" "$ep_no" | grep -Eo '^(-1|[0-9]+(\.[0-9]+)?)') - _end=$(printf "%s" "$ep_no" | grep -Eo '(-1|[0-9]+(\.[0-9]+)?)$') - [ "$_start" = "-1" ] && ep_no=$(printf "%s" "$ep_list" | tail -n 1) && unset _start - [ -z "$_end" ] || [ "$_end" = "$_start" ] && unset _start _end - [ "$_end" = "-1" ] && _end=$(printf "%s" "$ep_list" | tail -n 1) - _line_count=$(printf "%s\n" "$ep_no" | wc -l | tr -d "[:space:]") - if [ "$_line_count" != 1 ] || [ -n "$_start" ]; then - [ -z "$_start" ] && _start=$(printf "%s\n" "$ep_no" | head -n 1) - [ -z "$_end" ] && _end=$(printf "%s\n" "$ep_no" | tail -n 1) - _range=$(printf "%s\n" "$ep_list" | sed -nE "/^${_start}\$/,/^${_end}\$/p") - [ -z "$_range" ] && die "Invalid range!" - for i in $_range; do - tput clear - ep_no=$i - canon_ep_no="$(printf "%s" "$ep_list" | sed -n "/^${ep_no}$/=")" - info "Playing episode $ep_no..." - [ "$i" = "$_end" ] && unset _range - play_episode - done - else - printf "%s" "$ep_list" | grep -q "^$ep_no$" || die "Invalid episode!" - canon_ep_no="$(printf "%s" "$ep_list" | sed -n "/^${ep_no}$/=")" - play_episode - fi - # moves up to stored position and deletes to end - [ "$player_function" != "debug" ] && [ "$player_function" != "download" ] && tput rc && tput ed -} - -# MAIN - -# setup -base_api="https://anidb.app" -search_api="${base_api}/browse?q=%s" -# search_api_alt="${base_api}/search/suggestions?q=%s" -desc_api="${base_api}/anime/%s" -episodes_api="${base_api}/api/frontend/anime/%s/episodes" -m3u8_api="${base_api}/api/frontend/episode/%s/languages" - -ciphers='ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305' -tls13_ciphers='TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256' -agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" - -mode="${ANI_CLI_MODE:-sub}" -download_dir="${ANI_CLI_DOWNLOAD_DIR:-.}" -log_episode="${ANI_CLI_LOG:-1}" -quality="${ANI_CLI_QUALITY:-best}" - -curl_exe=$(dep_ch_failover "curl_firefox135,curl_chrome136,curl_chrome116,curl_ff117,curl") || die "Program curl not found" - -case "$(uname -a | cut -d " " -f 1,3-)" in - *Darwin*) - cipher_flag="--ciphers $ciphers --tls13-ciphers $tls13_ciphers" - player_function="${ANI_CLI_PLAYER:-$(dep_ch_failover "iina,/Applications/IINA.app/Contents/MacOS/iina-cli,mpv,vlc")}" || die 'No player found. Looked for iina, mpv and vlc' - ;; # mac OS - *ndroid*) player_function="${ANI_CLI_PLAYER:-android_mpv}" ;; # Android OS (termux) - *MINGW* | *WSL2*) player_function="${ANI_CLI_PLAYER:-mpv.exe}" ;; # Windows OS - *ish*) - player_function="${ANI_CLI_PLAYER:-iSH}" - curl_exe=$(dep_ch_failover "curl_safari260_ios,$curl_exe") - ;; # iOS (iSH) - *) player_function="${ANI_CLI_PLAYER:-$(dep_ch_failover "mpv,$HOME/.local/share/flatpak/app/io.mpv/Mpv/,vlc")}" || die 'No player found. Looked for mpv and vlc' ;; # Linux OS -esac - -player_extra_flags="${ANI_CLI_PLAYER_FLAGS:-""}" -no_detach="${ANI_CLI_NO_DETACH:-0}" -exit_after_play="${ANI_CLI_EXIT_AFTER_PLAY:-0}" -skip_intro="${ANI_CLI_SKIP_INTRO:-0}" -menu_program="${ANI_CLI_MENU:-fzf}" -menu_extra_flags="${ANI_CLI_MENU_FLAGS:-""}" - -# not opening from a terminal -if [ ! -t 0 ]; then - command -v dmenu >/dev/null && menu_program=dmenu - command -v rofi >/dev/null && menu_program=rofi -fi - -hist_dir="${ANI_CLI_HIST_DIR:-${XDG_STATE_HOME:-$HOME/.local/state}/ani-cli}" -[ ! -d "$hist_dir" ] && mkdir -p "$hist_dir" -histfile="$hist_dir/ani-hsts" -[ ! -f "$histfile" ] && : >"$histfile" - -source="${ANI_CLI_DEFAULT_SOURCE:-search}" -branch="${ANI_CLI_BRANCH:-master}" - -while [ $# -gt 0 ]; do - case "$1" in - -v | --vlc) - case "$(uname -a | cut -d " " -f 1,3-)" in - *ndroid*) player_function="android_vlc" ;; - MINGW* | *WSL2*) player_function="vlc.exe" ;; - *ish*) player_function="iSH" ;; - *) player_function="vlc" ;; - esac - ;; - -s | --syncplay) - case "$(uname -s)" in - Darwin*) player_function="/Applications/Syncplay.app/Contents/MacOS/syncplay" ;; - MINGW* | *Msys) - export PATH="$PATH":"/c/Program Files (x86)/Syncplay/" - player_function="syncplay.exe" - ;; - *) player_function="syncplay" ;; - esac - ;; - -q | --quality) - [ $# -lt 2 ] && die "missing argument!" - quality="$2" - shift - ;; - -S | --select-nth) - [ $# -lt 2 ] && die "missing argument!" - index="$2" - shift - ;; - -c | --continue) source=history ;; - -d | --download) - player_function=download - ;; - -D | --delete) - : >"$histfile" - exit 0 - ;; - -l | --logview) - case "$(uname -s)" in - Darwin*) log show --predicate 'process == "logger"' ;; - Linux*) journalctl -t ani-cli ;; - *) die "Logger not implemented for your platform" ;; - esac - exit 0 - ;; - -V | --version) version_info ;; - -h | --help) help_info ;; - -e | --episode | -r | --range) - [ $# -lt 2 ] && die "missing argument!" - ep_no="$2" - shift - ;; - --dub) mode="dub" ;; - --no-detach) no_detach=1 ;; - --exit-after-play) exit_after_play=1 && no_detach=1 ;; - --rofi) menu_program=rofi ;; - --dmenu) menu_program=dmenu ;; - --skip) skip_intro=1 ;; - -N | --nextep-countdown) source=nextep ;; - -U | --update) - dep_ch "patch" - branch="${2:-$branch}" - update_script - ;; - *) query="$(printf "%s" "$query $1" | sed 's|^ ||;s| |+|g')" ;; - esac - shift -done - -[ "$menu_program" = "fzf" ] && menu_multi_flag="-m" -[ "$menu_program" = "rofi" ] && menu_multi_flag="-multi-select" - -info "Checking dependencies..." -dep_ch "sed" -dep_ch "grep" -[ "$skip_intro" = 1 ] && dep_ch "ani-skip" -dep_ch "$menu_program" # TODO: use dep_ch_failover to iterate through options - -case "$player_function" in - debug) ;; - download) dep_ch_failover "yt-dlp,ffmpeg" >/dev/null || die 'Neither yt-dlp nor ffmpeg found' ;; - android*) printf "\33[2K\rChecking of players on Android is disabled.\n" ;; - *iSH*) printf "\33[2K\rChecking of players on iOS is disabled\n" ;; - *) dep_ch "$player_function" ;; -esac - -# idk where to put this, so I put it here... -trap 'cleanup; exit 1' INT HUP TERM - -# searching -case "$source" in - history) - backup_old_hist - anime_list=$(while read -r ep_no anime_id anime_title; do process_hist_entry & done <"$histfile") - wait - [ -z "$anime_list" ] && die "No unwatched series in history!" - [ -z "${index##*[!0-9]*}" ] && anime_id=$(printf "%s" "$anime_list" | nl -w 2 | sed 's/^[[:space:]]//' | nth "Select anime: " | cut -f 1) - [ -z "${index##*[!0-9]*}" ] || anime_id=$(printf "%s" "$anime_list" | sed -n "${index}p" | cut -f 1) - [ -z "$anime_id" ] && exit 1 - anime_title=$(printf "%s" "$anime_list" | grep "^$anime_id " | cut -f 2 | sed 's| - episode.*||') - anidb_desc "$anime_id" || true - episode_maps="$(anidb_episodes "$anime_id")" - ep_list="$(printf "%s" "$episode_maps" | cut -f 2)" - ep_no=$(printf "%s" "$anime_list" | grep "^$anime_id " | sed -nE 's/.*- episode (.+)$/\1/p') - ;; - *) - if [ "$menu_program" = "fzf" ]; then - while [ -z "$query" ]; do - printf "\33[2K\r\033[1;36mSearch anime: \033[0m" && read -r query - done - else - [ -z "$query" ] && query=$(: | menu "Search anime: " "" "$menu_extra_flags") - [ -z "$query" ] && exit 1 - fi - # for checking new releases by specifying anime name - [ "$source" = "nextep" ] && time_until_next_ep "$query" - - query=$(printf "%s" "$query" | sed 's| |+|g') - - anime_list=$(anidb_search "$query") - [ -z "$anime_list" ] && die "No results found!" - [ "$index" -eq "$index" ] 2>/dev/null && result=$(printf "%s" "$anime_list" | sed -n "${index}p") - [ -z "$index" ] && result=$(printf "%s" "$anime_list" | nl -w 2 | sed 's/^[[:space:]]//' | nth "Select anime: ") - [ -z "$result" ] && die "Invalid anime selection" - anime_title="$(printf "%s" "$result" | cut -f 2)" - anime_id="$(printf "%s" "$result" | cut -f 1)" - anidb_desc "$anime_id" || true - episode_maps="$(anidb_episodes "$anime_id")" - ep_list="$(printf '%s' "$episode_maps" | cut -f 2)" - [ -z "$ep_no" ] && ep_no=$(printf "%s" "$ep_list" | nth "Select episode: " "$menu_multi_flag") - [ -z "$ep_no" ] && die "Invalid episode selection" - ;; -esac - -# moves the cursor up one line and clears that line -tput cuu1 && tput el -# stores the position of cursor -tput sc - -# playback & loop -play -[ "$player_function" = "download" ] || [ "$player_function" = "debug" ] && exit 0 - -#shellcheck disable=SC2059 -while cmd=$(printf "next\nreplay\nprevious\nselect$seasons_option\nchange_quality\nquit" | nth "Playing episode $ep_no of $anime_title... "); do - case "$cmd" in - next) ep_no=$(printf "%s" "$ep_list" | sed -n "/^${ep_no}$/{n;p;}") 2>/dev/null ;; - replay) video_link="$replay" ;; - previous) ep_no=$(printf "%s" "$ep_list" | sed -n "/^${ep_no}$/{g;1!p;};h") 2>/dev/null ;; - select) ep_no=$(printf "%s" "$ep_list" | nth "Select episode: " "$menu_multi_flag") ;; - change_season) - new_anime="$(printf "%s" "$seasons" | nl -w 2 | sed 's/^[[:space:]]//' | nth "Select season: ")" - [ -z "$new_anime" ] && die "Invalid season selection" - anime_title="$(printf "%s" "$new_anime" | cut -f 2)" - anime_id="$(printf "%s" "$new_anime" | cut -f 1)" - anidb_desc "$anime_id" || true - episode_maps="$(anidb_episodes "$anime_id")" - ep_list="$(printf '%s' "$episode_maps" | cut -f 2)" - ep_no=$(printf "%s" "$ep_list" | nth "Select episode: " "$menu_multi_flag") - [ -z "$ep_no" ] && die "Invalid episode selection" - ;; - change_quality) - new_quality="$(printf "%s" "$links" | menu "Select Quality: " "" "$menu_extra_flags" | cut -d ">" -f 1)" - [ -z "$new_quality" ] && die "No quality selected" - select_quality "$new_quality" - ;; - *) - cleanup - exit 0 - ;; - esac - [ -z "$ep_no" ] && die "Out of range" - play -done - -# ani-cli -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see