-
Notifications
You must be signed in to change notification settings - Fork 67
/
cmd.js
executable file
·179 lines (167 loc) · 4.65 KB
/
cmd.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#!/usr/bin/env node
const { program, Command, Option } = require("commander");
const chalk = require("chalk");
const packageDotJson = require("../package.json");
const { main } = require("./index");
const { generateConfig, getFileConfig } = require("./configuration");
const { setRuntimeConfig } = require("./runtimeConfig");
const { clear: clearCache } = require("./cache");
const { serve } = require("./server");
const logger = require("./logger");
require("./signalHandlers");
const { ACTIONS } = require("./constants");
async function run() {
const fileConfig = getFileConfig();
function fallback(...args) {
for (const arg of args) {
if (arg !== undefined) return arg;
}
return undefined;
}
function processOptions(options) {
options.trackers = options.trackers.split(",").filter((e) => e !== "");
if (options.action === "inject" && !options.rtorrentRpcUrl) {
logger.error(
"You need to specify --rtorrent-rpc-url when using '-A inject'."
);
process.exit(1);
}
return options;
}
function addSharedOptions() {
return this.requiredOption(
"-u, --jackett-server-url <url>",
"Your Jackett server url",
fileConfig.jackettServerUrl
)
.requiredOption(
"-k, --jackett-api-key <key>",
"Your Jackett API key",
fileConfig.jackettApiKey
)
.requiredOption(
"-t, --trackers <tracker1>,<tracker2>",
"Comma-separated list of Jackett tracker ids to search (Tracker ids can be found in their Torznab feed paths)",
fallback(
fileConfig.trackers && fileConfig.trackers.join(","),
""
)
)
.requiredOption(
"-i, --torrent-dir <dir>",
"Directory with torrent files",
fileConfig.torrentDir
)
.requiredOption(
"-s, --output-dir <dir>",
"Directory to save results in",
fileConfig.outputDir
)
.requiredOption(
"-a, --search-all",
"Search for all torrents regardless of their contents",
fallback(fileConfig.searchAll, false)
)
.requiredOption("-v, --verbose", "Log verbose output", false)
.addOption(
new Option(
"-A, --action <action>",
"If set to 'inject', cross-seed will attempt to add the found torrents to your torrent client."
)
.default(fallback(fileConfig.action, ACTIONS.SAVE))
.choices(Object.values(ACTIONS))
.makeOptionMandatory()
)
.option(
"--rtorrent-rpc-url <url>",
"The url of your rtorrent XMLRPC interface. Requires '-A inject'. See the docs for more information.",
fileConfig.rtorrentRpcUrl
);
}
// monkey patch Command with this addSharedOptions function
Command.prototype.addSharedOptions = addSharedOptions;
program.name(packageDotJson.name);
program.description(chalk.yellow.bold("cross-seed"));
program.version(
packageDotJson.version,
"-V, --version",
"output the current version"
);
program
.command("gen-config")
.description("Generate a config file")
.option(
"-d, --docker",
"Generate the docker config instead of the normal one"
)
.action((command) => {
const options = command.opts();
generateConfig(options);
});
program
.command("clear-cache")
.description("Clear the cache of downloaded-and-rejected torrents")
.action(clearCache);
program
.command("daemon")
.description("Start the cross-serve daemon")
.addSharedOptions()
.action(async (options, _command) => {
setRuntimeConfig(processOptions(options));
try {
if (process.env.DOCKER_ENV === "true") {
generateConfig({ docker: true });
}
await serve();
} catch (e) {
logger.error(chalk.bold.red(e.message));
}
});
program
.command("search")
.description("Search for cross-seeds\n")
.addSharedOptions()
.requiredOption(
"-o, --offset <offset>",
"Offset to start from",
(n) => parseInt(n),
0
)
.requiredOption(
"-d, --delay <delay>",
"Pause duration (seconds) between searches",
parseFloat,
fallback(fileConfig.delay, 10)
)
.option(
"-e, --include-episodes",
"Include single-episode torrents in the search",
fallback(fileConfig.includeEpisodes, false)
)
.option(
"-x, --exclude-older <cutoff>",
"Exclude torrents first seen more than x minutes ago. Overrides the -a flag.",
(n) => parseInt(n)
)
.option(
"-r, --exclude-recent-search <cutoff>",
"Exclude torrents which have been searched more recently than x minutes ago. Overrides the -a flag.",
(n) => parseInt(n)
)
.action(async (options, _command) => {
setRuntimeConfig(processOptions(options));
try {
await main();
} catch (e) {
console.log(e);
logger.error(chalk.bold.red(e.message));
}
});
await program.parseAsync();
}
if (require.main === module) {
run().catch((e) => {
console.error(e);
});
}
module.exports = { run };