mirror of
https://github.com/kristoferssolo/solorice.git
synced 2025-10-21 20:10:34 +00:00
166 lines
5.5 KiB
Bash
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
|