cross-seed 2.9.3 → 3.0.3
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 +45 -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 +142 -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 -137
- 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 -143
- 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,28 +1,23 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
};
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
const constants_1 = require("../constants");
|
13
|
-
const errors_1 = require("../errors");
|
14
|
-
const logger_1 = require("../logger");
|
15
|
-
const runtimeConfig_1 = require("../runtimeConfig");
|
16
|
-
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";
|
17
12
|
async function createLibTorrentResumeTree(meta, dataDir) {
|
18
13
|
async function getFileResumeData(file) {
|
19
|
-
const filePath =
|
20
|
-
const fileStat = await
|
14
|
+
const filePath = resolve(dataDir, file.path);
|
15
|
+
const fileStat = await fs
|
21
16
|
.lstat(filePath)
|
22
17
|
.catch(() => ({ isFile: () => false }));
|
23
18
|
if (!fileStat.isFile() || fileStat.size !== file.length) {
|
24
|
-
|
25
|
-
label:
|
19
|
+
logger.debug({
|
20
|
+
label: Label.RTORRENT,
|
26
21
|
message: `File ${filePath} either doesn't exist or is the wrong size.`,
|
27
22
|
});
|
28
23
|
return {
|
@@ -43,18 +38,18 @@ async function createLibTorrentResumeTree(meta, dataDir) {
|
|
43
38
|
};
|
44
39
|
}
|
45
40
|
async function saveWithLibTorrentResume(meta, savePath, dataDir) {
|
46
|
-
const rawMeta =
|
41
|
+
const rawMeta = bencode.decode(parseTorrent.toTorrentFile(meta));
|
47
42
|
rawMeta.libtorrent_resume = await createLibTorrentResumeTree(meta, dataDir);
|
48
|
-
await
|
43
|
+
await fs.writeFile(savePath, bencode.encode(rawMeta));
|
49
44
|
}
|
50
|
-
class RTorrent {
|
45
|
+
export default class RTorrent {
|
51
46
|
constructor() {
|
52
|
-
const { rtorrentRpcUrl } =
|
47
|
+
const { rtorrentRpcUrl } = getRuntimeConfig();
|
53
48
|
try {
|
54
49
|
const { origin, username, password, protocol, pathname } = new URL(rtorrentRpcUrl);
|
55
50
|
const clientCreator = protocol === "https:"
|
56
|
-
?
|
57
|
-
:
|
51
|
+
? xmlrpc.createSecureClient
|
52
|
+
: xmlrpc.createClient;
|
58
53
|
const shouldUseAuth = Boolean(username && password);
|
59
54
|
this.client = clientCreator({
|
60
55
|
url: origin + pathname,
|
@@ -67,13 +62,16 @@ class RTorrent {
|
|
67
62
|
});
|
68
63
|
}
|
69
64
|
catch (e) {
|
70
|
-
throw new
|
65
|
+
throw new CrossSeedError("rTorrent url must be percent-encoded");
|
71
66
|
}
|
72
67
|
}
|
73
68
|
async methodCallP(method, args) {
|
74
|
-
|
75
|
-
label:
|
76
|
-
message: `Calling method ${method} with params ${
|
69
|
+
logger.verbose({
|
70
|
+
label: Label.RTORRENT,
|
71
|
+
message: `Calling method ${method} with params ${inspect(args, {
|
72
|
+
depth: null,
|
73
|
+
compact: true,
|
74
|
+
})}`,
|
77
75
|
});
|
78
76
|
return new Promise((resolve, reject) => {
|
79
77
|
this.client.methodCall(method, args, (err, data) => {
|
@@ -89,7 +87,7 @@ class RTorrent {
|
|
89
87
|
}
|
90
88
|
async getTorrentConfiguration(searchee) {
|
91
89
|
if (!searchee.infoHash) {
|
92
|
-
throw new
|
90
|
+
throw new CrossSeedError("rTorrent direct injection not implemented for data-based searchees");
|
93
91
|
}
|
94
92
|
const infoHash = searchee.infoHash.toUpperCase();
|
95
93
|
const result = await this.methodCallP("system.multicall", [
|
@@ -112,18 +110,18 @@ class RTorrent {
|
|
112
110
|
try {
|
113
111
|
const [[isMultiFileStr], [dir], [isCompleteStr]] = result;
|
114
112
|
return {
|
115
|
-
dataDir: Number(isMultiFileStr) ?
|
113
|
+
dataDir: Number(isMultiFileStr) ? dirname(dir) : dir,
|
116
114
|
isComplete: Boolean(Number(isCompleteStr)),
|
117
115
|
};
|
118
116
|
}
|
119
117
|
catch (e) {
|
120
|
-
|
121
|
-
|
122
|
-
|
118
|
+
logger.error(e);
|
119
|
+
logger.debug("Failure caused by server response below:");
|
120
|
+
logger.debug(inspect(result));
|
123
121
|
}
|
124
122
|
}
|
125
123
|
async validateConfig() {
|
126
|
-
const { rtorrentRpcUrl } =
|
124
|
+
const { rtorrentRpcUrl } = getRuntimeConfig();
|
127
125
|
// no validation to do
|
128
126
|
if (!rtorrentRpcUrl)
|
129
127
|
return;
|
@@ -131,19 +129,19 @@ class RTorrent {
|
|
131
129
|
await this.methodCallP("download_list", []);
|
132
130
|
}
|
133
131
|
catch (e) {
|
134
|
-
throw new
|
132
|
+
throw new CrossSeedError(`Failed to reach rTorrent at ${rtorrentRpcUrl}`);
|
135
133
|
}
|
136
134
|
}
|
137
135
|
async inject(meta, searchee, nonceOptions) {
|
138
|
-
const { outputDir: runtimeConfigOutputDir } =
|
136
|
+
const { outputDir: runtimeConfigOutputDir } = getRuntimeConfig();
|
139
137
|
const { outputDir = runtimeConfigOutputDir } = nonceOptions;
|
140
138
|
if (await this.checkForInfoHashInClient(meta.infoHash)) {
|
141
|
-
return
|
139
|
+
return InjectionResult.ALREADY_EXISTS;
|
142
140
|
}
|
143
141
|
const { dataDir, isComplete } = await this.getTorrentConfiguration(searchee);
|
144
142
|
if (!isComplete)
|
145
|
-
return
|
146
|
-
const torrentFilePath =
|
143
|
+
return InjectionResult.TORRENT_NOT_COMPLETE;
|
144
|
+
const torrentFilePath = resolve(outputDir, `${meta.name}.tmp.${Date.now()}.torrent`);
|
147
145
|
await saveWithLibTorrentResume(meta, torrentFilePath, dataDir);
|
148
146
|
for (let i = 0; i < 5; i++) {
|
149
147
|
try {
|
@@ -157,19 +155,18 @@ class RTorrent {
|
|
157
155
|
break;
|
158
156
|
}
|
159
157
|
catch (e) {
|
160
|
-
await
|
158
|
+
await wait(1000 * Math.pow(2, i));
|
161
159
|
}
|
162
160
|
}
|
163
161
|
for (let i = 0; i < 5; i++) {
|
164
162
|
if (await this.checkForInfoHashInClient(meta.infoHash)) {
|
165
|
-
setTimeout(() =>
|
166
|
-
return
|
163
|
+
setTimeout(() => fs.unlink(torrentFilePath), 1000);
|
164
|
+
return InjectionResult.SUCCESS;
|
167
165
|
}
|
168
|
-
await
|
166
|
+
await wait(100 * Math.pow(2, i));
|
169
167
|
}
|
170
|
-
setTimeout(() =>
|
171
|
-
return
|
168
|
+
setTimeout(() => fs.unlink(torrentFilePath), 1000);
|
169
|
+
return InjectionResult.FAILURE;
|
172
170
|
}
|
173
171
|
}
|
174
|
-
exports.default = RTorrent;
|
175
172
|
//# sourceMappingURL=RTorrent.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"RTorrent.js","sourceRoot":"","sources":["../../src/clients/RTorrent.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAS,MAAM,IAAI,CAAC;AAC3C,OAAO,YAAuC,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,MAAkB,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAgB,MAAM,qBAAqB,CAAC;AAErE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAcnC,KAAK,UAAU,0BAA0B,CACxC,IAAc,EACd,OAAe;IAEf,KAAK,UAAU,iBAAiB,CAC/B,IAAiB;QAEjB,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,MAAM,EAAE;aACvB,KAAK,CAAC,QAAQ,CAAC;aACf,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,EAAY,CAAA,CAAC,CAAC;QAClD,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,EAAE;YACxD,MAAM,CAAC,KAAK,CAAC;gBACZ,KAAK,EAAE,KAAK,CAAC,QAAQ;gBACrB,OAAO,EAAE,QAAQ,QAAQ,6CAA6C;aACtE,CAAC,CAAC;YACH,OAAO;gBACN,SAAS,EAAE,CAAC;gBACZ,KAAK,EAAE,CAAC;gBACR,QAAQ,EAAE,CAAC;aACX,CAAC;SACF;QAED,OAAO;YACN,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC;YACpD,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;YAC1C,QAAQ,EAAE,CAAC;SACX,CAAC;IACH,CAAC;IAED,OAAO;QACN,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC;QACnD,KAAK,EAAE,MAAM,OAAO,CAAC,GAAG,CACvB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CACjC;KACD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,wBAAwB,CACtC,IAAc,EACd,QAAgB,EAChB,OAAe;IAEf,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,OAAO,CAAC,iBAAiB,GAAG,MAAM,0BAA0B,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5E,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,CAAC,OAAO,OAAO,QAAQ;IAE5B;QACC,MAAM,EAAE,cAAc,EAAE,GAAG,gBAAgB,EAAE,CAAC;QAE9C,IAAI;YACH,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,IAAI,GAAG,CACjE,cAAc,CACd,CAAC;YAEF,MAAM,aAAa,GAClB,QAAQ,KAAK,QAAQ;gBACpB,CAAC,CAAC,MAAM,CAAC,kBAAkB;gBAC3B,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;YAExB,MAAM,aAAa,GAAG,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC;YAEpD,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC;gBAC3B,GAAG,EAAE,MAAM,GAAG,QAAQ;gBACtB,UAAU,EAAE,aAAa;oBACxB,CAAC,CAAC;wBACA,IAAI,EAAE,kBAAkB,CAAC,QAAQ,CAAC;wBAClC,IAAI,EAAE,kBAAkB,CAAC,QAAQ,CAAC;qBACjC;oBACH,CAAC,CAAC,SAAS;aACZ,CAAC,CAAC;SACH;QAAC,OAAO,CAAC,EAAE;YACX,MAAM,IAAI,cAAc,CAAC,sCAAsC,CAAC,CAAC;SACjE;IACF,CAAC;IAEO,KAAK,CAAC,WAAW,CAAI,MAAc,EAAE,IAAI;QAChD,MAAM,CAAC,OAAO,CAAC;YACd,KAAK,EAAE,KAAK,CAAC,QAAQ;YACrB,OAAO,EAAE,kBAAkB,MAAM,gBAAgB,OAAO,CAAC,IAAI,EAAE;gBAC9D,KAAK,EAAE,IAAI;gBACX,OAAO,EAAE,IAAI;aACb,CAAC,EAAE;SACJ,CAAC,CAAC;QACH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACtC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;gBAClD,IAAI,GAAG;oBAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC5B,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;YACtB,CAAC,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,wBAAwB,CAAC,QAAgB;QAC9C,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,WAAW,CAC1C,eAAe,EACf,EAAE,CACF,CAAC;QACF,OAAO,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,uBAAuB,CAC5B,QAAkB;QAElB,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE;YACvB,MAAM,IAAI,cAAc,CACvB,oEAAoE,CACpE,CAAC;SACF;QACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QAEjD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAa,kBAAkB,EAAE;YACrE;gBACC;oBACC,UAAU,EAAE,iBAAiB;oBAC7B,MAAM,EAAE,CAAC,QAAQ,CAAC;iBAClB;gBACD;oBACC,UAAU,EAAE,aAAa;oBACzB,MAAM,EAAE,CAAC,QAAQ,CAAC;iBAClB;gBACD;oBACC,UAAU,EAAE,YAAY;oBACxB,MAAM,EAAE,CAAC,QAAQ,CAAC;iBAClB;aACD;SACD,CAAC,CAAC;QAEH,qBAAqB;QACrB,IAAI;YACH,MAAM,CAAC,CAAC,cAAc,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,GAAG,MAAM,CAAC;YAC1D,OAAO;gBACN,OAAO,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG;gBACpD,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;aAC1C,CAAC;SACF;QAAC,OAAO,CAAC,EAAE;YACX,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAChB,MAAM,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;YACzD,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;SAC9B;IACF,CAAC;IAED,KAAK,CAAC,cAAc;QACnB,MAAM,EAAE,cAAc,EAAE,GAAG,gBAAgB,EAAE,CAAC;QAC9C,sBAAsB;QACtB,IAAI,CAAC,cAAc;YAAE,OAAO;QAE5B,IAAI;YACH,MAAM,IAAI,CAAC,WAAW,CAAW,eAAe,EAAE,EAAE,CAAC,CAAC;SACtD;QAAC,OAAO,CAAC,EAAE;YACX,MAAM,IAAI,cAAc,CACvB,+BAA+B,cAAc,EAAE,CAC/C,CAAC;SACF;IACF,CAAC;IAED,KAAK,CAAC,MAAM,CACX,IAAc,EACd,QAAkB,EAClB,YAA0B;QAE1B,MAAM,EAAE,SAAS,EAAE,sBAAsB,EAAE,GAAG,gBAAgB,EAAE,CAAC;QACjE,MAAM,EAAE,SAAS,GAAG,sBAAsB,EAAE,GAAG,YAAY,CAAC;QAE5D,IAAI,MAAM,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;YACvD,OAAO,eAAe,CAAC,cAAc,CAAC;SACtC;QAED,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,IAAI,CAAC,uBAAuB,CACjE,QAAQ,CACR,CAAC;QAEF,IAAI,CAAC,UAAU;YAAE,OAAO,eAAe,CAAC,oBAAoB,CAAC;QAE7D,MAAM,eAAe,GAAG,OAAO,CAC9B,SAAS,EACT,GAAG,IAAI,CAAC,IAAI,QAAQ,IAAI,CAAC,GAAG,EAAE,UAAU,CACxC,CAAC;QACF,MAAM,wBAAwB,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC;QAE/D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC3B,IAAI;gBACH,MAAM,IAAI,CAAC,WAAW,CAAO,YAAY,EAAE;oBAC1C,EAAE;oBACF,eAAe;oBACf,oBAAoB,OAAO,GAAG;oBAC9B,4BAA4B;oBAC5B,wBAAwB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE;iBACvD,CAAC,CAAC;gBACH,MAAM;aACN;YAAC,OAAO,CAAC,EAAE;gBACX,MAAM,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;aAClC;SACD;QAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC3B,IAAI,MAAM,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;gBACvD,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,IAAI,CAAC,CAAC;gBACnD,OAAO,eAAe,CAAC,OAAO,CAAC;aAC/B;YACD,MAAM,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;SACjC;QACD,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,IAAI,CAAC,CAAC;QACnD,OAAO,eAAe,CAAC,OAAO,CAAC;IAChC,CAAC;CACD"}
|
@@ -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
|