ani-cli-npm 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,7 +4,7 @@
4
4
  <content url="file://$MODULE_DIR$">
5
5
  <excludeFolder url="file://$MODULE_DIR$/temp" />
6
6
  <excludeFolder url="file://$MODULE_DIR$/.tmp" />
7
- <excludeFolder url="file://$MODULE_DIR$/tmp.js" />
7
+ <excludeFolder url="file://$MODULE_DIR$/tmp" />
8
8
  </content>
9
9
  <orderEntry type="inheritedJdk" />
10
10
  <orderEntry type="sourceFolder" forTests="false" />
@@ -0,0 +1,10 @@
1
+ <component name="InspectionProjectProfileManager">
2
+ <profile version="1.0">
3
+ <option name="myName" value="Project Default" />
4
+ <inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
5
+ <Languages>
6
+ <language minSize="76" name="JavaScript" />
7
+ </Languages>
8
+ </inspection_tool>
9
+ </profile>
10
+ </component>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="JavaScriptLibraryMappings">
4
+ <includedPredefinedLibrary name="Node.js Core" />
5
+ </component>
6
+ </project>
package/.idea/modules.xml CHANGED
@@ -2,7 +2,7 @@
2
2
  <project version="4">
3
3
  <component name="ProjectModuleManager">
4
4
  <modules>
5
- <module fileurl="file://$PROJECT_DIR$/.idea/ani-cli-npm-ts.iml" filepath="$PROJECT_DIR$/.idea/ani-cli-npm-ts.iml" />
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/ani-cli-npm.iml" filepath="$PROJECT_DIR$/.idea/ani-cli-npm.iml" />
6
6
  </modules>
7
7
  </component>
8
8
  </project>
package/README.MD CHANGED
@@ -1,7 +1,7 @@
1
1
  # ANI-CLI-NPM
2
2
 
3
3
  ### An Anime client, writen in nodeJS, to access any* anime without the need for ad filled websites! Just install, search for the anime of your choice, and watch in the video player of your choice.
4
- ### NodeJS rewrite of the [ani-cli](https://github.com/pystardust/ani-cli) package for linux.
4
+ ### Typescript rewrite of the [ani-cli](https://github.com/pystardust/ani-cli) package for linux.
5
5
 
6
6
 
7
7
  ## Instalation:
@@ -31,40 +31,42 @@ npx ani-cli-npm@latest
31
31
  ```
32
32
  npx ani-cli-npm@latest
33
33
  ```
34
- ##### Note: If you are using linux, I would advise just using the origonal [ani-cli](https://github.com/pystardust/ani-cli), the main perpous of this package is to allow easier use on windows and android.
34
+
35
+ ### Build from git:
36
+ ```
37
+ git clone https://github.com/Bumpkin-Pi/ani-cli-npm.git
38
+ cd ani-cli-npm
39
+ npm run build
40
+ npm run start
41
+ ```
35
42
 
36
43
 
37
44
  ## Usage:
