solorice/local/bin/ani-skip.bak

166 lines
5.5 KiB
Bash

#!/bin/sh
version_number="1.0.1"
agent="Mozilla/5.0 (Windows NT 6.1; Win64; rv:109.0) Gecko/20100101 Firefox/109.0"
chapter_format="\n[CHAPTER]\nTIMEBASE=1/1000\nSTART=%s\nEND=%s\nTITLE=%s\n"
option_format="skip-%s_start=%s,skip-%s_end=%s"
die() {
printf "\33[2K\r\033[1;31m%s\033[0m\n" "$*" >&2
exit 1
}
help_info() {
printf "
Usage:
%s [OPTIONS]
Options:
-q, --query
Anime Title or MyAnimeList ID
-e, --episode
Specify the episode number
-V, --version
Show the version of the script
-h, --help
Show this help message and exit
-U, --update
Update the script
Some example usages:
%s -q \"Solo Leveling\" # Returns MyAnimeList ID
%s -q \"Solo Leveling\" -e 3 # Returns MPV skip flag
%s -q 52299 -e 5 # Returns MPV skip flag
\n" "${0##*/}" "${0##*/}" "${0##*/}" "${0##*/}"
exit 0
}
update_script() {
update="$(curl -s -A "$agent" "https://raw.githubusercontent.com/synacktraa/ani-skip/master/ani-skip")" || die "Connection error"
update="$(printf '%s\n' "$update" | diff -u "$0" -)"
if [ -z "$update" ]; then
printf "Script is up to date :)\n"
else
if printf '%s\n' "$update" | patch "$0" -; then
printf "Script has been updated\n"
else
die "Can't update for some reason!"
fi
fi
exit 0
}
fetch_mal_id() {
#shellcheck disable=SC2016
: '
`fetch_mal_id` fetches MyAnimeList Identifier of particular anime
:param $1: title of the anime
'
name=$(printf "%s" "$*" | sed 's| (\([0-9]*\) episodes)||')
keyword=$(printf "%s" "$name" | tr -c '[:alnum:]' ' ' | sed -E 's| |%20|g')
mal_metadata=$(curl -sL -A "$agent" "https://myanimelist.net/search/prefix.json?type=anime&keyword=$keyword" | tr -d "\\" 2>/dev/null)
name=$(printf "%s\n" "$name" | tr -cs '[:print:]' ' ' | tr -c '[:alnum:]' ' ')
fzf_nth=$(printf "%s," $(seq 1 "$(printf "%s" "$name" | wc -w)") | sed 's|,$||')
results=$(printf "%s" "$mal_metadata" | sed 's|},{|\n|g' | sed 's|.*,"name":"||g ; s|","url":".*||g')
relevant_name=$(printf "%s" "$results" | fzf -i --filter="$name" --nth="$fzf_nth" | head -n1)
[ -z "$relevant_name" ] && relevant_name=$(printf "%s" "$results" | fzf -i --filter="$name" | head -n1)
[ -z "$relevant_name" ] && relevant_name=$(printf "%s" "$results" | head -n1)
printf "%s" "$mal_metadata" | sed 's|},{|\n|g' | grep 'name":"'"$relevant_name"'","url":' | sed -nE 's|.*"id":([0-9]{1,9}),.*|\1|p'
}
ftoi() {
printf "%.3f" "$1" | tr -d '.'
}
build_options() {
#shellcheck disable=SC2016
: '
`build_options` builds options for `--script-opts` flag
:param $1: AniSkip metadata
'
st_time_re='"start_time":([0-9.]+)'
ed_time_re='"end_time":([0-9.]+)'
op_end=""
ed_start=""
options=""
for skip_type in "op" "ed"
do
sk_type_re='"skip_type":"('$skip_type')"'
unformatted=$(printf "%s" "$1" | grep -Eo "$st_time_re,$ed_time_re},$sk_type_re")
if [ -n "$unformatted" ]; then
st_time=$(printf "%s" "$unformatted" | grep -Eo "$st_time_re" | sed -E 's@'"$st_time_re"'@\1@')
ed_time=$(printf "%s" "$unformatted" | grep -Eo "$ed_time_re" | sed -E 's@'"$ed_time_re"'@\1@')
[ "$skip_type" = "op" ] && op_end=$ed_time && ch_name="Opening"
[ "$skip_type" = "ed" ] && ed_start=$st_time && ch_name="Ending"
[ -n "$options" ] && options="$options,"
printf "$chapter_format" "$(ftoi $st_time)" "$(ftoi $ed_time)" "$ch_name" >> $chapters_file
options=$(printf "%s%s" "$options" $(printf "$option_format" "$skip_type" "$st_time" "$skip_type" "$ed_time"))
fi
done
if [ -n "$op_end" ]; then
[ -n "$ed_start" ] && ep_ed=$ed_start || ep_ed=$op_end
printf "$chapter_format" "$(ftoi $op_end)" "$(ftoi $ep_ed)" "Episode" >> $chapters_file
fi
printf "%s" "$options"
}
build_flags() {
#shellcheck disable=SC2016
: '
`build_flags` builds `--script-opts` and `--chapters-file` flags for MPV player
:param $1: MyAnimeList Identifier
:param $2: Episode number
'
aniskip_api="https://api.aniskip.com/v1/skip-times/$1/$2?types=op&types=ed"
metadata=$(curl -s --connect-timeout 5 -A "$agent" "$aniskip_api")
found_status=$(printf "%s" "$metadata" | sed -n 's/.*"found":\([^,]*\).*/\1/p')
[ "$found_status" != "true" ] && die "Skip times not found!"
printf "%s" ";FFMETADATA1" > "$chapters_file"
options=$(build_options "$metadata")
[ -n "$options" ] && printf -- "--chapters-file=%s --script-opts=%s" "$chapters_file" "$options"
}
[ $# -eq 0 ] && help_info
while [ $# -gt 0 ]; do
[ "$OSTYPE" = msys* ] && flag=${1//[![:print:]]/} || flag="$1"
case "$flag" in
-U | --update) update_script ;;
-V | --version) printf "%s\n" "$version_number" && exit 0 ;;
-h | --help) help_info ;;
-q | --query)
[ $# -lt 2 ] && die "missing anime title/MyAnimeList ID!"
case $2 in
''|*[!0-9]*) mal_id=$(fetch_mal_id $2) ;;
*) mal_id=$2 ;;
esac
shift
;;
-e | --episode)
[ $# -lt 2 ] && die "missing episode number!"
case $2 in
''|*[!0-9]*) die "value must be a number!" ;;
*) episode=$2 ;;
esac
esac
shift
done
[ -z "$mal_id" ] && die "-q/--query is required!"
if [ -z "$episode" ]; then
printf "%s" "$mal_id"
else
chapters_file=$(mktemp)
build_flags $mal_id $episode
fi