1 | #!/usr/bin/env node
|
2 |
|
3 | const path = require('path');
|
4 | const fs = require('fs-extra');
|
5 | const fetch = require('node-fetch');
|
6 | const yargs = require('yargs');
|
7 | const semver = require('semver');
|
8 | const { downloadThreadWithDownloader } = require('..');
|
9 | const { l10n, print, CONST, Database, fetchThreads } = require('..');
|
10 |
|
11 |
|
12 | (async () => {
|
13 | const REFETCH_TIMES = 15;
|
14 | if (fs.existsSync(CONST.remoteVersionPath)) {
|
15 | let { count, version: lastRemoteVersion } = fs.readJSONSync(CONST.remoteVersionPath, 'utf-8');
|
16 | if (count > REFETCH_TIMES) {
|
17 | const data = await fetch('https://registry.npmjs.org/dmhy-subscribe').then((resp) => resp.json());
|
18 | const remoteVersion = data['dist-tags'].latest;
|
19 | count = 0;
|
20 | if (semver.gt(remoteVersion, CONST.packageVersion) || semver.gt(remoteVersion, lastRemoteVersion)) {
|
21 | console.log();
|
22 | print.info(l10n('NEW_VERSION_MSG'));
|
23 | console.log();
|
24 | }
|
25 | fs.writeJSONSync(CONST.remoteVersionPath, { count: count, version: remoteVersion });
|
26 | } else {
|
27 | fs.writeJSONSync(CONST.remoteVersionPath, { count: count + 1, version: lastRemoteVersion });
|
28 | }
|
29 | } else {
|
30 | fs.writeJSONSync(CONST.remoteVersionPath, { count: 0, version: CONST.packageVersion });
|
31 | }
|
32 | main();
|
33 | })();
|
34 |
|
35 |
|
36 |
|
37 |
|
38 | function main() {
|
39 | const command = fs.readdirSync(`${__dirname}/command`)
|
40 | .map((cmdpath) => path.basename(cmdpath, '.js'))
|
41 | .reduce((prev, cur) => {
|
42 | prev[cur] = require(`./command/${cur}`);
|
43 | return prev;
|
44 | }, {});
|
45 |
|
46 | const supportCommands = Object.entries(command).reduce((collect, [key, mod]) => {
|
47 | return collect.concat(key).concat(mod.aliases);
|
48 | }, []);
|
49 |
|
50 | const argv = yargs
|
51 | .parserConfiguration({
|
52 | yargs: {
|
53 | 'short-option-groups': false,
|
54 | },
|
55 | })
|
56 | .usage(l10n('MAIN_USAGE'))
|
57 | .command(command.add)
|
58 | .command(command.list)
|
59 | .command(command.remove)
|
60 | .command(command.search)
|
61 | .command(command.config)
|
62 | .command(command.download)
|
63 | .option('x', {
|
64 | alias: 'no-dl',
|
65 | describe: l10n('MAIN_OPT_X'),
|
66 | type: 'boolean',
|
67 | global: false,
|
68 | })
|
69 | .example('dmhy add "搖曳露營,喵萌,繁體"\ndmhy', l10n('MAIN_EXAMPLE1_DESC'))
|
70 | .help('h')
|
71 | .alias('h', 'help')
|
72 | .alias('v', 'version')
|
73 | .argv;
|
74 |
|
75 |
|
76 | if (!argv._.length) {
|
77 | const db = new Database();
|
78 |
|
79 | const allTasks = db.subscriptions.map(async (sub) => {
|
80 | const remoteThreads = await fetchThreads(sub);
|
81 | const allDownloadTasks = Promise.all(remoteThreads.map((rth) => {
|
82 | const found = sub.threads.find((th) => th.title === rth.title);
|
83 | if (!found) {
|
84 | sub.add(rth);
|
85 | if (!argv.x) {
|
86 | const downloader = db.config.get('downloader').value;
|
87 | return downloadThreadWithDownloader(downloader, rth, db.config.parameters);
|
88 | }
|
89 | }
|
90 | }));
|
91 |
|
92 |
|
93 | return new Promise((resolve, reject) => {
|
94 | allDownloadTasks.then(resolve).catch(reject);
|
95 | });
|
96 | });
|
97 |
|
98 | Promise.all(allTasks)
|
99 | .then(() => {
|
100 | if (argv.x) {
|
101 | print.success(l10n('MAIN_ALL_X_DONE'));
|
102 | } else {
|
103 | print.success(l10n('MAIN_ALL_DONE'));
|
104 | }
|
105 | db.save();
|
106 | })
|
107 | .catch((_) => {
|
108 |
|
109 | });
|
110 | } else if (argv._.length > 1 || !supportCommands.includes(argv._[0])) {
|
111 |
|
112 | yargs.showHelp();
|
113 | }
|
114 | }
|
115 |
|
116 |
|