ani-cli-npm 2.1.3 → 2.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/temp.sh ADDED
@@ -0,0 +1,676 @@
1
+
2
+ #!/bin/sh
3
+
4
+ #---
5
+ #dependencies:
6
+ # curl.se: ^7.8
7
+ # openssl.org: ^1.1
8
+ # ffmpeg.org: ^5.1
9
+ #---
10
+
11
+ # License preamble at the end of the file
12
+ # Version number
13
+ VERSION="3.4.7"
14
+
15
+
16
+ #######################
17
+ # AUXILIARY FUNCTIONS #
18
+ #######################
19
+
20
+ help_text () {
21
+ while read -r line; do
22
+ printf "%s\n" "$line"
23
+ done <<-EOF
24
+ Usage:
25
+ ${0##*/} [-f] [-s] [-v] [-x] [-q <quality>] [-a <episode>] [-d | -p <download_dir>] [<query>] [-r <provider_no.>]
26
+ ${0##*/} [-f] [-s] [-v] [-x] [-q <quality>] -c
27
+ ${0##*/} -h | -D | -U | -V
28
+ Options:
29
+ -v use VLC as the media player
30
+ -q set video quality (best|worst|360|480|720|1080)
31
+ -s watch anime together with friends, using Syncplay (works with mpv only)
32
+ -f use fzf for anime selection
33
+ -a specify episode to watch
34
+ -d download episode
35
+ -p download episode to specified directory
36
+ -c continue watching anime from history
37
+ -h show helptext
38
+ -D delete history
39
+ -U fetch update from github
40
+ -V print version number and exit
41
+ -r select provider to scrape first [1-3]
42
+ -x print all video links from all providers to stdout (for debugging purpose)
43
+ Episode selection:
44
+ Multiple episodes can be chosen given a range
45
+ Choose episode [1-13]: 1 6
46
+ This would choose episodes 1 2 3 4 5 6
47
+ To select the last episode use -1
48
+ When selecting non-interactively, the first result will be
49
+ selected, if anime is passed
50
+ EOF
51
+ }
52
+
53
+ retry () {
54
+ err "$*"
55
+ prompt
56
+ }
57
+
58
+ # display an error message to stderr (in red)
59
+ err () {
60
+ printf "\33[2K\r\033[1;31m%s\033[0m\n" "$*" >&2
61
+ }
62
+
63
+ #display error message and exit
64
+ die () {
65
+ err "$*"
66
+ exit 1
67
+ }
68
+
69
+ # display an informational message (first argument in green, second in magenta)
70
+ inf () {
71
+ printf "\33[2K\r\033[1;35m%s \033[1;35m%s\033[0m\n" "$1" "$2"
72
+ }
73
+
74
+ progress() {
75
+ printf "\33[2K\r\033[1;34m%s\033[0m" "$1"
76
+ }
77
+
78
+ debug () {
79
+ printf "\n\033[1;32mReferrer :\033[0m %s\n\033[1;32mlinks >>\n\033[0m%s\n" "$1" "$2"
80
+ }
81
+
82
+ # 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
83
+ prompt () {
84
+ [ -n "$*" ] && printf "\33[2K\r\033[1;35m%s\n" "$*"
85
+ printf "\033[1;35m> \033[0m"
86
+ read -r REPLY REPLY2
87
+ }
88
+
89
+ selection_menu() {
90
+ menu_line_parity=0
91
+ while read -r option line; do
92
+ if [ "$option" = "q" ]; then
93
+ printf "\033[1;31m(\033[1;31m%s\033[1;31m) \033[1;31m%s\033[0m\n" "$option" "$line"
94
+ else
95
+ if [ "$menu_line_parity" -eq 0 ]; then
96
+ printf "\033[1;33m(\033[1;33m%s\033[1;33m) \033[1;33m%s\033[0m\n" "$option" "$line"
97
+ menu_line_parity=1
98
+ else
99
+ printf "\033[1;36m(\033[1;36m%s\033[1;36m) \033[1;36m%s\033[0m\n" "$option" "$line"
100
+ menu_line_parity=0
101
+ fi
102
+ fi
103
+ done <<-EOF
104
+ $*
105
+ EOF
106
+ prompt
107
+ }
108
+
109
+ selection_menu_fzf() {
110
+ printf "%s\n%s" "$1" "$2" | fzf --height=30% --border -1 --layout=reverse --header-first --header-lines=1 --cycle --with-nth 2.. | cut -d\ -f1
111
+ }
112
+
113
+ version_text () {
114
+ inf "Version: $VERSION"
115
+ }
116
+
117
+ # get the newest version of this script from github and replace it
118
+ update_script () {
119
+ update="$(curl -A "$agent" -s "https://raw.githubusercontent.com/pystardust/ani-cli/master/ani-cli")" || die "Connection error"
120
+ update="$(printf '%s\n' "$update" | diff -u "$0" -)"
121
+ if [ -z "$update" ]; then
122
+ inf "Script is up to date :)"
123
+ else
124
+ if printf '%s\n' "$update" | patch "$0" - ; then
125
+ inf "Script has been updated"
126
+ else
127
+ die "Can't update for some reason!"
128
+ fi
129
+ fi
130
+ exit 0
131
+ }
132
+
133
+ # checks if dependencies are present
134
+ dep_ch () {
135
+ for dep; do
136
+ if ! command -v "$dep" >/dev/null ; then
137
+ die "Program \"$dep\" not found. Please install it."
138
+ fi
139
+ done
140
+ }
141
+
142
+ download () {
143
+ case $2 in
144
+ *m3u8*)
145
+ ffmpeg -loglevel error -stats -referer "$1" -i "$2" -c copy "$download_dir/$3.mp4" ;;
146
+ *)
147
+ axel -a -k -n 10 --header=Referer:"$1" "$2" -o "$download_dir/$3.mp4" ;;
148
+ esac
149
+ }
150
+
151
+ #############
152
+ # SEARCHING #
153
+ #############
154
+
155
+ # gets anime names along with its id for search term
156
+ search_anime () {
157
+ search=$(printf '%s' "$1" | tr ' ' '-' )
158
+ curl -s "https://gogoanime.dk//search.html?keyword=$search" -L |
159
+ sed -nE "s_^[[:space:]]*<a href=\"/category/([^\"]*)\" title.*\">\$_\1_p"
160
+ }
161
+
162
+ #fetches all the episodes embed links in an anime from gogoanime server
163
+ episode_list () {
164
+ select_ep_result=$(curl -A "$agent" -s "$base_url/v1/$1" | sed -nE "s_.*epslistplace.*>(.*)</div>_\1_p" | tr "," "\n" | sed -e '/extra/d' -e '/PV/d' | sed -nE 's_".*":"(.*)".*_\1_p')
165
+ first_ep_number=1
166
+ [ -z "$select_ep_result" ] && last_ep_number=0 || last_ep_number=$(printf "%s\n" "$select_ep_result" | wc -l)
167
+ }
168
+
169
+ process_hist_entry () {
170
+ temp_anime_id=$(printf "%s" "$anime_id" | sed 's/\t[0-9]*.$//')
171
+ current_ep=$(printf "%s" "$anime_id" | sed "s/$temp_anime_id\t//g")
172
+ episode_list "$temp_anime_id"
173
+ latest_ep=$last_ep_number
174
+ if [ -n "$latest_ep" ] && [ "$latest_ep" -ge "$current_ep" ]; then
175
+ printf "%s : %s / %s\n" "$temp_anime_id" "$current_ep" "$latest_ep"
176
+ fi
177
+ }
178
+
179
+ # compares history with gogoplay, only shows unfinished anime
180
+ search_history () {
181
+ [ ! -s "$logfile" ] && die "History is empty"
182
+ progress "Processing $scrape.."
183
+ search_results=$(while read -r anime_id; do process_hist_entry & done < "$logfile"; wait)
184
+ [ -z "$search_results" ] && die "No unwatched episodes"
185
+ one_hist=$(printf '%s\n' "$search_results" | grep -e "$" -c)
186
+ [ "$one_hist" = 1 ] && select_first=1
187
+ anime_selection "$search_results"
188
+ ep_choice_start=$(sed -n -E "s/${selection_id}\t(.*)/\1/p" "$logfile")
189
+ }
190
+
191
+ ##################
192
+ # URL PROCESSING #
193
+ ##################
194
+
195
+ generate_link() {
196
+ case $1 in
197
+ 2)
198
+ provider_name='Xstreamcdn'
199
+ progress "Fetching $provider_name links.."
200
+ fb_id=$(printf "%s" "$resp" | sed -n "s_.*fembed.*/v/__p")
201
+ refr="https://fembed-hd.com/v/$fb_id"
202
+ [ -z "$fb_id" ] && return 0
203
+ result_links="$(curl -A "$agent" -s -X POST "https://fembed-hd.com/api/source/$fb_id" -H "x-requested-with:XMLHttpRequest" |
204
+ sed -e 's/\\//g' -e 's/.*data"://' | tr "}" "\n" | sed -nE 's/.*file":"(.*)","label":"(.*)","type.*/\2>\1/p')"
205
+ ;;
206
+ 1)
207
+ provider_name='Animixplay'
208
+ progress "Fetching $provider_name Direct link.."
209
+ refr="$base_url"
210
+ [ -z "$id" ] && return 0
211
+ enc_id=$(printf "%s" "$id" | base64)
212
+ ani_id=$(printf "%sLTXs3GrU8we9O%s" "$id" "$enc_id" | base64)
213
+ result_links="$(curl -s "$base_url/api/cW9${ani_id}" -A "$agent" -I | sed -nE 's_[L|l]ocation: https?://[^#]*#([^#]*).*_\1_p' | base64 -d)"
214
+ ;;
215
+ *)
216
+ provider_name='Gogoanime'
217
+ progress "Fetching $provider_name Direct link.."
218
+ refr="$gogohd_url"
219
+ [ -z "$id" ] && return 0
220
+ secret_key=$(printf "%s" "$resp" | sed -n '2p' | tr -d "\n" | od -A n -t x1 | tr -d " |\n")
221
+ echo "secret_key: $secret_key"
222
+ iv=$(printf "%s" "$resp" | sed -n '3p' | tr -d "\n" | od -A n -t x1 | tr -d " |\n")
223
+ echo "iv: $iv"
224
+ second_key=$(printf "%s" "$resp" | sed -n '4p' | tr -d "\n" | od -A n -t x1 | tr -d " |\n")
225
+ echo "second_key: $second_key"
226
+ token=$(printf "%s" "$resp" | head -1 | base64 -d | openssl enc -d -aes256 -K "$secret_key" -iv "$iv" | sed -nE 's/.*&(token.*)/\1/p')
227
+ echo "token: $token"
228
+ ajax=$(printf '%s' "$id" | openssl enc -e -aes256 -K "$secret_key" -iv "$iv" -a)
229
+ echo "ajax: $ajax"
230
+ data=$(curl -A "$agent" -sL -H "X-Requested-With:XMLHttpRequest" "${gogohd_url}encrypt-ajax.php?id=${ajax}&alias=${id}&${token}" | sed -e 's/{"data":"//' -e 's/"}/\n/' -e 's/\\//g')
231
+ echo "data: $data"
232
+ result_links="$(printf '%s' "$data" | base64 -d 2>/dev/null | openssl enc -d -aes256 -K "$second_key" -iv "$iv" 2>/dev/null |
233
+ tr -d \\\\ | sed -nE "s_.*file\":\"([^\"]*)\".*source.*_\1_p")"
234
+ echo "result_links: $result_links"
235
+ ;;
236
+
237
+ esac
238
+ }
239
+
240
+ # chooses the link for the set quality
241
+ get_video_link() {
242
+ dpage_url="$1"
243
+ id=$(printf "%s" "$dpage_url" | sed -nE 's/.*id=([^&]*).*/\1/p')
244
+ #multiple sed are used (regex seperated by ';') for extracting only required data from response of embed url
245
+ resp="$(curl -A "$agent" -sL "${gogohd_url}streaming.php?id=$id" |
246
+ sed -nE 's/.*class="container-(.*)">/\1/p ;
247
+ s/.*class="wrapper container-(.*)">/\1/p ;
248
+ s/.*class=".*videocontent-(.*)">/\1/p ;
249
+ s/.*data-value="(.*)">.*/\1/p ;
250
+ s/.*data-status="1".*data-video="(.*)">.*/\1/p')"
251
+ provider=1
252
+ [ -n "$select_provider" ] && provider="$select_provider"
253
+ i=0
254
+ while [ "$i" -lt 3 ] && [ -z "$result_links" ];do
255
+ generate_link "$provider"
256
+ provider=$((provider % 3 + 1))
257
+ if [ "$debug" -eq 1 ]; then
258
+ debug "$refr" "$result_links"
259
+ unset result_links
260
+ fi
261
+ : $((i+=1))
262
+ done
263
+ [ "$debug" -eq 1 ] && return 0
264
+ if printf '%s' "$result_links" | grep -q "m3u8"; then
265
+ get_video_quality_m3u8 "$result_links"
266
+ else
267
+ video_url=$(get_video_quality_mp4 "$result_links")
268
+ fi
269
+ unset result_links
270
+ }
271
+
272
+ get_video_quality_mp4() {
273
+ case $quality in
274
+ best)
275
+ video_url=$(printf '%s' "$1" | tail -n 1 | cut -d">" -f2) ;;
276
+ worst)
277
+ video_url=$(printf '%s' "$1" | head -n 1 | cut -d">" -f2) ;;
278
+ *)
279
+ video_url=$(printf '%s' "$1" | grep -i "${quality}p" | head -n 1 | cut -d">" -f2)
280
+ if [ -z "$video_url" ]; then
281
+ err "Current video quality is not available (defaulting to best quality)"
282
+ video_url=$(printf '%s' "$1" | tail -n 1 | cut -d">" -f2)
283
+ fi
284
+ ;;
285
+ esac
286
+ printf '%s' "$video_url"
287
+ }
288
+
289
+ get_video_quality_m3u8() {
290
+ printf '%s' "$1" | grep -qE "manifest.*m3u.*" && video_url=$1 && return 0
291
+ m3u8_links=$(curl -A "$agent" -s --referer "$dpage_link" "$1")
292
+ case $quality in
293
+ best)
294
+ res_selector=$(printf "%s" "$m3u8_links" | sed -nE 's_.*RESOLUTION=.*x([^,]*).*_\1_p' | sort -nr | head -1);;
295
+ worst)
296
+ res_selector=$(printf "%s" "$m3u8_links" | sed -nE 's_.*RESOLUTION=.*x([^,]*).*_\1_p' | sort -nr | tail -1);;
297
+ *)
298
+ res_selector=$quality
299
+ if ! (printf '%s' "$m3u8_links" | grep -q "x$quality"); then
300
+ err "Current video quality is not available (defaulting to best quality)"
301
+ res_selector=$(printf "%s" "$m3u8_links" | sed -nE 's_.*RESOLUTION=.*x([^,]*).*_\1_p' | sort -nr | head -1)
302
+ fi
303
+ ;;
304
+ esac
305
+ video_url=$(printf '%s' "$m3u8_links" | sed -n "/x$res_selector/{n;p;}" | tr -d '\r')
306
+ printf "%s" "$m3u8_links" | grep -q "http" || video_url="$(printf "%s" "$1" | sed 's|[^/]*$||')$video_url" || true
307
+ }
308
+
309
+
310
+ #################
311
+ # INPUT PARSING #
312
+ #################
313
+
314
+ append () {
315
+ [ -z "$1" ] || printf "%s\n" "$1"
316
+ printf "%s %s" "$3" "$2"
317
+ }
318
+
319
+ # only lets the user pass in case of a valid search
320
+ process_search () {
321
+ progress "Searching $scrape.."
322
+ search_results=$(search_anime "$query")
323
+ while [ -z "$search_results" ]; do
324
+ retry 'No search results found'
325
+ query="$REPLY $REPLY2"
326
+ progress "Searching $scrape.."
327
+ search_results=$(search_anime "$query")
328
+ done
329
+ anime_selection "$search_results"
330
+ episode_selection
331
+ }
332
+
333
+ # anime-selection menu handling function
334
+ anime_selection () {
335
+ if [ "$fzf" -eq 0 ];then
336
+ inf "$scrape Results >>"
337
+ else
338
+ progress ""
339
+ fi
340
+ count=1
341
+ unset selection_list
342
+ while read -r anime_id; do
343
+ displayed_title=$(printf '%s' "$anime_id" | tr '-' ' ')
344
+ selection_list=$(append "$selection_list" "$displayed_title" "$count")
345
+ : $((count+=1))
346
+ done <<-EOF
347
+ $search_results
348
+ EOF
349
+ if [ -n "$select_first" ]; then
350
+ tput clear
351
+ choice=1
352
+ elif [ -z "$ep_choice_to_start" ] || { [ -n "$ep_choice_to_start" ] && [ -z "$select_first" ]; }; then
353
+ selection_list=$(append "$selection_list" "quit" "q")
354
+ if [ "$fzf" -eq 1 ]; then
355
+ choice=$(selection_menu_fzf ". $scrape Results>>" "$selection_list")
356
+ [ -z "$choice" ] && exit 0
357
+ else
358
+ selection_menu "$selection_list"
359
+ choice="$REPLY"
360
+ [ -z "$choice" ] && choice=1
361
+ fi
362
+ while ! [ "$choice" -eq "$choice" ] 2>/dev/null || [ "$choice" -lt 1 ] || [ "$choice" -ge "$count" ] || [ "$choice" = " " ]; do
363
+ [ "$choice" = "q" ] && exit 0
364
+ retry "Invalid choice entered"
365
+ choice="$REPLY"
366
+ done
367
+ fi
368
+ # Select respective anime_id
369
+ selection_id="$(printf "%s" "$search_results" | sed -n "${choice}p" | cut -d':' -f1 | tr -d ' ')"
370
+ progress "Searching Episodes.."
371
+ episode_list "$selection_id"
372
+ }
373
+
374
+ # gets episode number from user, makes sure it's in range, skips input if only one episode exists
375
+ episode_selection () {
376
+ [ "$last_ep_number" -eq 0 ] && die "Episodes not released yet!"
377
+ if [ "$last_ep_number" -gt "$first_ep_number" ]; then
378
+ [ "$ep_choice_to_start" = "-1" ] && ep_choice_to_start="$last_ep_number"
379
+ if [ -z "$ep_choice_to_start" ]; then
380
+ # if branches, because order matters this time
381
+ while : ; do
382
+ last_ep_number=$(printf '%s' "$last_ep_number"|tr -d "[:space:]")
383
+ prompt "To specify a range, use: start_number end_number (Episodes: $first_ep_number-$last_ep_number)"
384
+ ep_choice_start="$REPLY"
385
+ ep_choice_end="$REPLY2"
386
+ [ "$REPLY" = q ] && exit 0
387
+ [ "$ep_choice_start" = "-1" ] && ep_choice_start="$last_ep_number" || [ -z "$ep_choice_start" ] && ep_choice_start="$last_ep_number"
388
+ [ "$ep_choice_end" = "-1" ] && ep_choice_end="$last_ep_number"
389
+ if ! [ "$ep_choice_start" -eq "$ep_choice_start" ] 2>/dev/null || { [ -n "$ep_choice_end" ] && ! [ "$ep_choice_end" -eq "$ep_choice_end" ] 2>/dev/null; }; then
390
+ err "Invalid number(s)"
391
+ continue
392
+ fi
393
+ if [ "$ep_choice_start" -gt "$last_ep_number" ] 2>/dev/null || [ "$ep_choice_end" -gt "$last_ep_number" ] 2>/dev/null || [ "$ep_choice_start" -lt "$first_ep_number" ] 2>/dev/null; then
394
+ err "Episode out of range"
395
+ continue
396
+ fi
397
+ if [ -n "$ep_choice_end" ] && [ "$ep_choice_end" -le "$ep_choice_start" ]; then
398
+ err "Invalid range"
399
+ continue
400
+ fi
401
+ break
402
+ done
403
+ else
404
+ ep_choice_start="$ep_choice_to_start" && unset ep_choice_to_start
405
+ fi
406
+ else
407
+ # In case the anime contains only a single episode
408
+ ep_choice_start=1
409
+ fi
410
+ [ -n "$ep_choice_end" ] && auto_play=1
411
+ }
412
+
413
+ # creates $episodes from $ep_choice_start and $ep_choice_end
414
+ generate_ep_list() {
415
+ episodes=$ep_choice_start
416
+ [ -n "$ep_choice_end" ] && episodes=$(seq "$ep_choice_start" "$ep_choice_end")
417
+ }
418
+
419
+
420
+ ##################
421
+ # VIDEO PLAYBACK #
422
+ ##################
423
+
424
+ # opens selected episodes one-by-one
425
+ open_selection() {
426
+ for ep in $episodes; do
427
+ open_episode "$selection_id" "$ep"
428
+ done
429
+ episode=${ep_choice_end:-$ep_choice_start}
430
+ }
431
+
432
+ open_episode () {
433
+ anime_id="$1"
434
+ episode="$2"
435
+ tput clear
436
+ progress "Loading episode $episode..."
437
+ # decrypting url
438
+ dpage_link=$(printf "%s" "$select_ep_result" | sed -n "${episode}p")
439
+ if [ -z "$dpage_link" ];then
440
+ die "Episode doesn't exist!!"
441
+ else
442
+ get_video_link "$dpage_link"
443
+ fi
444
+ [ "$debug" -eq 1 ] && exit 0
445
+ # write anime and episode number and save to temporary history
446
+ grep -q -- "$selection_id" "$logfile" || printf "%s\t%s\n" "$selection_id" $((episode+1)) >> "$logfile"
447
+ sed -E "s/^${selection_id}\t[0-9]*/${selection_id}\t$((episode+1))/" "$logfile" > "${logfile}.new"
448
+ [ ! "$PID" = "0" ] && kill "$PID" >/dev/null 2>&1
449
+ [ -z "$video_url" ] && die "Video URL not found"
450
+ trackma_title="$(printf '%s' "$anime_id Episode $episode" | tr '-' ' ' | awk '{for(i=1;i<=NF;i++){ $i=toupper(substr($i,1,1)) substr($i,2) }}1')"
451
+ if [ "$auto_play" -eq 0 ]; then
452
+ play_episode "$video_url" "$refr" "$trackma_title"
453
+ else
454
+ printf "\n"
455
+ play_episode "$video_url" "$refr" "$trackma_title"
456
+ wait
457
+ sleep 2
458
+ fi
459
+ PID=$!
460
+ # overwrite history with temporary history
461
+ mv "${logfile}.new" "$logfile"
462
+ }
463
+
464
+ play_episode () {
465
+ video_url="$1"; refr="$2" trackma_title="$3"
466
+ if [ "$player_fn" = "download" ];then
467
+ inf "Currently downloading $trackma_title ($provider_name)"
468
+ else
469
+ inf "Currently playing $trackma_title ($provider_name)"
470
+ fi
471
+ case "$player_fn" in
472
+ download)
473
+ if download "$refr" "$video_url" "$trackma_title"; then
474
+ inf "Downloaded episode: $trackma_title"
475
+ else
476
+ err "Download failed episode: $trackma_title , please retry or check your internet connection"
477
+ fi
478
+ ;;
479
+ iina)
480
+ nohup "$player_fn" "$video_url" --no-stdin --keep-running --mpv-referrer="$refr" --mpv-force-media-title="$trackma_title" > /dev/null 2>&1 & ;;
481
+ vlc)
482
+ if uname -a | grep -qE '[Aa]ndroid';then
483
+ am start --user 0 -a android.intent.action.VIEW -d "$video_url" -n org.videolan.vlc/org.videolan.vlc.gui.video.VideoPlayerActivity -e "title" "$trackma_title" > /dev/null 2>&1 &
484
+ else
485
+ nohup "$player_fn" "$video_url" --http-referrer="$refr" --meta-title "$trackma_title" --play-and-exit > /dev/null 2>&1 &
486
+ fi
487
+ ;;
488
+ "syncplay"|"/Applications/Syncplay.app/Contents/MacOS/syncplay"|"/c/Program Files (x86)/Syncplay/Syncplay.exe")
489
+ nohup "$player_fn" "$video_url" -- --referrer="$refr" --force-media-title="$trackma_title" > /dev/null 2>&1 & ;;
490
+ *)
491
+ if uname -a | grep -qE '[Aa]ndroid';then
492
+ am start --user 0 -a android.intent.action.VIEW -d "$video_url" -n is.xyz.mpv/.MPVActivity > /dev/null 2>&1 &
493
+ else
494
+ nohup "$player_fn" "$video_url" --referrer="$refr" --force-media-title="$trackma_title" > /dev/null 2>&1 &
495
+ fi
496
+ ;;
497
+ esac
498
+ }
499
+
500
+ ############
501
+ # START UP #
502
+ ############
503
+
504
+ # clears the colors and deletes temporary logfile when exited using SIGINT
505
+ trap 'printf "\033[0m";rm -f "$logfile".new;exit 1' INT HUP
506
+
507
+ # default options
508
+ agent="Mozilla/5.0 (X11; Linux x86_64; rv:99.0) Gecko/20100101 Firefox/100.0"
509
+ PID=0
510
+ quality=best
511
+ scrape=Query
512
+ debug=0
513
+ choice=
514
+ fzf=0
515
+ auto_play=0
516
+ download_dir="$(pwd)"
517
+ case "$(uname)" in
518
+ Darwin*) player_fn='iina';;
519
+ *) player_fn='mpv';;
520
+ esac
521
+ # history file path
522
+ logdir="${XDG_CACHE_HOME:-$HOME/.cache}"
523
+ logfile="$logdir/ani-hsts"
524
+ # create history file and history dir if none found
525
+ [ -d "$logdir" ] || mkdir "$logdir"
526
+ [ -f "$logfile" ] || : > "$logfile"
527
+
528
+ while getopts 'svq:dp:chDUVa:xr:fn' OPT; do
529
+ case $OPT in
530
+ d) player_fn='download' ;;
531
+ a) ep_choice_to_start=$OPTARG ;;
532
+ U) update_script ;;
533
+ D)
534
+ : > "$logfile"
535
+ exit 0
536
+ ;;
537
+ p)
538
+ player_fn='download'
539
+ download_dir="$OPTARG"
540
+ if [ ! -d "$download_dir" ] ; then
541
+ mkdir -p "$download_dir" || die "Couldn't create $download_dir"
542
+ fi
543
+ ;;
544
+ n) scrape=New ;;
545
+ s)
546
+ case "$(uname -s)" in
547
+ Darwin*) player_fn="/Applications/Syncplay.app/Contents/MacOS/syncplay" ;;
548
+ MINGW*|*Msys) player_fn="/c/Program Files (x86)/Syncplay/Syncplay.exe" ;;
549
+ *) player_fn="syncplay" ;;
550
+ esac
551
+ ;;
552
+ q) quality=$OPTARG ;;
553
+ x) debug=1 ;;
554
+ r) select_provider=$OPTARG ;;
555
+ f) fzf=1 ;;
556
+ c) scrape=History ;;
557
+ v) player_fn='vlc';;
558
+ V)
559
+ version_text
560
+ exit 0
561
+ ;;
562
+ h)
563
+ help_text
564
+ exit 0
565
+ ;;
566
+ *)
567
+ help_text
568
+ exit 1
569
+ ;;
570
+ esac
571
+ done
572
+ shift $((OPTIND - 1))
573
+ progress "Checking dependencies.."
574
+ # shellcheck disable=SC2046
575
+ dep_ch "curl" "sed" "grep" "openssl" || true
576
+
577
+ if [ "$player_fn" = "download" ];then
578
+ dep_ch "ffmpeg" "axel"
579
+ elif ! (uname -a | grep -qE '[Aa]ndroid');then
580
+ dep_ch "$player_fn"
581
+ fi
582
+
583
+ gogohd_url="https://gogohd.net/"
584
+ base_url="https://animixplay.to"
585
+ if [ "$scrape" = "Query" ];then
586
+ if [ -z "$*" ]; then
587
+ prompt "Search Anime"
588
+ query="$REPLY $REPLY2"
589
+ else
590
+ if [ -n "$ep_choice_to_start" ]; then
591
+ REPLY=1
592
+ select_first=1
593
+ fi
594
+ query="$*"
595
+ fi
596
+ process_search
597
+ elif [ "$scrape" = "New" ];then
598
+ progress ""
599
+ selection_id="$(curl -s "https://animixplay.to/rss.xml" | sed -nE 's_.*link.*animixplay.to/v1/([^<]*)/ep([^<]*)<.*_\1 episode \2_p' | tr '-' ' ' | fzf --height=30% --border -1 --layout=reverse --cycle)"
600
+ [ -z "$selection_id" ] && die "No anime Selected"
601
+ ep=$(printf "%s" "$selection_id" | sed 's_.*episode __')
602
+ selection_id=$(printf "%s" "$selection_id" | sed 's_ episode.*__' | tr ' ' '-')
603
+ episode_list "$selection_id"
604
+ open_episode "$selection_id" "$ep"
605
+ exit 0
606
+ else
607
+ search_history
608
+ fi
609
+
610
+ generate_ep_list
611
+ open_selection
612
+
613
+ ########
614
+ # LOOP #
615
+ ########
616
+
617
+ while : ; do
618
+ auto_play=0
619
+ unset menu
620
+ unset options
621
+ [ "$episode" -ne "$last_ep_number" ] && menu=$(append "$menu" 'next' 'n')
622
+ [ "$episode" -ne "$first_ep_number" ] && menu=$(append "$menu" 'previous' 'p')
623
+ menu=$(append "$menu" 'replay' 'r')
624
+ [ "$first_ep_number" -ne "$last_ep_number" ] && menu=$(append "$menu" 'select' 's')
625
+ menu=$(append "$menu" 'quit' 'q')
626
+ if [ "$fzf" -eq 1 ];then
627
+ progress ""
628
+ choice="$(selection_menu_fzf ". Menu>>" "$menu")"
629
+ [ -z "$choice" ] && die "No anime Selected"
630
+ else
631
+ selection_menu "$menu"
632
+ choice="$REPLY"
633
+ fi
634
+ case $choice in
635
+ n|'')
636
+ ep_choice_start=$((episode + 1))
637
+ unset ep_choice_end
638
+ ;;
639
+ p)
640
+ ep_choice_start=$((episode - 1))
641
+ unset ep_choice_end
642
+ ;;
643
+ r)
644
+ ep_choice_start="$episode"
645
+ unset ep_choice_end
646
+ ;;
647
+ s)
648
+ episode_selection ;;
649
+ q)
650
+ break ;;
651
+ *)
652
+ tput clear
653
+ err "Invalid choice"
654
+ continue
655
+ ;;
656
+ esac
657
+ generate_ep_list
658
+ open_selection
659
+ done
660
+
661
+ # ani-cli
662
+ #
663
+ # This program is free software: you can redistribute it and/or modify
664
+ # it under the terms of the GNU General Public License as published by
665
+ # the Free Software Foundation, either version 3 of the License, or
666
+ # (at your option) any later version.
667
+ #
668
+ # This program is distributed in the hope that it will be useful,
669
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
670
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
671
+ # GNU General Public License for more details.
672
+ #
673
+ # You should have received a copy of the GNU General Public License
674
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
675
+ #
676
+ # Project repository: https://github.com/pystardust/ani-cli