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/README.MD CHANGED
@@ -3,6 +3,8 @@
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
4
  ### Typescript rewrite of the [ani-cli](https://github.com/pystardust/ani-cli) package for linux.
5
5
 
6
+ # Warning: due to shutdowns of Animixplay, this tool, along with ani-cli, is broken at present. I am currently working on a fix, but for now this will not work.
7
+
6
8
  ![image](https://user-images.githubusercontent.com/74017165/205444723-20520eb1-55dd-4103-811b-07e2cf6c466d.png)
7
9
 
8
10
 
package/bin/Anime.js CHANGED
@@ -3,15 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Anime = void 0;
4
4
  const curl_1 = require("./core_utils/curl");
5
5
  const regex_1 = require("./core_utils/regex");
6
- const generate_link_1 = require("./generate_link");
6
+ const generate_link_1 = require("./url_genoration/generate_link");
7
7
  const cache_1 = require("./file_managment/cache");
8
- const input_1 = require("./input");
8
+ const input_1 = require("./IO/input");
9
9
  const load_config_1 = require("./file_managment/load_config");
10
10
  const W2GClient = require("w2g-client");
11
11
  const open = require("open");
12
12
  const PlayerController = require("media-player-controller");
13
13
  const dl = require("download-file-with-progressbar");
14
14
  const chalk = require("chalk");
15
+ const m3u8ToMp4 = require("m3u8-to-mp4");
16
+ const converter = new m3u8ToMp4();
15
17
  class Anime {
16
18
  /*
17
19
  Class for handling a show/film
@@ -267,6 +269,9 @@ class Anime {
267
269
  this.player.play(await this.get_episode_link(this.current_episode, player));
268
270
  }
269
271
  async play_controller(episode, config, config_dir, first = false) {
272
+ if (config.show_cover) {
273
+ }
274
+ console.clear();
270
275
  console.log(`Playing ${this.id} episode ${episode + 1}`); // from ${new Date(this.current_pos * 1000).toISOString().slice(11, 19)}`)
271
276
  // if (!first){
272
277
  // console.clear()
@@ -307,6 +312,7 @@ class Anime {
307
312
  });
308
313
  let selected; // Look, I'm sorry, but there is no way I can possibly document this in a sane way. It's a dumb patch.
309
314
  do {
315
+ console.clear();
310
316
  selected = await (0, input_1.selection)((episode <= 0) ? [chalk.yellow("1/n) Next"), chalk.grey("2/p) Previous"), chalk.yellow("3/s) Select"), chalk.green("4/q) Quit")] :
311
317
  (episode >= this.episode_list.length - 1) ? [chalk.grey("1/n) Next"), chalk.green("2/p) Previous"), chalk.yellow("3/s) Select"), chalk.green("4/q) Quit")] :
312
318
  [chalk.yellow("1/n) Next"), chalk.green("2/p) Previous"), chalk.yellow("3/s) Select"), chalk.green("4/q) Quit")], ["n", "p", "s", "q"], ((thing) => { return (thing); }), ((thing) => { return (thing); }), true);
@@ -352,41 +358,51 @@ class Anime {
352
358
  /*
353
359
  ## Downloads an episode (counting from 0) to download_folder, with progress bar.
354
360
  */
361
+ while (episode <= final_ep) {
362
+ }
355
363
  try {
356
- // @ts-ignore
357
364
  let ep_link = await this.get_episode_link(episode);
358
365
  let file_name = `${this.id}-${episode + 1}.mp4`;
359
- if (ep_link.includes(".m3u8"))
360
- console.log(chalk.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."));
361
- // @ts-ignore
362
- let option = {
363
- filename: (ep_link.includes("m3u8") ? file_name.replace("mp4", "m3u8") : file_name),
364
- dir: download_folder,
365
- onDone: (final_ep > episode) ? ((info) => {
366
+ if (ep_link.includes(".m3u8")) {
367
+ console.log(chalk.green(`Downloading episode ${episode + 1} of ${this.id.replace("-", "")} to ${download_folder + "/" + file_name}...`));
368
+ console.log("Progress bar unavailable for m3u8 files.");
369
+ await converter
370
+ .setInputFile(ep_link)
371
+ .setOutputFile((download_folder + "/" + file_name))
372
+ .start();
373
+ console.log(chalk.green("Download finished."));
374
+ }
375
+ else {
376
+ // @ts-ignore
377
+ let option = {
378
+ filename: (ep_link.includes("m3u8") ? file_name.replace("mp4", "m3u8") : file_name),
379
+ dir: download_folder,
380
+ onDone: (final_ep > episode) ? ((info) => {
381
+ // @ts-ignore
382
+ console.log(chalk.green(`\n -- 1Download finished -- \nLocation: ${info.path}. Size: ${Math.round(info.size / 100000) * 10} Bytes\n`));
383
+ this.download(episode + 1, download_folder, final_ep);
384
+ }) : ((info) => {
385
+ // @ts-ignore
386
+ console.log(chalk.green(`\n -- 2Download finished -- \n${info.path}. Size: ${Math.round(info.size / 100000) * 10} Bytes\n`));
387
+ }),
366
388
  // @ts-ignore
367
- console.log(chalk.green(`\n -- 1Download finished -- \nLocation: ${info.path}. Size: ${Math.round(info.size / 100000) * 10} Bytes\n`));
368
- this.download(episode + 1, download_folder, final_ep);
369
- }) : ((info) => {
389
+ onError: (err) => {
390
+ console.log(chalk.red('error', err));
391
+ this.download(episode, download_folder, final_ep);
392
+ },
370
393
  // @ts-ignore
371
- console.log(chalk.green(`\n -- 2Download finished -- \n${info.path}. Size: ${Math.round(info.size / 100000) * 10} Bytes\n`));
372
- }),
373
- // @ts-ignore
374
- onError: (err) => {
375
- console.log(chalk.red('error', err));
376
- this.download(episode, download_folder, final_ep);
377
- },
378
- // @ts-ignore
379
- onProgress: (curr, total) => {
380
- process.stdout.clearLine(0);
381
- process.stdout.cursorTo(0);
382
- process.stdout.write("\x1b[32m -- " + (curr / total * 100).toFixed(2) + "% " + "#".repeat(Math.ceil((curr / total) * ((process.stdout.columns - 20) / 1.5))) + "~".repeat(Math.ceil(((process.stdout.columns - 20) / 1.5) - (curr / total) * ((process.stdout.columns - 20) / 1.5))) + " -- \x1b[0m");
383
- }
384
- };
385
- //console.log((`${option.dir}/${option.filename}`))
386
- return await dl(ep_link, option);
394
+ onProgress: (curr, total) => {
395
+ process.stdout.clearLine(0);
396
+ process.stdout.cursorTo(0);
397
+ process.stdout.write("\x1b[32m -- " + (curr / total * 100).toFixed(2) + "% " + "#".repeat(Math.ceil((curr / total) * ((process.stdout.columns - 20) / 1.5))) + "~".repeat(Math.ceil(((process.stdout.columns - 20) / 1.5) - (curr / total) * ((process.stdout.columns - 20) / 1.5))) + " -- \x1b[0m");
398
+ }
399
+ };
400
+ //console.log((`${option.dir}/${option.filename}`))
401
+ return await dl(ep_link, option);
402
+ }
387
403
  }
388
404
  catch {
389
- this.download(episode, download_folder, final_ep);
405
+ await this.download(episode, download_folder, final_ep);
390
406
  }
391
407
  }
392
408
  }
package/bin/IO/help.js ADDED
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.help = void 0;
4
+ const input_1 = require("./input");
5
+ const chalk = require("chalk");
6
+ const helps = [
7
+ (async () => {
8
+ console.log(chalk.cyan("Playing anime: \n" +
9
+ " Search: \n" +
10
+ " Search for a show/movie. This will search on gogoanime.dk.\n" +
11
+ " Episode selection: \n" +
12
+ " Once an anime is selected, select an episode. If there is only 1 episode " +
13
+ "(in the case of a movie), the episode will be played automatically.\n" +
14
+ " The episode selected will be played in the video player selected in options. Info on video players can be found in options help."));
15
+ await help();
16
+ return;
17
+ }),
18
+ (async () => {
19
+ console.log(chalk.cyan("Downloading anime: \n" +
20
+ " Search: \n" +
21
+ " Search for a show/movie. This will search on gogoanime.dk.\n" +
22
+ " Episode selection: \n" +
23
+ " Once an anime is selected, select a start episode and an end episode. If there is only 1 episode " +
24
+ "(in the case of a movie), the episode will be downloaded automatically. Download folder can be changed in options. Default to run location.\n" +
25
+ " The selected episodes will be downloaded. It is common for episode links to fail to be fetched, when this happens the episode will be passed, then reattempted in another pass.\n" +
26
+ " Episodes sourced from Animixplay links will download m3u8 file, which you will have difficulty playing, if you are able to at all."));
27
+ await help();
28
+ return;
29
+ }),
30
+ (async () => {
31
+ console.log(chalk.cyan("Options: \n" +
32
+ " Player: \n" +
33
+ " Player used to play anime.\n" +
34
+ " Proxy: \n" +
35
+ " https proxy address and port in form ip:port. This is not currently implemented.\n" +
36
+ " User agent:\n" +
37
+ " node-fetch user agent.\n" +
38
+ " Downloads folder:\n" +
39
+ " Folder to place downloaded episodes.\n" +
40
+ " MPV socket connection file:\n" +
41
+ " File for mpv socket, used to control mpv instance with outside tools.\n" +
42
+ " VLC socket:\n" +
43
+ " VLC http control socket\n" +
44
+ " VLC pass:\n" +
45
+ " VLC http control password\n" +
46
+ " W2G api token:\n" +
47
+ " Your user access token for w2g.tv. Can be found at https://w2g.tv/en/account/edit_user under Tools/API\n"));
48
+ await help();
49
+ return;
50
+ }),
51
+ (async () => {
52
+ return;
53
+ })
54
+ ];
55
+ async function help() {
56
+ console.log(chalk.cyan("Help page select: \n"));
57
+ return helps[await (0, input_1.selection)(["Playing", "Downloading", "Options", "Quit"], ["p", "d", "o", "q"])]();
58
+ }
59
+ exports.help = help;
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.number_input = exports.input = exports.selection = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const _prompt = require("simple-input");
9
+ async function selection(options, extra_options = [], color1 = ((thing) => { return chalk_1.default.yellow(thing); }), color2 = ((thing) => { return chalk_1.default.green(thing); }), overwrite = false) {
10
+ /*
11
+ selection(options, extra_options, color1, color2)
12
+
13
+ Gives use prompt to choose from a list of options. Either by inputting a number ranging from 1, to the length of the list. Or by inputting a letter (non-caps-sensitive) relating to the option.
14
+
15
+
16
+ - options: array of options; e.g. ["play", "download", "continue", "quit"] REQUIRED
17
+
18
+
19
+ - extra_options: array of characters as alternatives to numbers (both will be displayed). e.g. ["p", "d", "c", "q"].
20
+
21
+ default: []
22
+
23
+ - color1 and color2: functions that will dictate what 2 colors the options with alternate between (option1 will be color1, option2;color2, option3;color1, etc).
24
+ recommended for this function to return a chalk.____() parsed string.
25
+
26
+ default: ((thing:string) => {return chalk.yellow(thing)}) and ((thing:string) => {return chalk.green(thing)})
27
+
28
+ - Overwrite: boolean. Please dont use this. I should not be using it. It prints out the raw string instead of adding numbers to them to allow for bogus.
29
+ */
30
+ let color = true;
31
+ for (let x in options) {
32
+ if (!overwrite) {
33
+ if (color) {
34
+ console.log(color1((parseInt(x) + 1).toString() +
35
+ ((extra_options[x] == undefined) ? "" : "/" + extra_options[x]) +
36
+ ") " + options[x].replaceAll("-", " ")));
37
+ }
38
+ else {
39
+ console.log(color2((parseInt(x) + 1).toString() +
40
+ ((extra_options[x] == undefined) ? "" : "/" + extra_options[x]) +
41
+ ") " + options[x].replaceAll("-", " ")));
42
+ }
43
+ }
44
+ else {
45
+ console.log(options[x]);
46
+ }
47
+ color = !color;
48
+ }
49
+ let input = "";
50
+ do {
51
+ // @ts-ignore
52
+ input = (await _prompt(">")).toLowerCase();
53
+ for (let x in extra_options) {
54
+ if (extra_options[x].toLowerCase() == input) {
55
+ input = (parseInt(x) + 1).toString();
56
+ }
57
+ }
58
+ if (!(1 <= parseInt(input) && parseInt(input) <= options.length)) {
59
+ console.log(chalk_1.default.red("Invalid choice."));
60
+ }
61
+ } while (!(1 <= parseInt(input) && parseInt(input) <= options.length));
62
+ return parseInt(input) - 1;
63
+ }
64
+ exports.selection = selection;
65
+ async function input() {
66
+ return await _prompt(">");
67
+ }
68
+ exports.input = input;
69
+ async function number_input(max, min = 1, extra_options = [], extra_option_values = []) {
70
+ let selector;
71
+ let selection;
72
+ do {
73
+ selector = await _prompt(">");
74
+ if (extra_options.includes(selector.toLowerCase())) {
75
+ selection = extra_option_values[extra_options.indexOf(selector)];
76
+ }
77
+ else {
78
+ selection = parseInt(selector);
79
+ }
80
+ if (selector == "") {
81
+ selection = min;
82
+ }
83
+ if (!(min <= selection && selection <= max)) {
84
+ console.log(chalk_1.default.red("Invalid choice."));
85
+ }
86
+ } while (!(min <= selection && selection <= max));
87
+ return selection;
88
+ }
89
+ exports.number_input = number_input;
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ // let base:string = "https://gogocdn.net/cover/yuri-on-ice-dub.png"
3
+ // export {display_cover}
package/bin/download.js CHANGED
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.download = void 0;
4
- const search_anime_1 = require("./search_anime");
4
+ const search_anime_1 = require("./url_genoration/search_anime");
5
5
  const Anime_1 = require("./Anime");
6
- const input_1 = require("./input");
6
+ const input_1 = require("./IO/input");
7
7
  async function download(cache_folder, config) {
8
8
  try {
9
9
  console.clear();
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.config_ = void 0;
4
4
  const chalk = require("chalk");
5
- const input_1 = require("../input");
5
+ const input_1 = require("../IO/input");
6
6
  const configs = [
7
7
  (async (temp) => {
8
8
  temp.player = [
@@ -78,7 +78,8 @@ const configs = [
78
78
  mpv_socket_path: "",
79
79
  vlc_socket: 0,
80
80
  vlc_pass: "",
81
- w2g_api_key: ""
81
+ w2g_api_key: "",
82
+ show_cover: false
82
83
  };
83
84
  console.log(config);
84
85
  // @ts-ignore
@@ -62,7 +62,8 @@ function load_config(cache_dir) {
62
62
  mpv_socket_path: "",
63
63
  vlc_socket: 0,
64
64
  vlc_pass: "",
65
- w2g_api_key: ""
65
+ w2g_api_key: "",
66
+ show_cover: false
66
67
  };
67
68
  if (fs.existsSync(cache_dir + "/config.conf")) {
68
69
  // @ts-ignore
package/bin/index.js CHANGED
@@ -29,22 +29,27 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
30
  const process = __importStar(require("process"));
31
31
  //process.removeAllListeners() // Ignore warning
32
+ // TODO: Use terminal-kit properly
32
33
  // External
33
34
  const appdata_path_1 = __importDefault(require("appdata-path"));
35
+ const terminal_kit = require("terminal-kit");
34
36
  const chalk = require("chalk");
35
37
  // Internal
36
38
  const Anime_1 = require("./Anime");
37
- const search_anime_1 = require("./search_anime");
39
+ const search_anime_1 = require("./url_genoration/search_anime");
38
40
  const load_config_1 = require("./file_managment/load_config");
39
- const input_1 = require("./input");
41
+ const input_1 = require("./IO/input");
40
42
  const change_config_1 = require("./file_managment/change_config");
41
43
  const cache_1 = require("./file_managment/cache");
42
44
  const download_1 = require("./download");
43
- const help_1 = require("./help");
45
+ const help_1 = require("./IO/help");
46
+ // import {display_cover} from "./cover_manager";
44
47
  const app_data_folder = (0, appdata_path_1.default)();
45
48
  const cache_folder = app_data_folder + "/ani-cli-npm";
46
49
  (0, load_config_1.make_config_dir)(cache_folder, true);
50
+ // display_cover()
47
51
  console.clear();
52
+ terminal_kit.draw("https://gogocdn.net/cover/yuri-on-ice-dub.png");
48
53
  async function main() {
49
54
  let config = (0, load_config_1.load_config)(cache_folder);
50
55
  console.log(chalk.magenta("Ani-cli-npm!\n"));
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generate_link = void 0;
4
+ const gogohd_url = "https://gogohd.net/";
5
+ const base_url = "https://animixplay.to";
6
+ const curl_1 = require("../core_utils/curl");
7
+ const regex_1 = require("../core_utils/regex");
8
+ async function generate_link(provider, id, player) {
9
+ let html_ = "";
10
+ let provider_name = "";
11
+ switch (provider) {
12
+ case 1:
13
+ html_ = await (0, curl_1.curl)(`${gogohd_url}streaming.php?id=${id}`);
14
+ provider_name = 'Xstreamcdn';
15
+ console.log(`Fetching ${provider_name} links...`);
16
+ let html = html_.split("\n");
17
+ let fb_id = "";
18
+ for (let x in html) {
19
+ if ((0, regex_1.RegexParse)(html[x], "*<li class=\"linkserver\" data-status=\"1\" data-video=\"https://fembed9hd.com/v/*")) {
20
+ fb_id = html[x].slice(html[x].indexOf("/v/") + 3, html[x].indexOf("\">X"));
21
+ break;
22
+ }
23
+ }
24
+ if (!fb_id) {
25
+ console.log("Error, no fb_id found.");
26
+ return 0;
27
+ }
28
+ //let refr = "https://fembed-hd.com/v/"+fb_id
29
+ let post = await (0, curl_1.curl)("https://fembed-hd.com/api/source/" + fb_id, "POST");
30
+ post = post.slice(post.indexOf(",\"data\":[{\"file\":\"") + 18, post.length);
31
+ post = post.slice(0, post.indexOf("\"")).replaceAll("\\/", "/");
32
+ return post;
33
+ case 2:
34
+ provider_name = 'Animixplay';
35
+ console.log(`Fetching ${provider_name} links...`);
36
+ let buffer = new Buffer(id);
37
+ let enc_id = buffer.toString("base64");
38
+ buffer = new Buffer(id + "LTXs3GrU8we9O" + enc_id);
39
+ let ani_id = buffer.toString("base64");
40
+ buffer = Buffer.from((await (0, curl_1.curl)(`${base_url}/api/live${ani_id}`, "GET", true)).split("#")[1], "base64");
41
+ if (player === "BROWSER") {
42
+ return `${base_url}/api/live${ani_id}`;
43
+ }
44
+ return buffer.toString("utf-8");
45
+ }
46
+ }
47
+ exports.generate_link = generate_link;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.search = void 0;
7
+ const regex_1 = require("../core_utils/regex");
8
+ const curl_1 = require("../core_utils/curl");
9
+ const input_1 = require("../IO/input");
10
+ const chalk_1 = __importDefault(require("chalk"));
11
+ async function search_anime(search) {
12
+ let filter = "*<ahref=\"/category/*\"title=\"*\">";
13
+ let html = (await (0, curl_1.curl)("https://gogoanime.dk//search.html?keyword=" + search)).split("\n");
14
+ let lines = [];
15
+ for (let x in html) {
16
+ html[x] = html[x].replaceAll(/ /g, '').replaceAll(/\t/g, '');
17
+ if ((0, regex_1.RegexParse)(html[x], filter)) {
18
+ html[x] = html[x].slice(html[x].indexOf("/category/") + 10);
19
+ html[x] = html[x].slice(0, html[x].indexOf("\"title="));
20
+ lines.push(html[x]);
21
+ }
22
+ }
23
+ if (!lines[0]) {
24
+ lines.pop();
25
+ }
26
+ return lines;
27
+ }
28
+ async function search() {
29
+ console.clear();
30
+ console.log(chalk_1.default.magenta("Search..."));
31
+ let _selection = await (0, input_1.input)();
32
+ let results = await search_anime(_selection);
33
+ if (results[0] === undefined) {
34
+ console.log(chalk_1.default.red("No results found."));
35
+ return 1;
36
+ }
37
+ return results[await (0, input_1.selection)(results)];
38
+ }
39
+ exports.search = search;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ani-cli-npm",
3
- "version": "2.1.3",
3
+ "version": "2.1.5",
4
4
  "description": "ani-cli tool rewritten as npm package",
5
5
  "main": "bin/index.js",
6
6
  "scripts": {