cross-seed 5.9.2 → 6.0.0-0
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 +1 -1
- package/dist/Result.js +2 -0
- package/dist/Result.js.map +1 -1
- package/dist/action.js +117 -57
- package/dist/action.js.map +1 -1
- package/dist/auth.js +5 -5
- package/dist/auth.js.map +1 -1
- package/dist/clients/Deluge.js +68 -36
- package/dist/clients/Deluge.js.map +1 -1
- package/dist/clients/QBittorrent.js +40 -30
- package/dist/clients/QBittorrent.js.map +1 -1
- package/dist/clients/RTorrent.js +61 -23
- package/dist/clients/RTorrent.js.map +1 -1
- package/dist/clients/TorrentClient.js.map +1 -1
- package/dist/clients/Transmission.js +18 -8
- package/dist/clients/Transmission.js.map +1 -1
- package/dist/cmd.js +76 -75
- package/dist/cmd.js.map +1 -1
- package/dist/config.template.cjs +226 -142
- package/dist/config.template.cjs.map +1 -1
- package/dist/configSchema.js +184 -0
- package/dist/configSchema.js.map +1 -0
- package/dist/configuration.js +35 -9
- package/dist/configuration.js.map +1 -1
- package/dist/constants.js +26 -12
- package/dist/constants.js.map +1 -1
- package/dist/dataFiles.js +17 -8
- package/dist/dataFiles.js.map +1 -1
- package/dist/decide.js +91 -28
- package/dist/decide.js.map +1 -1
- package/dist/diff.js.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/indexers.js +3 -3
- package/dist/indexers.js.map +1 -1
- package/dist/jobs.js +15 -7
- package/dist/jobs.js.map +1 -1
- package/dist/logger.js +9 -9
- package/dist/logger.js.map +1 -1
- package/dist/migrations/00-initialSchema.js.map +1 -1
- package/dist/migrations/02-timestamps.js +3 -1
- package/dist/migrations/02-timestamps.js.map +1 -1
- package/dist/parseTorrent.js +11 -2
- package/dist/parseTorrent.js.map +1 -1
- package/dist/pipeline.js +34 -25
- package/dist/pipeline.js.map +1 -1
- package/dist/preFilter.js +17 -6
- package/dist/preFilter.js.map +1 -1
- package/dist/pushNotifier.js +29 -10
- package/dist/pushNotifier.js.map +1 -1
- package/dist/runtimeConfig.js.map +1 -1
- package/dist/searchee.js +8 -1
- package/dist/searchee.js.map +1 -1
- package/dist/server.js.map +1 -1
- package/dist/startup.js +62 -23
- package/dist/startup.js.map +1 -1
- package/dist/torrent.js +14 -29
- package/dist/torrent.js.map +1 -1
- package/dist/torznab.js +56 -32
- package/dist/torznab.js.map +1 -1
- package/dist/utils.js +32 -5
- package/dist/utils.js.map +1 -1
- package/package.json +23 -13
- package/dist/config.template.docker.cjs +0 -236
- package/dist/config.template.docker.cjs.map +0 -1
@@ -1,18 +1,16 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import { unlink, writeFile } from "fs/promises";
|
4
|
-
import fetch from "node-fetch";
|
5
|
-
import { join, posix } from "path";
|
6
|
-
import { appDir } from "../configuration.js";
|
7
|
-
import { InjectionResult, TORRENT_CACHE_FOLDER } from "../constants.js";
|
1
|
+
import { posix } from "path";
|
2
|
+
import { Decision, InjectionResult, TORRENT_TAG, TORRENT_CATEGORY_SUFFIX, } from "../constants.js";
|
8
3
|
import { CrossSeedError } from "../errors.js";
|
9
4
|
import { Label, logger, logOnce } from "../logger.js";
|
10
5
|
import { getRuntimeConfig } from "../runtimeConfig.js";
|
11
6
|
import { extractCredentialsFromUrl } from "../utils.js";
|
7
|
+
import { resultOf, resultOfErr } from "../Result.js";
|
12
8
|
const X_WWW_FORM_URLENCODED = {
|
13
9
|
"Content-Type": "application/x-www-form-urlencoded",
|
14
10
|
};
|
15
11
|
export default class QBittorrent {
|
12
|
+
cookie;
|
13
|
+
url;
|
16
14
|
constructor() {
|
17
15
|
const { qbittorrentUrl } = getRuntimeConfig();
|
18
16
|
this.url = extractCredentialsFromUrl(qbittorrentUrl, "/api/v2").unwrapOrThrow(new CrossSeedError("qBittorrent url must be percent-encoded"));
|
@@ -32,11 +30,8 @@ export default class QBittorrent {
|
|
32
30
|
if (response.status !== 200) {
|
33
31
|
throw new CrossSeedError(`qBittorrent login failed with code ${response.status}`);
|
34
32
|
}
|
35
|
-
|
36
|
-
if (
|
37
|
-
this.cookie = cookieArray[0].split(";")[0];
|
38
|
-
}
|
39
|
-
else {
|
33
|
+
this.cookie = response.headers.getSetCookie()[0];
|
34
|
+
if (!this.cookie) {
|
40
35
|
throw new CrossSeedError(`qBittorrent login failed: Invalid username or password`);
|
41
36
|
}
|
42
37
|
}
|
@@ -65,14 +60,16 @@ export default class QBittorrent {
|
|
65
60
|
return response.text();
|
66
61
|
}
|
67
62
|
async setUpCrossSeedCategory(ogCategoryName) {
|
63
|
+
const { dataCategory } = getRuntimeConfig();
|
68
64
|
if (!ogCategoryName)
|
69
65
|
return "";
|
70
|
-
if (ogCategoryName.endsWith(
|
66
|
+
if (ogCategoryName.endsWith(TORRENT_CATEGORY_SUFFIX) ||
|
67
|
+
ogCategoryName === dataCategory)
|
71
68
|
return ogCategoryName;
|
72
69
|
const categoriesStr = await this.request("/torrents/categories", "");
|
73
70
|
const categories = JSON.parse(categoriesStr);
|
74
71
|
const ogCategory = categories[ogCategoryName];
|
75
|
-
const newCategoryName = `${ogCategoryName}
|
72
|
+
const newCategoryName = `${ogCategoryName}${TORRENT_CATEGORY_SUFFIX}`;
|
76
73
|
const maybeNewCategory = categories[newCategoryName];
|
77
74
|
if (!ogCategory.savePath) {
|
78
75
|
logOnce(`qbit/cat/no-save-path/${ogCategoryName}`, () => {
|
@@ -91,7 +88,7 @@ export default class QBittorrent {
|
|
91
88
|
return newCategoryName;
|
92
89
|
}
|
93
90
|
async createTag() {
|
94
|
-
await this.request("/torrents/createTags",
|
91
|
+
await this.request("/torrents/createTags", `tags=${TORRENT_TAG}`, X_WWW_FORM_URLENCODED);
|
95
92
|
}
|
96
93
|
async isInfoHashInClient(infoHash) {
|
97
94
|
const responseText = await this.request("/torrents/properties", `hash=${infoHash}`, X_WWW_FORM_URLENCODED);
|
@@ -103,6 +100,24 @@ export default class QBittorrent {
|
|
103
100
|
return false;
|
104
101
|
}
|
105
102
|
}
|
103
|
+
async getDownloadDir(searchee) {
|
104
|
+
let torrentInfo;
|
105
|
+
try {
|
106
|
+
if (await this.isInfoHashInClient(searchee.infoHash)) {
|
107
|
+
torrentInfo = await this.getTorrentConfiguration(searchee);
|
108
|
+
if (torrentInfo.save_path === undefined) {
|
109
|
+
return resultOfErr("NOT_FOUND");
|
110
|
+
}
|
111
|
+
}
|
112
|
+
}
|
113
|
+
catch (e) {
|
114
|
+
if (e.includes("retrieve")) {
|
115
|
+
return resultOfErr("NOT_FOUND");
|
116
|
+
}
|
117
|
+
return resultOfErr("UNKNOWN_ERROR");
|
118
|
+
}
|
119
|
+
return resultOf(torrentInfo.save_path);
|
120
|
+
}
|
106
121
|
async getTorrentConfiguration(searchee) {
|
107
122
|
const responseText = await this.request("/torrents/info", `hashes=${searchee.infoHash}`, X_WWW_FORM_URLENCODED);
|
108
123
|
const searchResult = JSON.parse(responseText).find((e) => e.hash === searchee.infoHash);
|
@@ -123,16 +138,16 @@ export default class QBittorrent {
|
|
123
138
|
const [{ name }] = files;
|
124
139
|
return files.length === 1 && name !== posix.basename(name);
|
125
140
|
}
|
126
|
-
async inject(newTorrent, searchee, path) {
|
141
|
+
async inject(newTorrent, searchee, decision, path) {
|
127
142
|
const { duplicateCategories, skipRecheck, dataCategory } = getRuntimeConfig();
|
128
|
-
const filename = `${newTorrent.getFileSystemSafeName()}.cross-seed.torrent`;
|
129
|
-
const tempFilepath = join(appDir(), TORRENT_CACHE_FOLDER, filename);
|
130
143
|
try {
|
131
144
|
if (await this.isInfoHashInClient(newTorrent.infoHash)) {
|
132
145
|
return InjectionResult.ALREADY_EXISTS;
|
133
146
|
}
|
134
|
-
const
|
135
|
-
|
147
|
+
const filename = `${newTorrent.getFileSystemSafeName()}.cross-seed.torrent`;
|
148
|
+
const buffer = new Blob([newTorrent.encode()], {
|
149
|
+
type: "application/x-bittorrent",
|
150
|
+
});
|
136
151
|
const { save_path, isComplete, autoTMM, category } = path
|
137
152
|
? {
|
138
153
|
save_path: path,
|
@@ -151,10 +166,10 @@ export default class QBittorrent {
|
|
151
166
|
(await this.isSubfolderContentLayout(searchee))
|
152
167
|
? "Subfolder"
|
153
168
|
: "Original";
|
154
|
-
const
|
169
|
+
const skipRecheckTorrent = decision === Decision.MATCH_PARTIAL ? skipRecheck : true;
|
155
170
|
const formData = new FormData();
|
156
|
-
formData.append("torrents",
|
157
|
-
formData.append("tags",
|
171
|
+
formData.append("torrents", buffer, filename);
|
172
|
+
formData.append("tags", TORRENT_TAG);
|
158
173
|
formData.append("category", newCategoryName);
|
159
174
|
if (autoTMM) {
|
160
175
|
formData.append("autoTMM", "true");
|
@@ -170,8 +185,8 @@ export default class QBittorrent {
|
|
170
185
|
}
|
171
186
|
else {
|
172
187
|
formData.append("contentLayout", contentLayout);
|
173
|
-
formData.append("skip_checking",
|
174
|
-
formData.append("paused",
|
188
|
+
formData.append("skip_checking", skipRecheckTorrent.toString());
|
189
|
+
formData.append("paused", (!skipRecheckTorrent).toString());
|
175
190
|
}
|
176
191
|
// for some reason the parser parses the last kv pair incorrectly
|
177
192
|
// it concats the value and the sentinel
|
@@ -190,11 +205,6 @@ export default class QBittorrent {
|
|
190
205
|
});
|
191
206
|
return InjectionResult.FAILURE;
|
192
207
|
}
|
193
|
-
finally {
|
194
|
-
await unlink(tempFilepath).catch((error) => {
|
195
|
-
logger.debug(error);
|
196
|
-
});
|
197
|
-
}
|
198
208
|
}
|
199
209
|
}
|
200
210
|
//# sourceMappingURL=QBittorrent.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"QBittorrent.js","sourceRoot":"","sources":["../../src/clients/QBittorrent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
1
|
+
{"version":3,"file":"QBittorrent.js","sourceRoot":"","sources":["../../src/clients/QBittorrent.ts"],"names":[],"mappings":"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"}
|
package/dist/clients/RTorrent.js
CHANGED
@@ -1,14 +1,15 @@
|
|
1
|
-
import {
|
1
|
+
import { stat, unlink, writeFile } from "fs/promises";
|
2
2
|
import { dirname, join, resolve, sep } from "path";
|
3
3
|
import { inspect } from "util";
|
4
4
|
import xmlrpc from "xmlrpc";
|
5
|
-
import { InjectionResult } from "../constants.js";
|
5
|
+
import { Decision, InjectionResult, TORRENT_TAG } from "../constants.js";
|
6
6
|
import { CrossSeedError } from "../errors.js";
|
7
7
|
import { Label, logger } from "../logger.js";
|
8
8
|
import { Metafile } from "../parseTorrent.js";
|
9
9
|
import { resultOf, resultOfErr } from "../Result.js";
|
10
10
|
import { getRuntimeConfig } from "../runtimeConfig.js";
|
11
11
|
import { extractCredentialsFromUrl, wait } from "../utils.js";
|
12
|
+
const COULD_NOT_FIND_INFO_HASH = "Could not find info-hash.";
|
12
13
|
async function createLibTorrentResumeTree(meta, basePath) {
|
13
14
|
async function getFileResumeData(file) {
|
14
15
|
const filePathWithoutFirstSegment = file.path
|
@@ -16,9 +17,7 @@ async function createLibTorrentResumeTree(meta, basePath) {
|
|
16
17
|
.slice(1)
|
17
18
|
.join(sep);
|
18
19
|
const resolvedFilePath = resolve(basePath, filePathWithoutFirstSegment);
|
19
|
-
const fileStat = await
|
20
|
-
.stat(resolvedFilePath)
|
21
|
-
.catch(() => ({ isFile: () => false }));
|
20
|
+
const fileStat = await stat(resolvedFilePath).catch(() => ({ isFile: () => false }));
|
22
21
|
if (!fileStat.isFile() || fileStat.size !== file.length) {
|
23
22
|
logger.debug({
|
24
23
|
label: Label.RTORRENT,
|
@@ -46,9 +45,10 @@ async function saveWithLibTorrentResume(meta, savePath, basePath) {
|
|
46
45
|
...meta.raw,
|
47
46
|
libtorrent_resume: await createLibTorrentResumeTree(meta, basePath),
|
48
47
|
};
|
49
|
-
await
|
48
|
+
await writeFile(savePath, new Metafile(rawWithLibtorrentResume).encode());
|
50
49
|
}
|
51
50
|
export default class RTorrent {
|
51
|
+
client;
|
52
52
|
constructor() {
|
53
53
|
const { rtorrentRpcUrl } = getRuntimeConfig();
|
54
54
|
const { href, username, password } = extractCredentialsFromUrl(rtorrentRpcUrl).unwrapOrThrow(new CrossSeedError("rTorrent url must be percent-encoded"));
|
@@ -85,9 +85,9 @@ export default class RTorrent {
|
|
85
85
|
}
|
86
86
|
async checkOriginalTorrent(searchee) {
|
87
87
|
const infoHash = searchee.infoHash.toUpperCase();
|
88
|
-
let
|
88
|
+
let response;
|
89
89
|
try {
|
90
|
-
|
90
|
+
response = await this.methodCallP("system.multicall", [
|
91
91
|
[
|
92
92
|
{
|
93
93
|
methodName: "d.directory",
|
@@ -97,27 +97,44 @@ export default class RTorrent {
|
|
97
97
|
methodName: "d.complete",
|
98
98
|
params: [infoHash],
|
99
99
|
},
|
100
|
+
{
|
101
|
+
methodName: "d.is_multi_file",
|
102
|
+
params: [infoHash],
|
103
|
+
},
|
100
104
|
],
|
101
105
|
]);
|
102
106
|
}
|
103
107
|
catch (e) {
|
104
108
|
logger.debug(e);
|
105
|
-
return resultOfErr(
|
109
|
+
return resultOfErr("FAILURE");
|
110
|
+
}
|
111
|
+
function isFault(response) {
|
112
|
+
return "faultString" in response[0];
|
106
113
|
}
|
107
|
-
// temp diag for #154
|
108
114
|
try {
|
109
|
-
|
115
|
+
if (isFault(response)) {
|
116
|
+
if (response[0].faultString === COULD_NOT_FIND_INFO_HASH) {
|
117
|
+
return resultOfErr("NOT_FOUND");
|
118
|
+
}
|
119
|
+
else {
|
120
|
+
throw new Error("Unknown rTorrent fault while checking original torrent");
|
121
|
+
}
|
122
|
+
}
|
123
|
+
const [[directoryBase], [isCompleteStr], [isMultiFileStr]] = response;
|
110
124
|
const isComplete = Boolean(Number(isCompleteStr));
|
111
125
|
if (!isComplete) {
|
112
|
-
return resultOfErr(
|
126
|
+
return resultOfErr("TORRENT_NOT_COMPLETE");
|
113
127
|
}
|
114
|
-
return resultOf({
|
128
|
+
return resultOf({
|
129
|
+
directoryBase,
|
130
|
+
isMultiFile: Boolean(Number(isMultiFileStr)),
|
131
|
+
});
|
115
132
|
}
|
116
133
|
catch (e) {
|
117
134
|
logger.error(e);
|
118
135
|
logger.debug("Failure caused by server response below:");
|
119
|
-
logger.debug(inspect(
|
120
|
-
return resultOfErr(
|
136
|
+
logger.debug(inspect(response));
|
137
|
+
return resultOfErr("FAILURE");
|
121
138
|
}
|
122
139
|
}
|
123
140
|
async getDownloadLocation(meta, searchee, path) {
|
@@ -152,24 +169,45 @@ export default class RTorrent {
|
|
152
169
|
throw new CrossSeedError(`Failed to reach rTorrent at ${rtorrentRpcUrl}`);
|
153
170
|
}
|
154
171
|
}
|
155
|
-
async
|
156
|
-
const
|
172
|
+
async getDownloadDir(searchee) {
|
173
|
+
const result = await this.checkOriginalTorrent(searchee);
|
174
|
+
return result
|
175
|
+
.mapOk(({ directoryBase, isMultiFile }) => {
|
176
|
+
return isMultiFile ? dirname(directoryBase) : directoryBase;
|
177
|
+
})
|
178
|
+
.mapErr((error) => (error === "FAILURE" ? "UNKNOWN_ERROR" : error));
|
179
|
+
}
|
180
|
+
async inject(meta, searchee, decision, path) {
|
181
|
+
const { outputDir, skipRecheck } = getRuntimeConfig();
|
157
182
|
if (await this.checkForInfoHashInClient(meta.infoHash)) {
|
158
183
|
return InjectionResult.ALREADY_EXISTS;
|
159
184
|
}
|
160
185
|
const result = await this.getDownloadLocation(meta, searchee, path);
|
161
|
-
if (result.isErr())
|
162
|
-
|
186
|
+
if (result.isErr()) {
|
187
|
+
switch (result.unwrapErrOrThrow()) {
|
188
|
+
case "NOT_FOUND":
|
189
|
+
return InjectionResult.FAILURE;
|
190
|
+
case "TORRENT_NOT_COMPLETE":
|
191
|
+
return InjectionResult.TORRENT_NOT_COMPLETE;
|
192
|
+
case "FAILURE":
|
193
|
+
return InjectionResult.FAILURE;
|
194
|
+
}
|
195
|
+
}
|
163
196
|
const { directoryBase, basePath } = result.unwrapOrThrow();
|
164
197
|
const torrentFilePath = resolve(outputDir, `${meta.name}.tmp.${Date.now()}.torrent`);
|
165
198
|
await saveWithLibTorrentResume(meta, torrentFilePath, basePath);
|
199
|
+
const loadType = decision === Decision.MATCH_PARTIAL
|
200
|
+
? skipRecheck
|
201
|
+
? "load.start"
|
202
|
+
: "load"
|
203
|
+
: "load.start";
|
166
204
|
for (let i = 0; i < 5; i++) {
|
167
205
|
try {
|
168
|
-
await this.methodCallP(
|
206
|
+
await this.methodCallP(loadType, [
|
169
207
|
"",
|
170
208
|
torrentFilePath,
|
171
209
|
`d.directory_base.set="${directoryBase}"`,
|
172
|
-
`d.custom1.set="
|
210
|
+
`d.custom1.set="${TORRENT_TAG}"`,
|
173
211
|
`d.custom.set=addtime,${Math.round(Date.now() / 1000)}`,
|
174
212
|
]);
|
175
213
|
break;
|
@@ -180,12 +218,12 @@ export default class RTorrent {
|
|
180
218
|
}
|
181
219
|
for (let i = 0; i < 5; i++) {
|
182
220
|
if (await this.checkForInfoHashInClient(meta.infoHash)) {
|
183
|
-
setTimeout(() =>
|
221
|
+
setTimeout(() => unlink(torrentFilePath), 1000);
|
184
222
|
return InjectionResult.SUCCESS;
|
185
223
|
}
|
186
224
|
await wait(100 * Math.pow(2, i));
|
187
225
|
}
|
188
|
-
setTimeout(() =>
|
226
|
+
setTimeout(() => unlink(torrentFilePath), 1000);
|
189
227
|
return InjectionResult.FAILURE;
|
190
228
|
}
|
191
229
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"RTorrent.js","sourceRoot":"","sources":["../../src/clients/RTorrent.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"RTorrent.js","sourceRoot":"","sources":["../../src/clients/RTorrent.ts"],"names":[],"mappings":"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"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"TorrentClient.js","sourceRoot":"","sources":["../../src/clients/TorrentClient.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,WAAW,MAAM,kBAAkB,CAAC;AAC3C,OAAO,QAAQ,MAAM,eAAe,CAAC;AACrC,OAAO,YAAY,MAAM,mBAAmB,CAAC;AAC7C,OAAO,MAAM,MAAM,aAAa,CAAC;
|
1
|
+
{"version":3,"file":"TorrentClient.js","sourceRoot":"","sources":["../../src/clients/TorrentClient.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,WAAW,MAAM,kBAAkB,CAAC;AAC3C,OAAO,QAAQ,MAAM,eAAe,CAAC;AACrC,OAAO,YAAY,MAAM,mBAAmB,CAAC;AAC7C,OAAO,MAAM,MAAM,aAAa,CAAC;AAGjC,IAAI,YAA2B,CAAC;AAoBhC,SAAS,yBAAyB;IACjC,MAAM,EAAE,cAAc,EAAE,cAAc,EAAE,kBAAkB,EAAE,YAAY,EAAE,GACzE,gBAAgB,EAAE,CAAC;IACpB,IAAI,cAAc,EAAE,CAAC;QACpB,YAAY,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC/B,CAAC;SAAM,IAAI,cAAc,EAAE,CAAC;QAC3B,YAAY,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,CAAC;SAAM,IAAI,kBAAkB,EAAE,CAAC;QAC/B,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC;IACnC,CAAC;SAAM,IAAI,YAAY,EAAE,CAAC;QACzB,YAAY,GAAG,IAAI,MAAM,EAAE,CAAC;IAC7B,CAAC;AACF,CAAC;AAED,MAAM,UAAU,SAAS;IACxB,IAAI,CAAC,YAAY,EAAE,CAAC;QACnB,yBAAyB,EAAE,CAAC;IAC7B,CAAC;IACD,OAAO,YAAY,CAAC;AACrB,CAAC"}
|
@@ -1,5 +1,4 @@
|
|
1
|
-
import
|
2
|
-
import { InjectionResult } from "../constants.js";
|
1
|
+
import { Decision, InjectionResult, TORRENT_TAG } from "../constants.js";
|
3
2
|
import { CrossSeedError } from "../errors.js";
|
4
3
|
import { Label, logger } from "../logger.js";
|
5
4
|
import { resultOf, resultOfErr } from "../Result.js";
|
@@ -10,6 +9,7 @@ function doesAlreadyExist(args) {
|
|
10
9
|
return "torrent-duplicate" in args;
|
11
10
|
}
|
12
11
|
export default class Transmission {
|
12
|
+
xTransmissionSessionId;
|
13
13
|
async request(method, args = {}, retries = 1) {
|
14
14
|
const { transmissionRpcUrl } = getRuntimeConfig();
|
15
15
|
const { username, password, href } = extractCredentialsFromUrl(transmissionRpcUrl).unwrapOrThrow(new CrossSeedError("Transmission rpc url must be percent-encoded"));
|
@@ -92,25 +92,35 @@ export default class Transmission {
|
|
92
92
|
}
|
93
93
|
return resultOf({ downloadDir });
|
94
94
|
}
|
95
|
-
async
|
95
|
+
async getDownloadDir(searchee) {
|
96
|
+
const result = await this.checkOriginalTorrent(searchee);
|
97
|
+
return result
|
98
|
+
.mapOk((r) => r.downloadDir)
|
99
|
+
.mapErr((err) => (err === "FAILURE" ? "UNKNOWN_ERROR" : err));
|
100
|
+
}
|
101
|
+
async inject(newTorrent, searchee, decision, path) {
|
102
|
+
const { skipRecheck } = getRuntimeConfig();
|
96
103
|
let downloadDir;
|
97
104
|
if (path) {
|
98
105
|
downloadDir = path;
|
99
106
|
}
|
100
107
|
else {
|
101
|
-
const result = await this.
|
108
|
+
const result = await this.getDownloadDir(searchee);
|
102
109
|
if (result.isErr()) {
|
103
|
-
return
|
110
|
+
return InjectionResult.FAILURE;
|
111
|
+
}
|
112
|
+
else {
|
113
|
+
downloadDir = result.unwrapOrThrow();
|
104
114
|
}
|
105
|
-
downloadDir = result.unwrapOrThrow().downloadDir;
|
106
115
|
}
|
107
116
|
let addResponse;
|
117
|
+
const skipRecheckTorrent = decision === Decision.MATCH_PARTIAL ? skipRecheck : true;
|
108
118
|
try {
|
109
119
|
addResponse = await this.request("torrent-add", {
|
110
120
|
"download-dir": downloadDir,
|
111
121
|
metainfo: newTorrent.encode().toString("base64"),
|
112
|
-
paused:
|
113
|
-
labels: [
|
122
|
+
paused: !skipRecheckTorrent,
|
123
|
+
labels: [TORRENT_TAG],
|
114
124
|
});
|
115
125
|
}
|
116
126
|
catch (e) {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"Transmission.js","sourceRoot":"","sources":["../../src/clients/Transmission.ts"],"names":[],"mappings":"AAAA,OAAO,
|
1
|
+
{"version":3,"file":"Transmission.js","sourceRoot":"","sources":["../../src/clients/Transmission.ts"],"names":[],"mappings":"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"}
|