38
- <img width="147" alt="image" src="https://user-images.githubusercontent.com/74017165/195988816-5088cbff-348e-4852-a1a0-ef343785d488.png">
45
+ ![image](https://user-images.githubusercontent.com/74017165/204142452-485e31b5-68dc-4eea-9924-bfb040429b02.png)
39
46
 
40
- #### Input the page you wish to got to then press the enter key to select
41
47
 
42
- ### Search:
43
48
 
44
- #### Input the name of the anime you want to watch, the select an anime from the search results. Then select the episode you wish to watch (If there is only one episode, said ep will be played automaticly)
49
+ #### Input the page you wish to got to then press the enter key to select
45
50
 
46
- #### Play - Plays the episode you have chosen in the player you have selected in config (VLC by default)
51
+ ### Search: Input the name of the anime you want to watch, the select an anime from the search results. Then select the episode you wish to watch (If there is only one episode, said ep will be played automaticly)
47
52
 
48
- #### Download - Will download the episode. (This requires you to have chosed a download directory in config).
53
+ ### Download - Download either a single episode, or a range of episodes from an anime of your choice. Download folder can be changed in options.
49
54
 
50
55
  ##### The download feature is not currently implemented, if you wish to download, open in browser and download there.
51
56
 
52
57
  #### Show Link - Will display the link to the video file. This can be opened in a video player or browser.
53
58
 
54
- ### Config:
59
+ ### Options:
55
60
 
56
61
  #### For configuring several of options about how the program works.
57
62
 
58
- #### Player - Change which player is used to open the anime (default mpv).
59
-
60
- #### Proxy - Proxy used for searching. This is not currently implemented and will not work.
61
-
62
- #### User agent - The user agent used to make requests to websites.
63
+ #### Player - Change which player is used to open the anime (default browser).
63
64
 
65
+ #### Proxy - Proxy used for searching. This is not currently implemented and will not work.
64
66
 
65
- ## Current limitations:
67
+ #### User agent - The user agent used to make requests to websites.
66
68
 
69
+ #### Download folder - The folder in which to download episodes.
67
70
 
68
- ### This project is still somewhat under development, as such, there are a few bugs you may run into. Feel free to open an issue on github, though there is a solid chance I am aware of it and just havn't gotten round to fixing it yet.
69
71
 
70
72
  ## Happy watching :)
package/bin/download.js CHANGED
@@ -15,10 +15,18 @@ async function download(cache_folder, config) {
15
15
  let download_id = await (0, search_anime_1.search)();
16
16
  let download = new Anime_1.Anime();
17
17
  await download.init(download_id, cache_folder);
18
- console.log(`Select start episode [1-${download.episode_list.length}]`);
19
- let start_ep_number = await (0, input_1.number_input)(download.episode_list.length);
20
- console.log(`Select end episode [${start_ep_number}-${download.episode_list.length}]`);
21
- let end_ep_number = await (0, input_1.number_input)(download.episode_list.length, start_ep_number) - 1;
18
+ let start_ep_number;
19
+ let end_ep_number;
20
+ if (download.episode_list.length <= 1) {
21
+ start_ep_number = 1;
22
+ end_ep_number = 0;
23
+ }
24
+ else {
25
+ console.log(`Select start episode [1-${download.episode_list.length}]`);
26
+ start_ep_number = await (0, input_1.number_input)(download.episode_list.length);
27
+ console.log(`Select end episode [${start_ep_number}-${download.episode_list.length}]`);
28
+ end_ep_number = await (0, input_1.number_input)(download.episode_list.length, start_ep_number) - 1;
29
+ }
22
30
  let to_do = (0, libs_1.range)(start_ep_number, end_ep_number + 1);
23
31
  do {
24
32
  for (let x in to_do) {
package/bin/index.js CHANGED
@@ -36,8 +36,14 @@ async function main() {
36
36
  let anime_id = await (0, search_anime_1.search)();
37
37
  let anime = new Anime_1.Anime();
38
38
  await anime.init(anime_id, cache_folder);
39
- console.log(`Select episode [1-${anime.episode_list.length}]`);
40
- let episode_number = await (0, input_1.number_input)(anime.episode_list.length) - 1;
39
+ let episode_number;
40
+ if (anime.episode_list.length == 1) {
41
+ episode_number = 0;
42
+ }
43
+ else {
44
+ console.log(`Select episode [1-${anime.episode_list.length}]`);
45
+ episode_number = await (0, input_1.number_input)(anime.episode_list.length) - 1;
46
+ }
41
47
  await anime.play_head(episode_number, config, cache_folder);
42
48
  await anime.player.quit();
43
49
  await main();
package/bin/input.js CHANGED
@@ -42,9 +42,14 @@ async function input() {
42
42
  }
43
43
  exports.input = input;
44
44
  async function number_input(max, min = 1) {
45
+ let selector;
45
46
  let selection;
46
47
  do {
47
- selection = parseInt(await _prompt(">"));
48
+ selector = await _prompt(">");
49
+ selection = parseInt(selector);
50
+ if (selector == "") {
51
+ selection = min;
52
+ }
48
53
  if (!(min <= selection && selection <= max)) {
49
54
  console.log(chalk_1.default.red("Invalid choice."));
50
55
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ani-cli-npm",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "ani-cli tool rewritten as npm package",
5
5
  "main": "bin/index.js",
6
6
  "scripts": {
package/bin/index.js.old DELETED
@@ -1,586 +0,0 @@
1
- #! /usr/bin/env node
2
-
3
- const {emitWarning} = process;
4
-
5
- process.emitWarning = (warning, ...args) => {
6
- if (args[0] === 'ExperimentalWarning') {
7
- return;
8
- }
9
-
10
- if (args[0] && typeof args[0] === 'object' && args[0].type === 'ExperimentalWarning') {
11
- return;
12
- }
13
-
14
- return emitWarning(warning, ...args);
15
- };
16
- const fetch = require('node-fetch');
17
- const PlayerController = require("media-player-controller")
18
- const open = require("open")
19
- const prompt = require("simple-input");
20
- const getAppDataPath = require("appdata-path")
21
- const fs = require("fs")
22
- const dl = require("download-file-with-progressbar");
23
-
24
-
25
-
26
- let config = {
27
- player: "BROWSER",
28
- proxy: "",
29
- user_agent: "Mozilla/5.0 (X11; Linux x86_64; rv:99.0) Gecko/20100101 Firefox/100.0",
30
- most_recent: {
31
- episode_number: 0,
32
- anime_id: "",
33
- episodes: []
34
- },
35
- download_folder: "./",
36
- download_progress_bar: true
37
- }
38
-
39
-
40
- function read_config(){
41
- try{
42
- try {
43
- config = JSON.parse(fs.readFileSync(getAppDataPath() + "/ani-cli-npm.conf")) //getAppDataPath()
44
- if (!config.hasOwnProperty("player")) config.player = "BROWSER";
45
- if (!config.hasOwnProperty("user_agent")) config.user_agent = "Mozilla/5.0 (X11; Linux x86_64; rv:99.0) Gecko/20100101 Firefox/100.0";
46
- if (!config.hasOwnProperty("proxy")) config.user_agent = "";
47
- if (!config.hasOwnProperty("most_recent")) config.most_recent = null;
48
- if (!config.hasOwnProperty("download_folder")) config.download_folder = "./";
49
- if (!config.hasOwnProperty("download_progress_bar")) config.download_progress_bar = true;
50
- fs.writeFileSync(getAppDataPath() + "/ani-cli-npm.conf", JSON.stringify(config))
51
- } catch {
52
- fs.writeFileSync(getAppDataPath() + "/ani-cli-npm.conf", JSON.stringify(config))
53
- }
54
- }catch{
55
- console.log(colors.Red, "Failed to read config file")
56
- }
57
- }
58
-
59
- function write_config(){
60
- try{
61
- fs.writeFileSync(getAppDataPath() + "/ani-cli-npm.conf", JSON.stringify(config))
62
- }catch{
63
- console.log(colors.Red, "Failed to write to config file")
64
- }
65
- }
66
-
67
-
68
-
69
- const gogohd_url="https://gogohd.net/"
70
- const base_url="https://animixplay.to"
71
- const colors = {
72
- Black: "\x1b[30m%s\x1b[0m",
73
- Red: "\x1b[31m%s\x1b[0m",
74
- Green: "\x1b[32m%s\x1b[0m",
75
- Yellow: "\x1b[33m%s\x1b[0m",
76
- Blue: "\x1b[34m%s\x1b[0m",
77
- Magenta: "\x1b[35m%s\x1b[0m",
78
- Cyan: "\x1b[36m%s\x1b[0m",
79
- White: "\x1b[37m%s\x1b[0m"
80
- }
81
-
82
-
83
- //const HttpsProxyAgent = require('https-proxy-agent');
84
- //let proxyAgent = new HttpsProxyAgent(config.proxy);
85
-
86
-
87
- async function config_(temp){
88
- console.clear()
89
- console.log(colors.Blue, "ANI-CLI-NPM \n")
90
- console.log(colors.Yellow, "Config:\n")
91
- console.log(colors.Cyan, `1) Player; ${temp.player}`)
92
- console.log(colors.Cyan, `2) Proxy; ${temp.proxy}`)
93
- console.log(colors.Cyan, `3) User agent; ${temp.user_agent}`)
94
- console.log(colors.Cyan, `4) Download folder; ${config.download_folder}`)
95
- console.log(colors.Cyan, "5) Save and exit")
96
- console.log(colors.Cyan, "6) Exit without saving changes")
97
- let choice = parseInt(await input(""));
98
- switch (choice){
99
- case 1:
100
- console.log(colors.Cyan, `1) VLC (default)`)
101
- console.log(colors.Cyan, `2) Browser`)
102
- console.log(colors.Cyan, `3) MPV`)
103
- let player = parseInt(await input("New Player;"))
104
- switch (player){
105
- case 1:
106
- temp.player = "VLC"
107
- break
108
- case 2:
109
- temp.player = "BROWSER"
110
- break
111
- case 3:
112
- temp.player = "MPV"
113
- break
114
- }
115
- return temp,0
116
- case 2:
117
- temp.proxy = (await(input("New Proxy;"))).replaceAll(" ", "")
118
- return temp, 0
119
- case 3:
120
- temp.user_agent = await(input("New User agent;"))
121
- return temp, 0
122
- case 4:
123
- temp.download_folder = await(input("New download folder: "))
124
- return temp, 0
125
- case 5:
126
- return temp, 1
127
- case 6:
128
- return temp, 2
129
- }
130
- }
131
-
132
- async function input(message){
133
- if (message){
134
- console.log(colors.Magenta,message)
135
- }
136
- return await prompt(">")
137
- }
138
-
139
- async function curl(url, method="GET", redirect = false){
140
- //try{
141
- let response = await fetch(url, {
142
- //"agent": proxyAgent,
143
- "headers": {
144
- 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:99.0) Gecko/20100101 Firefox/100.0',
145
- "X-Requested-With": "XMLHttpRequest"
146
- },
147
- "referrerPolicy": "origin",
148
- "body": null,
149
- "method": method,
150
- "redirect": 'follow',
151
- "follow": 10,
152
- }).catch(async function(err) {
153
- console.warn(colors.Red, `Something went wrong connecting to ${url}.`);
154
- await search();
155
- process.exit()
156
- })
157
- if (redirect){
158
- return response.url
159
- }else{
160
- return await response.text()
161
- }
162
- /*}catch{
163
- console.log(colors.Red, "Something went wrong in curl()")
164
- await main()
165
- }*/
166
-
167
- }
168
-
169
- async function _continue(){
170
- let link = await get_video_link(config.most_recent.episodes[config.most_recent.episode_number])
171
- await play(link, config.most_recent)
172
- process.exit()
173
- }
174
-
175
-
176
- function RegexParse(str, rule) {
177
- let escapeRegex = (str) => str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
178
- return new RegExp("^" + rule.split("*").map(escapeRegex).join(".*") + "$").test(str);
179
- }
180
-
181
- async function search_anime(search){
182
- let filter = "*<ahref=\"/category/*\"title=\"*\">"
183
- let html = (await curl("https://gogoanime.dk//search.html?keyword="+search)).split("\n")
184
- let lines = []
185
- for (x in html){
186
- html[x] = html[x].replaceAll(/ /g,'').replaceAll(/\t/g,'')
187
- if (RegexParse(html[x], filter)){
188
- html[x] = html[x].slice(html[x].indexOf("/category/")+10);
189
- html[x] = html[x].slice(0, html[x].indexOf("\"title="));
190
- lines.push(html[x])
191
- }
192
- }
193
- if (!lines[0]){
194
- lines.pop()
195
- }
196
-
197
-
198
- return lines
199
- }
200
-
201
- async function episode_list(anime_id){
202
- let html = (await curl(base_url+"/v1/"+anime_id)).split("\n")
203
- let lines = ""
204
-
205
- for (let x in html){
206
- if(RegexParse(html[x], "*<div id=\"epslistplace\"*")){
207
- lines = (html[x])
208
- }
209
- }
210
-
211
- lines = lines.slice(55, lines.length).replace("}</div>", "")
212
- lines = "{" + lines.slice(lines.indexOf(",")+1, lines.length) + "}"
213
- lines = JSON.parse(lines)
214
-
215
- let json = []
216
- for (x in lines){
217
- json.push(lines[x])
218
- }
219
- return json
220
- }
221
-
222
- function download(link, file_name){
223
- if (link.includes("m3u8")) console.log(colors.Red, "Warning: Animixplay will download an m3u8 file. This will require some extra steps to play. It is advised to use a 3rd party website or tool to download these from the link.");
224
- let option = {
225
- filename: link.includes("m3u8") ? file_name.replace("mp4", "m3u8") : file_name,
226
- dir: config.download_folder,
227
- onDone: (info)=>{
228
- console.log(colors.Green, `\n -- Download finished -- \nLocation: ${info.path}\nSize: ${Math.round(info.size/100000)*10} Bytes`);
229
- return 0;
230
- },
231
- onError: (err) => {
232
- console.log(colors.Red, 'error', err);
233
- },
234
- onProgress: (curr, total) => {
235
- process.stdout.clearLine(0);
236
- process.stdout.cursorTo(0);
237
- if (config.download_progress_bar){
238
- process.stdout.write("\x1b[32m -- "+(curr / total * 100).toFixed(2)+"% "+"#". repeat(Math.ceil((curr / total)*(process.stdout.columns-20)))+"~".repeat(Math.ceil((process.stdout.columns-20) - (curr / total)*(process.stdout.columns-20)))+" -- \x1b[0m")
239
-
240
- }else{
241
- process.stdout.write(('\x1b[32m -- progress '+ (curr / total * 100).toFixed(2) + '% -- \x1b[0m'));
242
- }
243
- },
244
- }
245
- console.log(colors.White, `${option.dir}/${option.filename}`)
246
-
247
- return dl(link, option);
248
-
249
- }
250
-
251
- async function selection(options, prompt, extra_options = []){
252
- let selection = 0
253
- while (true){
254
- selection = (await input(prompt))
255
- if ((selection <= options && selection >= 1) || extra_options.includes(selection)){
256
- break
257
- }
258
- console.log(colors.Red,`Please input a valid option.`)
259
- }
260
- return selection
261
- }
262
-
263
- async function process_search(query) {
264
- console.log(colors.Yellow, "Searching: "+query)
265
-
266
- let search_results = await search_anime(query)
267
- if (!search_results[0]) {
268
- console.log(colors.Red, "No results.")
269
- await main()
270
- process.exit()
271
- } else {
272
- for (x in search_results) {
273
- console.log(colors.Cyan,`${parseInt(x)+1})${" ".repeat(((search_results.length).toString().length+1)-((parseInt(x)+1).toString().length))}${search_results[x].replaceAll("-", " ")}`)
274
- }
275
- }
276
-
277
- let anime_id = search_results[await selection(search_results.length, "Please select an anime.")-1]
278
- let episodes = await episode_list(anime_id)
279
- let episode_number = 0;
280
- if (episodes.length > 1){
281
- episode_number = (await selection(episodes.length, `Please select an episode (1-${episodes.length}).`))-1
282
- }
283
- return {
284
- anime_id: anime_id,
285
- episodes: episodes,
286
- episode_number: episode_number
287
- }
288
- }
289
-
290
- async function get_video_link(episode_dpage){
291
- let id = episode_dpage.replace("//gogohd.net/streaming.php?id=","")
292
- id = id.slice(0, id.indexOf("="))
293
- let link = await generate_link(1,id)
294
- if (!link){
295
- link = await generate_link(2,id)
296
- }
297
- return link
298
- }
299
-
300
- async function generate_link(provider, id){
301
- let html = ""
302
- let provider_name = ""
303
- switch (provider) {
304
- case 1:
305
- html = await curl(`${gogohd_url}streaming.php?id=${id}`)
306
- provider_name = 'Xstreamcdn'
307
- console.log(colors.Yellow, `Fetching ${provider_name} links...`)
308
- html = html.split("\n")
309
- let fb_id = ""
310
- for (x in html){
311
- if (RegexParse(html[x], "*<li class=\"linkserver\" data-status=\"1\" data-video=\"https://fembed9hd.com/v/*")){
312
- fb_id = html[x].slice(html[x].indexOf("/v/")+3, html[x].indexOf("\">X"))
313
- break
314
- }
315
- }
316
- if (!fb_id){
317
- console.log("Error, no fb_id found.")
318
- return 0
319
- }
320
-
321
- //let refr = "https://fembed-hd.com/v/"+fb_id
322
- let post = await curl("https://fembed-hd.com/api/source/"+fb_id, "POST")
323
- post = post.slice(post.indexOf(",\"data\":[{\"file\":\"")+18, post.length)
324
- post = post.slice(0, post.indexOf("\"")).replaceAll("\\/","/")
325
- return post
326
- case 2:
327
- provider_name = 'Animixplay'
328
- let buffer = new Buffer(id)
329
- let enc_id = buffer.toString("base64")
330
- buffer = new Buffer(id+"LTXs3GrU8we9O"+enc_id)
331
- let ani_id = buffer.toString("base64")
332
- buffer = Buffer.from((await curl(`${base_url}/api/live${ani_id}`, "GET", true)).split("#")[1], "base64")
333
- if (config.player === "BROWSER"){
334
- return `${base_url}/api/live${ani_id}`
335
- }
336
- return buffer.toString("utf-8") //TODO m3u8 player
337
-
338
-
339
- }
340
- }
341
-
342
- async function post_play(link, anime, player = null){
343
- while (true){
344
- config.most_recent = anime
345
- write_config()
346
-
347
- console.log(colors.Yellow, `Playing episode ${anime.episode_number+1} of ${anime.anime_id.replaceAll("-", " ")}\n`)
348
- console.log(colors.Cyan, "1/l) Show Link")
349
- console.log(colors.Cyan, "2/n) Next Episode")
350
- console.log(colors.Cyan, "3/p) Prev Episode")
351
- console.log(colors.Cyan, "4/d) Download")
352
- console.log(colors.Cyan, "5/q) Quit")
353
- switch (await selection(5, "select;", ["l", "n", "p", "d", "q"])){
354
- case "l":
355
- case "1":
356
- console.log(colors.Yellow, "Link: "+link)
357
- break
358
- case "n":
359
- case "2":
360
- if (anime.episode_number > anime.episodes.length-2){
361
- console.log(colors.Red, "Damn, all out of episodes?")
362
- break
363
- }
364
- anime.episode_number += 1
365
- link = await get_video_link(anime.episodes[anime.episode_number])
366
- await play(link, anime, player)
367
- process.exit()
368
- break
369
- //EVEN MORE NEEDLESS QUIT STATEMENTS!!!!!!
370
- case "p":
371
- case "3":
372
- if (anime.episode_number < 2){
373
- console.log(colors.Red, "Error; Episode 0 is only available for premium members")
374
- break
375
- }
376
- anime.episode_number -= 1
377
- link = await get_video_link(anime.episodes[anime.episode_number])
378
- await play(link, anime, player)
379
- process.exit()
380
- break
381
- case "d":
382
- case "4":
383
- console.log(colors.Yellow, "Beware of the dysfunctional await clause.")
384
- await download(link, anime.anime_id+(anime.episode_number+1)+".mp4")
385
- post_play(link, anime, player)
386
- break
387
- case "q":
388
- case "5":
389
- console.clear()
390
- await main()
391
- process.exit()
392
- break
393
- }
394
- }
395
- }
396
-
397
- async function play(link, anime, player){
398
- console.clear()
399
- console.log(colors.Blue, "ANI-CLI-NPM \n")
400
- if (config.player === "VLC"){
401
- if (!player){
402
- console.log(colors.Yellow, "Loading VLC... ")
403
- player = new PlayerController({
404
- app: 'vlc',
405
- args: ['--fullscreen'],
406
- media: link
407
- });
408
- await player.launch(err => {
409
- if (err) return console.error(err.message);
410
- });
411
- }else{
412
- player.quit()
413
- console.log(colors.Yellow, "Loading VLC... ")
414
- player = new PlayerController({
415
- app: 'vlc',
416
- args: ['--fullscreen'],
417
- media: link
418
- });
419
- await player.launch(err => {
420
- if (err) return console.error(err.message);
421
- });
422
- }
423
-
424
- await post_play(link, anime, player)
425
- process.exit()
426
-
427
-
428
- }else if (config.player === "BROWSER"){
429
- console.log(colors.Yellow, "Opening video in browser... ")
430
- open(link)
431
- await post_play(link, anime)
432
- process.exit()
433
- }else if (config.player === "MPV"){
434
- if (!player){
435
- console.log(colors.Yellow, "Loading MPV... ")
436
- player = new PlayerController({
437
- app: 'mpv',
438
- args: ['--fullscreen'],
439
- media: link
440
- });
441
- await player.launch(err => {
442
- if (err) return console.error(err.message);
443
- });
444
- }else{
445
- player.load(link)
446
- }
447
-
448
- await post_play(link, anime, player)
449
- process.exit()
450
- }
451
- }
452
-
453
- async function search(){
454
- console.log(colors.Magenta, "Search...")
455
- let choice = await input("")
456
- let anime = await process_search(choice)
457
-
458
- console.log("\n")
459
-
460
- console.log(colors.Blue, "Indexing video...")
461
- let link = await get_video_link(anime.episodes[anime.episode_number])
462
- if (!link){
463
- console.log(colors.Red, "Np link for this episode found?")
464
- console.log(colors.Yellow, "^ at current this is due to not all of the required video repos being implemented.")
465
- console.log(colors.Yellow, "Sorry for any inconvenience, this should soon by implemented. We appreciate your patience.")
466
- process.exit()
467
- }
468
- console.log(colors.Blue, `Episode ${anime.episode_number+1} of ${anime.anime_id.replaceAll("-", " ")} found.\n`)
469
- if (link.includes("animixplay.to") && config.player === "VLC"){
470
- console.log(colors.Red, "Warning; animix.to uses m3u8 playlists. Without custom plugins, VLC will not be able to play this file format. It is recomended to use another player for this show/film.")
471
- }
472
- console.log(colors.Cyan, "1/p) Play")
473
- console.log(colors.Cyan, "2/d) Download")
474
- console.log(colors.Cyan, "3/l) Show Link")
475
- console.log(colors.Cyan, "4/q) quit")
476
- choice = (await selection(4, "select;", ["p", "d", "l", "q"]))
477
- switch (choice){
478
- case "p":
479
- case "1":
480
- await play(link, anime, null)
481
- break
482
- case "d":
483
- case "2":
484
- await download(link, anime.anime_id+(anime.episode_number+1)+".mp4")
485
- break
486
- case "l":
487
- case "3":
488
- console.log(colors.Yellow, "Link: "+link)
489
- console.log(colors.Cyan, "\n1/p) Play")
490
- console.log(colors.Cyan, "2/d) Download")
491
- console.log(colors.Cyan, "3/q) quit")
492
- choice = (await selection(3, "select;", ["p", "d", "q"]))
493
- switch (choice){
494
- case "p":
495
- case "1":
496
- await play(link, anime, null)
497
- break
498
- case "d":
499
- case "2":
500
- await download(link, anime.anime_id+anime.episode_number+".mp4")
501
- break
502
- case "q":
503
- case "3":
504
- await main()
505
- process.exit()
506
- }
507
- break
508
- case "q":
509
- case "4":
510
- await main()
511
- process.exit()
512
- }
513
- }
514
-
515
-
516
- console.clear()
517
- read_config()
518
- console.log(colors.Blue, "Welcome to Ani-Cli-npm\n")
519
- if (config.most_recent.episode_number !== 0){
520
- console.log(colors.White, `Most recently played: ${config.most_recent.anime_id}, ep${config.most_recent.episode_number+1}`)
521
- }
522
- async function main(){
523
- if (config.player === "VLC"){
524
- console.log(colors.Red, "Warning; if you do not have mpv video player installed, you will have to change your video player to either vlc or browser in config.\n")
525
- }
526
- console.log(colors.Cyan, "\n1/s) Search")
527
- if (config.most_recent.episode_number !== 0){
528
- console.log(colors.Cyan, "2/c) Continue")
529
- }else{
530
- console.log(colors.White, "2/c) Continue")
531
- }
532
- console.log(colors.Cyan, "3/C) Config")
533
- console.log(colors.Cyan, "4/q) Quit")
534
- let choice = await selection(4, "select;", ["s", "c", "C", "q"])
535
- switch (choice){
536
- case "s":
537
- case "1":
538
- await search()
539
- break
540
- case "c":
541
- case "2":
542
- if (config.most_recent.episode_number !== 0){
543
- await _continue()
544
- }else{
545
- console.log(colors.White, "No episodes watched recently")
546
- await main()
547
- }
548
-
549
- break
550
- case "C":
551
- case "3":
552
- let temp = structuredClone(config);
553
- let exit_code;
554
- while (true) {
555
- temp, exit_code = await config_(temp)
556
- if (exit_code === 1) {
557
- config = temp
558
- //proxyAgent = new HttpsProxyAgent(config.proxy);
559
- console.clear()
560
- console.log(colors.Blue, "ANI-CLI-NPM \n")
561
- console.log(colors.Yellow, "Config changed.")
562
- break
563
- } else if (exit_code === 2) {
564
- temp = config
565
- console.clear()
566
- console.log(colors.Blue, "ANI-CLI-NPM \n")
567
- console.log(colors.Yellow, "Config changes disregarded.")
568
- break
569
- }
570
- }
571
- try{
572
- fs.writeFileSync(getAppDataPath()+"/ani-cli-npm.conf", JSON.stringify(config))
573
- }catch{
574
- console.log(colors.Red, "Error writing to .conf file.")
575
- }
576
- await main()
577
- break
578
- case "q":
579
- case "4":
580
- console.log(colors.Black, "Exiting...")
581
- process.exit()
582
- }
583
- }
584
-
585
-
586
- main()