cross-seed 2.9.1 → 3.0.1
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 +2 -1
- package/dist/{src/clients → clients}/QBittorrent.js +31 -37
- package/dist/clients/QBittorrent.js.map +1 -0
- package/dist/{src/clients → clients}/RTorrent.js +52 -48
- package/dist/clients/RTorrent.js.map +1 -0
- package/dist/clients/TorrentClient.js +20 -0
- package/dist/clients/TorrentClient.js.map +1 -0
- package/dist/cmd.js +148 -0
- package/dist/cmd.js.map +1 -0
- package/dist/{src/config.template.js → config.template.cjs} +4 -2
- package/dist/config.template.cjs.map +1 -0
- package/dist/{src/config.template.docker.js → config.template.docker.cjs} +4 -3
- package/dist/config.template.docker.cjs.map +1 -0
- package/dist/configuration.js +39 -0
- package/dist/configuration.js.map +1 -0
- package/dist/constants.js +33 -0
- package/dist/constants.js.map +1 -0
- package/dist/db.js +29 -0
- package/dist/db.js.map +1 -0
- package/dist/decide.js +134 -0
- package/dist/decide.js.map +1 -0
- package/dist/diff.js +23 -0
- package/dist/diff.js.map +1 -0
- package/dist/errors.js +11 -0
- package/dist/errors.js.map +1 -0
- package/dist/jackett.js +68 -0
- package/dist/jackett.js.map +1 -0
- package/dist/logger.js +88 -0
- package/dist/logger.js.map +1 -0
- package/dist/pipeline.js +134 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/preFilter.js +66 -0
- package/dist/preFilter.js.map +1 -0
- package/dist/pushNotifier.js +27 -0
- package/dist/pushNotifier.js.map +1 -0
- package/dist/runtimeConfig.js +12 -0
- package/dist/runtimeConfig.js.map +1 -0
- package/dist/searchee.js +52 -0
- package/dist/searchee.js.map +1 -0
- package/dist/{src/server.js → server.js} +23 -30
- package/dist/server.js.map +1 -0
- package/dist/{src/signalHandlers.js → signalHandlers.js} +0 -0
- package/dist/signalHandlers.js.map +1 -0
- package/dist/startup.js +24 -0
- package/dist/startup.js.map +1 -0
- package/dist/torrent.js +128 -0
- package/dist/torrent.js.map +1 -0
- package/dist/utils.js +28 -0
- package/dist/utils.js.map +1 -0
- package/package.json +22 -25
- package/dist/package.json +0 -68
- package/dist/src/clients/QBittorrent.js.map +0 -1
- package/dist/src/clients/RTorrent.js.map +0 -1
- package/dist/src/clients/TorrentClient.js +0 -27
- package/dist/src/clients/TorrentClient.js.map +0 -1
- package/dist/src/cmd.js +0 -136
- package/dist/src/cmd.js.map +0 -1
- package/dist/src/config.template.docker.js.map +0 -1
- package/dist/src/config.template.js.map +0 -1
- package/dist/src/configuration.js +0 -66
- package/dist/src/configuration.js.map +0 -1
- package/dist/src/constants.js +0 -39
- package/dist/src/constants.js.map +0 -1
- package/dist/src/db.js +0 -34
- package/dist/src/db.js.map +0 -1
- package/dist/src/decide.js +0 -140
- package/dist/src/decide.js.map +0 -1
- package/dist/src/errors.js +0 -15
- package/dist/src/errors.js.map +0 -1
- package/dist/src/jackett.js +0 -76
- package/dist/src/jackett.js.map +0 -1
- package/dist/src/logger.js +0 -78
- package/dist/src/logger.js.map +0 -1
- package/dist/src/pipeline.js +0 -140
- package/dist/src/pipeline.js.map +0 -1
- package/dist/src/preFilter.js +0 -77
- package/dist/src/preFilter.js.map +0 -1
- package/dist/src/pushNotifier.js +0 -35
- package/dist/src/pushNotifier.js.map +0 -1
- package/dist/src/runtimeConfig.js +0 -17
- package/dist/src/runtimeConfig.js.map +0 -1
- package/dist/src/searchee.js +0 -72
- package/dist/src/searchee.js.map +0 -1
- package/dist/src/server.js.map +0 -1
- package/dist/src/signalHandlers.js.map +0 -1
- package/dist/src/startup.js +0 -28
- package/dist/src/startup.js.map +0 -1
- package/dist/src/torrent.js +0 -169
- package/dist/src/torrent.js.map +0 -1
- package/dist/src/utils.js +0 -39
- package/dist/src/utils.js.map +0 -1
package/README.md
CHANGED
@@ -19,7 +19,7 @@ delivery into your client.
|
|
19
19
|
|
20
20
|
## Requirements
|
21
21
|
|
22
|
-
- [Node
|
22
|
+
- [Node 14+](https://nodejs.org/en/download)
|
23
23
|
- [Jackett](https://github.com/Jackett/Jackett)
|
24
24
|
|
25
25
|
It will work on Mac and on Linux; I haven't tested it on Windows but it should
|
@@ -59,6 +59,7 @@ Options:
|
|
59
59
|
-i, --torrent-dir <dir> Directory with torrent files
|
60
60
|
-s, --output-dir <dir> Directory to save results in
|
61
61
|
-a, --search-all Search for all torrents regardless of their contents (default: false)
|
62
|
+
--fuzzy-size-threshold <decimal> The size difference allowed to be considered a match. (default: 0.02)
|
62
63
|
-v, --verbose Log verbose output (default: false)
|
63
64
|
-A, --action <action> If set to 'inject', cross-seed will attempt to add the found torrents to your torrent client. (choices: "save", "inject", default: "save")
|
64
65
|
--rtorrent-rpc-url <url> The url of your rtorrent XMLRPC interface. Requires '-A inject'. See the docs for more information.
|
@@ -1,57 +1,52 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
const querystring_1 = __importDefault(require("querystring"));
|
10
|
-
const constants_1 = require("../constants");
|
11
|
-
const errors_1 = require("../errors");
|
12
|
-
const logger_1 = require("../logger");
|
13
|
-
const runtimeConfig_1 = require("../runtimeConfig");
|
1
|
+
import FormData from "form-data";
|
2
|
+
import fetch from "node-fetch";
|
3
|
+
import parseTorrent from "parse-torrent";
|
4
|
+
import querystring from "querystring";
|
5
|
+
import { InjectionResult } from "../constants.js";
|
6
|
+
import { CrossSeedError } from "../errors.js";
|
7
|
+
import { Label, logger } from "../logger.js";
|
8
|
+
import { getRuntimeConfig } from "../runtimeConfig.js";
|
14
9
|
const X_WWW_FORM_URLENCODED = {
|
15
10
|
"Content-Type": "application/x-www-form-urlencoded",
|
16
11
|
};
|
17
|
-
class QBittorrent {
|
12
|
+
export default class QBittorrent {
|
18
13
|
constructor() {
|
19
|
-
const { qbittorrentUrl } =
|
14
|
+
const { qbittorrentUrl } = getRuntimeConfig();
|
20
15
|
try {
|
21
16
|
this.url = new URL(`${qbittorrentUrl}/api/v2`);
|
22
17
|
}
|
23
18
|
catch (e) {
|
24
|
-
throw new
|
19
|
+
throw new CrossSeedError("qBittorrent url must be percent-encoded");
|
25
20
|
}
|
26
21
|
}
|
27
22
|
async login() {
|
28
23
|
const { origin, pathname, username, password } = this.url;
|
29
24
|
let qs;
|
30
25
|
try {
|
31
|
-
qs =
|
26
|
+
qs = querystring.encode({
|
32
27
|
username: decodeURIComponent(username),
|
33
28
|
password: decodeURIComponent(password),
|
34
29
|
});
|
35
30
|
}
|
36
31
|
catch (e) {
|
37
|
-
throw new
|
32
|
+
throw new CrossSeedError("qBittorrent url must be percent-encoded");
|
38
33
|
}
|
39
34
|
let response;
|
40
35
|
try {
|
41
|
-
response = await
|
36
|
+
response = await fetch(`${origin}${pathname}/auth/login?${qs}`);
|
42
37
|
}
|
43
38
|
catch (e) {
|
44
|
-
throw new
|
39
|
+
throw new CrossSeedError(`qBittorrent login failed: ${e.message}`);
|
45
40
|
}
|
46
41
|
if (response.status !== 200) {
|
47
|
-
throw new
|
42
|
+
throw new CrossSeedError(`qBittorrent login failed with code ${response.status}`);
|
48
43
|
}
|
49
44
|
const cookieArray = response.headers.raw()["set-cookie"];
|
50
45
|
if (cookieArray) {
|
51
46
|
this.cookie = cookieArray[0].split(";")[0];
|
52
47
|
}
|
53
48
|
else {
|
54
|
-
throw new
|
49
|
+
throw new CrossSeedError(`qBittorrent login failed: Invalid username or password`);
|
55
50
|
}
|
56
51
|
}
|
57
52
|
async validateConfig() {
|
@@ -59,19 +54,19 @@ class QBittorrent {
|
|
59
54
|
await this.createTag();
|
60
55
|
}
|
61
56
|
async request(path, body, headers = {}, retries = 1) {
|
62
|
-
|
63
|
-
label:
|
57
|
+
logger.verbose({
|
58
|
+
label: Label.QBITTORRENT,
|
64
59
|
message: `Making request to ${path} with body ${body.toString()}`,
|
65
60
|
});
|
66
61
|
const { origin, pathname } = this.url;
|
67
|
-
const response = await
|
62
|
+
const response = await fetch(`${origin}${pathname}${path}`, {
|
68
63
|
method: "post",
|
69
64
|
headers: { Cookie: this.cookie, ...headers },
|
70
65
|
body,
|
71
66
|
});
|
72
67
|
if (response.status === 403 && retries > 0) {
|
73
|
-
|
74
|
-
label:
|
68
|
+
logger.verbose({
|
69
|
+
label: Label.QBITTORRENT,
|
75
70
|
message: "received 403 from API. Logging in again and retrying",
|
76
71
|
});
|
77
72
|
await this.login();
|
@@ -103,14 +98,14 @@ class QBittorrent {
|
|
103
98
|
}
|
104
99
|
async inject(newTorrent, searchee, nonceOptions) {
|
105
100
|
if (await this.isInfoHashInClient(newTorrent.infoHash)) {
|
106
|
-
return
|
101
|
+
return InjectionResult.ALREADY_EXISTS;
|
107
102
|
}
|
108
|
-
const buf =
|
103
|
+
const buf = parseTorrent.toTorrentFile(newTorrent);
|
109
104
|
try {
|
110
|
-
const { save_path, category, isComplete
|
105
|
+
const { save_path, category, isComplete } = await this.getTorrentConfiguration(searchee);
|
111
106
|
if (!isComplete)
|
112
|
-
return
|
113
|
-
const formData = new
|
107
|
+
return InjectionResult.TORRENT_NOT_COMPLETE;
|
108
|
+
const formData = new FormData();
|
114
109
|
formData.append("torrents", buf, {
|
115
110
|
filename: `${newTorrent.name}.cross-seed.torrent`,
|
116
111
|
contentType: "application/x-bittorrent",
|
@@ -120,16 +115,15 @@ class QBittorrent {
|
|
120
115
|
formData.append("tags", "cross-seed");
|
121
116
|
formData.append("autoTMM", "false");
|
122
117
|
await this.request("/torrents/add", formData);
|
123
|
-
return
|
118
|
+
return InjectionResult.SUCCESS;
|
124
119
|
}
|
125
120
|
catch (e) {
|
126
|
-
|
127
|
-
label:
|
121
|
+
logger.debug({
|
122
|
+
label: Label.QBITTORRENT,
|
128
123
|
message: `injection failed: ${e.message}`,
|
129
124
|
});
|
130
|
-
return
|
125
|
+
return InjectionResult.FAILURE;
|
131
126
|
}
|
132
127
|
}
|
133
128
|
}
|
134
|
-
exports.default = QBittorrent;
|
135
129
|
//# sourceMappingURL=QBittorrent.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"QBittorrent.js","sourceRoot":"","sources":["../../src/clients/QBittorrent.ts"],"names":[],"mappings":"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"}
|
@@ -1,27 +1,23 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
};
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
const errors_1 = require("../errors");
|
13
|
-
const logger_1 = require("../logger");
|
14
|
-
const runtimeConfig_1 = require("../runtimeConfig");
|
15
|
-
const utils_1 = require("../utils");
|
1
|
+
import bencode from "bencode";
|
2
|
+
import { promises as fs } from "fs";
|
3
|
+
import parseTorrent from "parse-torrent";
|
4
|
+
import { dirname, resolve } from "path";
|
5
|
+
import { inspect } from "util";
|
6
|
+
import xmlrpc from "xmlrpc";
|
7
|
+
import { InjectionResult } from "../constants.js";
|
8
|
+
import { CrossSeedError } from "../errors.js";
|
9
|
+
import { Label, logger } from "../logger.js";
|
10
|
+
import { getRuntimeConfig } from "../runtimeConfig.js";
|
11
|
+
import { wait } from "../utils.js";
|
16
12
|
async function createLibTorrentResumeTree(meta, dataDir) {
|
17
13
|
async function getFileResumeData(file) {
|
18
|
-
const filePath =
|
19
|
-
const fileStat = await
|
14
|
+
const filePath = resolve(dataDir, file.path);
|
15
|
+
const fileStat = await fs
|
20
16
|
.lstat(filePath)
|
21
17
|
.catch(() => ({ isFile: () => false }));
|
22
18
|
if (!fileStat.isFile() || fileStat.size !== file.length) {
|
23
|
-
|
24
|
-
label:
|
19
|
+
logger.debug({
|
20
|
+
label: Label.RTORRENT,
|
25
21
|
message: `File ${filePath} either doesn't exist or is the wrong size.`,
|
26
22
|
});
|
27
23
|
return {
|
@@ -42,18 +38,18 @@ async function createLibTorrentResumeTree(meta, dataDir) {
|
|
42
38
|
};
|
43
39
|
}
|
44
40
|
async function saveWithLibTorrentResume(meta, savePath, dataDir) {
|
45
|
-
const rawMeta =
|
41
|
+
const rawMeta = bencode.decode(parseTorrent.toTorrentFile(meta));
|
46
42
|
rawMeta.libtorrent_resume = await createLibTorrentResumeTree(meta, dataDir);
|
47
|
-
await
|
43
|
+
await fs.writeFile(savePath, bencode.encode(rawMeta));
|
48
44
|
}
|
49
|
-
class RTorrent {
|
45
|
+
export default class RTorrent {
|
50
46
|
constructor() {
|
51
|
-
const { rtorrentRpcUrl } =
|
47
|
+
const { rtorrentRpcUrl } = getRuntimeConfig();
|
52
48
|
try {
|
53
49
|
const { origin, username, password, protocol, pathname } = new URL(rtorrentRpcUrl);
|
54
50
|
const clientCreator = protocol === "https:"
|
55
|
-
?
|
56
|
-
:
|
51
|
+
? xmlrpc.createSecureClient
|
52
|
+
: xmlrpc.createClient;
|
57
53
|
const shouldUseAuth = Boolean(username && password);
|
58
54
|
this.client = clientCreator({
|
59
55
|
url: origin + pathname,
|
@@ -66,13 +62,13 @@ class RTorrent {
|
|
66
62
|
});
|
67
63
|
}
|
68
64
|
catch (e) {
|
69
|
-
throw new
|
65
|
+
throw new CrossSeedError("rTorrent url must be percent-encoded");
|
70
66
|
}
|
71
67
|
}
|
72
68
|
async methodCallP(method, args) {
|
73
|
-
|
74
|
-
label:
|
75
|
-
message: `Calling method ${method} with params ${args}`,
|
69
|
+
logger.verbose({
|
70
|
+
label: Label.RTORRENT,
|
71
|
+
message: `Calling method ${method} with params ${inspect(args)}`,
|
76
72
|
});
|
77
73
|
return new Promise((resolve, reject) => {
|
78
74
|
this.client.methodCall(method, args, (err, data) => {
|
@@ -88,10 +84,10 @@ class RTorrent {
|
|
88
84
|
}
|
89
85
|
async getTorrentConfiguration(searchee) {
|
90
86
|
if (!searchee.infoHash) {
|
91
|
-
throw new
|
87
|
+
throw new CrossSeedError("rTorrent direct injection not implemented for data-based searchees");
|
92
88
|
}
|
93
89
|
const infoHash = searchee.infoHash.toUpperCase();
|
94
|
-
const
|
90
|
+
const result = await this.methodCallP("system.multicall", [
|
95
91
|
[
|
96
92
|
{
|
97
93
|
methodName: "d.is_multi_file",
|
@@ -107,13 +103,22 @@ class RTorrent {
|
|
107
103
|
},
|
108
104
|
],
|
109
105
|
]);
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
106
|
+
// temp diag for #154
|
107
|
+
try {
|
108
|
+
const [[isMultiFileStr], [dir], [isCompleteStr]] = result;
|
109
|
+
return {
|
110
|
+
dataDir: Number(isMultiFileStr) ? dirname(dir) : dir,
|
111
|
+
isComplete: Boolean(Number(isCompleteStr)),
|
112
|
+
};
|
113
|
+
}
|
114
|
+
catch (e) {
|
115
|
+
logger.error(e);
|
116
|
+
logger.debug("Failure caused by server response below:");
|
117
|
+
logger.debug(inspect(result));
|
118
|
+
}
|
114
119
|
}
|
115
120
|
async validateConfig() {
|
116
|
-
const { rtorrentRpcUrl } =
|
121
|
+
const { rtorrentRpcUrl } = getRuntimeConfig();
|
117
122
|
// no validation to do
|
118
123
|
if (!rtorrentRpcUrl)
|
119
124
|
return;
|
@@ -121,19 +126,19 @@ class RTorrent {
|
|
121
126
|
await this.methodCallP("download_list", []);
|
122
127
|
}
|
123
128
|
catch (e) {
|
124
|
-
throw new
|
129
|
+
throw new CrossSeedError(`Failed to reach rTorrent at ${rtorrentRpcUrl}`);
|
125
130
|
}
|
126
131
|
}
|
127
132
|
async inject(meta, searchee, nonceOptions) {
|
128
|
-
const { outputDir: runtimeConfigOutputDir } =
|
133
|
+
const { outputDir: runtimeConfigOutputDir } = getRuntimeConfig();
|
129
134
|
const { outputDir = runtimeConfigOutputDir } = nonceOptions;
|
130
135
|
if (await this.checkForInfoHashInClient(meta.infoHash)) {
|
131
|
-
return
|
136
|
+
return InjectionResult.ALREADY_EXISTS;
|
132
137
|
}
|
133
138
|
const { dataDir, isComplete } = await this.getTorrentConfiguration(searchee);
|
134
139
|
if (!isComplete)
|
135
|
-
return
|
136
|
-
const torrentFilePath =
|
140
|
+
return InjectionResult.TORRENT_NOT_COMPLETE;
|
141
|
+
const torrentFilePath = resolve(outputDir, `${meta.name}.tmp.${Date.now()}.torrent`);
|
137
142
|
await saveWithLibTorrentResume(meta, torrentFilePath, dataDir);
|
138
143
|
for (let i = 0; i < 5; i++) {
|
139
144
|
try {
|
@@ -147,19 +152,18 @@ class RTorrent {
|
|
147
152
|
break;
|
148
153
|
}
|
149
154
|
catch (e) {
|
150
|
-
await
|
155
|
+
await wait(1000 * Math.pow(2, i));
|
151
156
|
}
|
152
157
|
}
|
153
158
|
for (let i = 0; i < 5; i++) {
|
154
159
|
if (await this.checkForInfoHashInClient(meta.infoHash)) {
|
155
|
-
setTimeout(() =>
|
156
|
-
return
|
160
|
+
setTimeout(() => fs.unlink(torrentFilePath), 1000);
|
161
|
+
return InjectionResult.SUCCESS;
|
157
162
|
}
|
158
|
-
await
|
163
|
+
await wait(100 * Math.pow(2, i));
|
159
164
|
}
|
160
|
-
setTimeout(() =>
|
161
|
-
return
|
165
|
+
setTimeout(() => fs.unlink(torrentFilePath), 1000);
|
166
|
+
return InjectionResult.FAILURE;
|
162
167
|
}
|
163
168
|
}
|
164
|
-
exports.default = RTorrent;
|
165
169
|
//# sourceMappingURL=RTorrent.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"RTorrent.js","sourceRoot":"","sources":["../../src/clients/RTorrent.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import { getRuntimeConfig } from "../runtimeConfig.js";
|
2
|
+
import QBittorrent from "./QBittorrent.js";
|
3
|
+
import RTorrent from "./RTorrent.js";
|
4
|
+
let activeClient;
|
5
|
+
function instantiateDownloadClient() {
|
6
|
+
const { rtorrentRpcUrl, qbittorrentUrl } = getRuntimeConfig();
|
7
|
+
if (rtorrentRpcUrl) {
|
8
|
+
activeClient = new RTorrent();
|
9
|
+
}
|
10
|
+
else if (qbittorrentUrl) {
|
11
|
+
activeClient = new QBittorrent();
|
12
|
+
}
|
13
|
+
}
|
14
|
+
export function getClient() {
|
15
|
+
if (!activeClient) {
|
16
|
+
instantiateDownloadClient();
|
17
|
+
}
|
18
|
+
return activeClient;
|
19
|
+
}
|
20
|
+
//# sourceMappingURL=TorrentClient.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"TorrentClient.js","sourceRoot":"","sources":["../../src/clients/TorrentClient.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAgB,MAAM,qBAAqB,CAAC;AAErE,OAAO,WAAW,MAAM,kBAAkB,CAAC;AAC3C,OAAO,QAAQ,MAAM,eAAe,CAAC;AAErC,IAAI,YAA2B,CAAC;AAWhC,SAAS,yBAAyB;IACjC,MAAM,EAAE,cAAc,EAAE,cAAc,EAAE,GAAG,gBAAgB,EAAE,CAAC;IAC9D,IAAI,cAAc,EAAE;QACnB,YAAY,GAAG,IAAI,QAAQ,EAAE,CAAC;KAC9B;SAAM,IAAI,cAAc,EAAE;QAC1B,YAAY,GAAG,IAAI,WAAW,EAAE,CAAC;KACjC;AACF,CAAC;AAED,MAAM,UAAU,SAAS;IACxB,IAAI,CAAC,YAAY,EAAE;QAClB,yBAAyB,EAAE,CAAC;KAC5B;IACD,OAAO,YAAY,CAAC;AACrB,CAAC"}
|
package/dist/cmd.js
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
import chalk from "chalk";
|
3
|
+
import { Option, program } from "commander";
|
4
|
+
import { createRequire } from "module";
|
5
|
+
import { inspect } from "util";
|
6
|
+
import { generateConfig, getFileConfig } from "./configuration.js";
|
7
|
+
import { Action } from "./constants.js";
|
8
|
+
import { dropDatabase } from "./db.js";
|
9
|
+
import { diffCmd } from "./diff.js";
|
10
|
+
import { CrossSeedError } from "./errors.js";
|
11
|
+
import { initializeLogger, Label, logger } from "./logger.js";
|
12
|
+
import { main } from "./pipeline.js";
|
13
|
+
import { initializePushNotifier, sendTestNotification, } from "./pushNotifier.js";
|
14
|
+
import { setRuntimeConfig } from "./runtimeConfig.js";
|
15
|
+
import { createSearcheeFromMetafile } from "./searchee.js";
|
16
|
+
import { serve } from "./server.js";
|
17
|
+
import "./signalHandlers.js";
|
18
|
+
import { doStartupValidation } from "./startup.js";
|
19
|
+
import { parseTorrentFromFilename } from "./torrent.js";
|
20
|
+
const require = createRequire(import.meta.url);
|
21
|
+
const packageDotJson = require("../package.json");
|
22
|
+
function fallback(...args) {
|
23
|
+
for (const arg of args) {
|
24
|
+
if (arg !== undefined)
|
25
|
+
return arg;
|
26
|
+
}
|
27
|
+
return undefined;
|
28
|
+
}
|
29
|
+
function processOptions(options) {
|
30
|
+
var _a;
|
31
|
+
options.trackers = (_a = options.trackers) === null || _a === void 0 ? void 0 : _a.split(",").filter((e) => e !== "");
|
32
|
+
return options;
|
33
|
+
}
|
34
|
+
const fileConfig = await getFileConfig();
|
35
|
+
function createCommandWithSharedOptions(name, description) {
|
36
|
+
var _a;
|
37
|
+
return program
|
38
|
+
.command(name)
|
39
|
+
.description(description)
|
40
|
+
.requiredOption("-u, --jackett-server-url <url>", "Your Jackett server url", fileConfig.jackettServerUrl)
|
41
|
+
.requiredOption("-k, --jackett-api-key <key>", "Your Jackett API key", fileConfig.jackettApiKey)
|
42
|
+
.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((_a = fileConfig.trackers) === null || _a === void 0 ? void 0 : _a.join(","), ""))
|
43
|
+
.requiredOption("-i, --torrent-dir <dir>", "Directory with torrent files", fileConfig.torrentDir)
|
44
|
+
.requiredOption("-s, --output-dir <dir>", "Directory to save results in", fileConfig.outputDir)
|
45
|
+
.requiredOption("-a, --search-all", "Search for all torrents regardless of their contents", fallback(fileConfig.searchAll, false))
|
46
|
+
.requiredOption("--fuzzy-size-threshold <decimal>", "The size difference allowed to be considered a match.", fallback(fileConfig.fuzzySizeThreshold, 0.02))
|
47
|
+
.option("-x, --exclude-older <cutoff>", "Exclude torrents first seen more than n minutes ago. Bypasses the -a flag.", (n) => parseInt(n), fileConfig.excludeOlder)
|
48
|
+
.option("-r, --exclude-recent-search <cutoff>", "Exclude torrents which have been searched more recently than n minutes ago. Bypasses the -a flag.", (n) => parseInt(n), fileConfig.excludeRecentSearch)
|
49
|
+
.requiredOption("-v, --verbose", "Log verbose output", false)
|
50
|
+
.addOption(new Option("-A, --action <action>", "If set to 'inject', cross-seed will attempt to add the found torrents to your torrent client.")
|
51
|
+
.default(fallback(fileConfig.action, Action.SAVE))
|
52
|
+
.choices(Object.values(Action))
|
53
|
+
.makeOptionMandatory())
|
54
|
+
.option("--rtorrent-rpc-url <url>", "The url of your rtorrent XMLRPC interface. Requires '-A inject'. See the docs for more information.", fileConfig.rtorrentRpcUrl)
|
55
|
+
.option("--qbittorrent-url <url>", "The url of your qBittorrent webui. Requires '-A inject'. See the docs for more information.", fileConfig.qbittorrentUrl)
|
56
|
+
.option("--notification-webhook-url <url>", "cross-seed will send POST requests to this url with a JSON payload of { title, body }", fileConfig.notificationWebhookUrl);
|
57
|
+
}
|
58
|
+
program.name(packageDotJson.name);
|
59
|
+
program.description(chalk.yellow.bold("cross-seed"));
|
60
|
+
program.version(packageDotJson.version, "-V, --version", "output the current version");
|
61
|
+
program
|
62
|
+
.command("gen-config")
|
63
|
+
.description("Generate a config file")
|
64
|
+
.option("-d, --docker", "Generate the docker config instead of the normal one")
|
65
|
+
.action((options) => {
|
66
|
+
generateConfig(options);
|
67
|
+
});
|
68
|
+
program
|
69
|
+
.command("clear-cache")
|
70
|
+
.description("Clear the cache of downloaded-and-rejected torrents")
|
71
|
+
.action(dropDatabase);
|
72
|
+
program
|
73
|
+
.command("test-notification")
|
74
|
+
.description("Send a test notification")
|
75
|
+
.requiredOption("--notification-webhook-url <url>", "cross-seed will send POST requests to this url with a JSON payload of { title, body }", fileConfig.notificationWebhookUrl)
|
76
|
+
.action((options) => {
|
77
|
+
const runtimeConfig = processOptions(options);
|
78
|
+
setRuntimeConfig(runtimeConfig);
|
79
|
+
initializeLogger();
|
80
|
+
initializePushNotifier();
|
81
|
+
sendTestNotification();
|
82
|
+
});
|
83
|
+
program
|
84
|
+
.command("diff")
|
85
|
+
.description("Analyze two torrent files for cross-seed compatibility")
|
86
|
+
.argument("searchee")
|
87
|
+
.argument("candidate")
|
88
|
+
.action(diffCmd);
|
89
|
+
program
|
90
|
+
.command("tree")
|
91
|
+
.description("Print a torrent's file tree")
|
92
|
+
.argument("torrent")
|
93
|
+
.action(async (fn) => {
|
94
|
+
console.log(createSearcheeFromMetafile(await parseTorrentFromFilename(fn)));
|
95
|
+
});
|
96
|
+
createCommandWithSharedOptions("daemon", "Start the cross-seed daemon").action(async (options) => {
|
97
|
+
try {
|
98
|
+
const runtimeConfig = processOptions(options);
|
99
|
+
setRuntimeConfig(runtimeConfig);
|
100
|
+
initializeLogger();
|
101
|
+
initializePushNotifier();
|
102
|
+
logger.verbose({
|
103
|
+
label: Label.CONFIGDUMP,
|
104
|
+
message: inspect(runtimeConfig),
|
105
|
+
});
|
106
|
+
if (process.env.DOCKER_ENV === "true") {
|
107
|
+
generateConfig({ docker: true });
|
108
|
+
}
|
109
|
+
await doStartupValidation();
|
110
|
+
await serve();
|
111
|
+
}
|
112
|
+
catch (e) {
|
113
|
+
if (e instanceof CrossSeedError) {
|
114
|
+
e.print();
|
115
|
+
process.exitCode = 1;
|
116
|
+
return;
|
117
|
+
}
|
118
|
+
throw e;
|
119
|
+
}
|
120
|
+
});
|
121
|
+
createCommandWithSharedOptions("search", "Search for cross-seeds")
|
122
|
+
.requiredOption("-o, --offset <offset>", "Offset to start from", (n) => parseInt(n), 0)
|
123
|
+
.requiredOption("-d, --delay <delay>", "Pause duration (seconds) between searches", parseFloat, fallback(fileConfig.delay, 10))
|
124
|
+
.option("-e, --include-episodes", "Include single-episode torrents in the search", fallback(fileConfig.includeEpisodes, false))
|
125
|
+
.action(async (options) => {
|
126
|
+
try {
|
127
|
+
const runtimeConfig = processOptions(options);
|
128
|
+
setRuntimeConfig(runtimeConfig);
|
129
|
+
initializeLogger();
|
130
|
+
initializePushNotifier();
|
131
|
+
logger.verbose({
|
132
|
+
label: Label.CONFIGDUMP,
|
133
|
+
message: inspect(runtimeConfig),
|
134
|
+
});
|
135
|
+
await doStartupValidation();
|
136
|
+
await main();
|
137
|
+
}
|
138
|
+
catch (e) {
|
139
|
+
if (e instanceof CrossSeedError) {
|
140
|
+
e.print();
|
141
|
+
process.exitCode = 1;
|
142
|
+
return;
|
143
|
+
}
|
144
|
+
throw e;
|
145
|
+
}
|
146
|
+
});
|
147
|
+
await program.parseAsync();
|
148
|
+
//# sourceMappingURL=cmd.js.map
|
package/dist/cmd.js.map
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"cmd.js","sourceRoot":"","sources":["../src/cmd.ts"],"names":[],"mappings":"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"}
|
@@ -1,7 +1,6 @@
|
|
1
1
|
// If you find yourself always using the same command-line flag, you can set
|
2
2
|
// it here as a default.
|
3
3
|
module.exports = {
|
4
|
-
configVersion: 1,
|
5
4
|
jackettServerUrl: "http://localhost:9117/jackett",
|
6
5
|
jackettApiKey: "YOUR_JACKETT_API_KEY_HERE",
|
7
6
|
// Pause at least this much in between each Jackett search. Higher is safer.
|
@@ -23,6 +22,9 @@ module.exports = {
|
|
23
22
|
// search for all torrents, regardless of their contents
|
24
23
|
// this option overrides includeEpisodes.
|
25
24
|
searchAll: false,
|
25
|
+
// fuzzy size match threshold
|
26
|
+
// decimal value (0.02 = 2%)
|
27
|
+
fuzzySizeThreshold: 0.02,
|
26
28
|
// Exclude torrents first seen more than n minutes ago.
|
27
29
|
excludeOlder: undefined,
|
28
30
|
// Exclude torrents which have been searched
|
@@ -45,4 +47,4 @@ module.exports = {
|
|
45
47
|
// Conforms to the caronc/apprise REST API.
|
46
48
|
notificationWebhookUrl: undefined,
|
47
49
|
};
|
48
|
-
//# sourceMappingURL=config.template.
|
50
|
+
//# sourceMappingURL=config.template.cjs.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"config.template.cjs","sourceRoot":"","sources":["../src/config.template.cjs"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,wBAAwB;AAExB,MAAM,CAAC,OAAO,GAAG;IAChB,gBAAgB,EAAE,+BAA+B;IACjD,aAAa,EAAE,2BAA2B;IAE1C,4EAA4E;IAC5E,4DAA4D;IAC5D,KAAK,EAAE,EAAE;IAET,qBAAqB;IACrB,gDAAgD;IAChD,uDAAuD;IACvD,QAAQ,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC;IAEnC,sCAAsC;IACtC,+CAA+C;IAC/C,2CAA2C;IAC3C,8CAA8C;IAC9C,UAAU,EAAE,2BAA2B;IAEvC,gEAAgE;IAChE,SAAS,EAAE,GAAG;IAEd,gDAAgD;IAChD,eAAe,EAAE,KAAK;IAEtB,wDAAwD;IACxD,yCAAyC;IACzC,SAAS,EAAE,KAAK;IAEhB,6BAA6B;IAC7B,4BAA4B;IAC5B,kBAAkB,EAAE,IAAI;IAExB,uDAAuD;IACvD,YAAY,EAAE,SAAS;IAEvB,4CAA4C;IAC5C,oCAAoC;IACpC,mBAAmB,EAAE,SAAS;IAE9B,oCAAoC;IACpC,6DAA6D;IAC7D,MAAM,EAAE,MAAM;IAEd,6CAA6C;IAC7C,uCAAuC;IACvC,wEAAwE;IACxE,cAAc,EAAE,SAAS;IAEzB,qCAAqC;IACrC,uCAAuC;IACvC,4DAA4D;IAC5D,4CAA4C;IAC5C,cAAc,EAAE,SAAS;IAEzB,iDAAiD;IACjD,0CAA0C;IAC1C,2CAA2C;IAC3C,sBAAsB,EAAE,SAAS;CACjC,CAAC"}
|
@@ -1,5 +1,3 @@
|
|
1
|
-
// All of the configuration can be overridden with command-line flags,
|
2
|
-
// and some are more useful as flags than permanent config (offset).
|
3
1
|
// If you find yourself always using the same command-line flag, you can set
|
4
2
|
// it here as a default.
|
5
3
|
module.exports = {
|
@@ -28,6 +26,9 @@ module.exports = {
|
|
28
26
|
// search for all torrents, regardless of their contents
|
29
27
|
// this option overrides includeEpisodes.
|
30
28
|
searchAll: false,
|
29
|
+
// fuzzy size match threshold
|
30
|
+
// decimal value (0.02 = 2%)
|
31
|
+
fuzzySizeThreshold: 0.02,
|
31
32
|
// Exclude torrents first seen more than n minutes ago.
|
32
33
|
excludeOlder: undefined,
|
33
34
|
// Exclude torrents which have been searched
|
@@ -50,4 +51,4 @@ module.exports = {
|
|
50
51
|
// Conforms to the caronc/apprise REST API.
|
51
52
|
notificationWebhookUrl: undefined,
|
52
53
|
};
|
53
|
-
//# sourceMappingURL=config.template.docker.
|
54
|
+
//# sourceMappingURL=config.template.docker.cjs.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"config.template.docker.cjs","sourceRoot":"","sources":["../src/config.template.docker.cjs"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,wBAAwB;AAExB,MAAM,CAAC,OAAO,GAAG;IAChB,gBAAgB,EAAE,6BAA6B;IAC/C,aAAa,EAAE,2BAA2B;IAE1C,4EAA4E;IAC5E,4DAA4D;IAC5D,KAAK,EAAE,EAAE;IAET,qBAAqB;IACrB,gDAAgD;IAChD,uDAAuD;IACvD,QAAQ,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC;IAEnC,sCAAsC;IACtC,+CAA+C;IAC/C,2CAA2C;IAC3C,8CAA8C;IAC9C,gCAAgC;IAChC,2DAA2D;IAC3D,UAAU,EAAE,WAAW;IAEvB,gEAAgE;IAChE,gCAAgC;IAChC,2DAA2D;IAC3D,SAAS,EAAE,cAAc;IAEzB,gDAAgD;IAChD,eAAe,EAAE,KAAK;IAEtB,wDAAwD;IACxD,yCAAyC;IACzC,SAAS,EAAE,KAAK;IAEhB,6BAA6B;IAC7B,4BAA4B;IAC5B,kBAAkB,EAAE,IAAI;IAExB,uDAAuD;IACvD,YAAY,EAAE,SAAS;IAEvB,4CAA4C;IAC5C,oCAAoC;IACpC,mBAAmB,EAAE,SAAS;IAE9B,oCAAoC;IACpC,6DAA6D;IAC7D,MAAM,EAAE,MAAM;IAEd,6CAA6C;IAC7C,uCAAuC;IACvC,wEAAwE;IACxE,cAAc,EAAE,SAAS;IAEzB,qCAAqC;IACrC,uCAAuC;IACvC,4DAA4D;IAC5D,4CAA4C;IAC5C,cAAc,EAAE,SAAS;IAEzB,iDAAiD;IACjD,0CAA0C;IAC1C,2CAA2C;IAC3C,sBAAsB,EAAE,SAAS;CACjC,CAAC"}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
import chalk from "chalk";
|
2
|
+
import { copyFileSync, existsSync, mkdirSync } from "fs";
|
3
|
+
import { createRequire } from "module";
|
4
|
+
import path from "path";
|
5
|
+
const require = createRequire(import.meta.url);
|
6
|
+
const packageDotJson = require("../package.json");
|
7
|
+
export function appDir() {
|
8
|
+
return (process.env.CONFIG_DIR ||
|
9
|
+
(process.platform === "win32"
|
10
|
+
? path.resolve(process.env.LOCALAPPDATA, packageDotJson.name)
|
11
|
+
: path.resolve(process.env.HOME, `.${packageDotJson.name}`)));
|
12
|
+
}
|
13
|
+
export function createAppDir() {
|
14
|
+
mkdirSync(path.join(appDir(), "torrent_cache"), { recursive: true });
|
15
|
+
mkdirSync(path.join(appDir(), "logs"), { recursive: true });
|
16
|
+
}
|
17
|
+
export function generateConfig({ force = false, docker = false, }) {
|
18
|
+
createAppDir();
|
19
|
+
const dest = path.join(appDir(), "config.js");
|
20
|
+
const templatePath = path.join(`./config.template${docker ? ".docker" : ""}.cjs`);
|
21
|
+
if (!force && existsSync(dest)) {
|
22
|
+
console.log("Configuration file already exists.");
|
23
|
+
return;
|
24
|
+
}
|
25
|
+
copyFileSync(new URL(templatePath, import.meta.url), dest);
|
26
|
+
console.log("Configuration file created at", chalk.yellow.bold(dest));
|
27
|
+
}
|
28
|
+
export async function getFileConfig() {
|
29
|
+
const configPath = path.join(appDir(), "config.js");
|
30
|
+
try {
|
31
|
+
return (await import(configPath)).default;
|
32
|
+
}
|
33
|
+
catch (e) {
|
34
|
+
if (e.code !== "ERR_MODULE_NOT_FOUND")
|
35
|
+
throw e;
|
36
|
+
return {};
|
37
|
+
}
|
38
|
+
}
|
39
|
+
//# sourceMappingURL=configuration.js.map
|