cross-seed 7.0.0-1 → 7.0.0-2

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.
Files changed (229) hide show
  1. package/dist/Result.d.ts +27 -0
  2. package/dist/Result.js +64 -0
  3. package/dist/Result.js.map +1 -0
  4. package/dist/action.d.ts +34 -0
  5. package/dist/action.js +694 -0
  6. package/dist/action.js.map +1 -0
  7. package/dist/arr.d.ts +31 -0
  8. package/dist/arr.js +267 -0
  9. package/dist/arr.js.map +1 -0
  10. package/dist/auth.d.ts +3 -0
  11. package/dist/auth.js +28 -0
  12. package/dist/auth.js.map +1 -0
  13. package/dist/clients/Deluge.d.ts +153 -0
  14. package/dist/clients/Deluge.js +698 -0
  15. package/dist/clients/Deluge.js.map +1 -0
  16. package/dist/clients/QBittorrent.d.ts +218 -0
  17. package/dist/clients/QBittorrent.js +785 -0
  18. package/dist/clients/QBittorrent.js.map +1 -0
  19. package/dist/clients/RTorrent.d.ts +43 -0
  20. package/dist/clients/RTorrent.js +657 -0
  21. package/dist/clients/RTorrent.js.map +1 -0
  22. package/dist/clients/TorrentClient.d.ts +108 -0
  23. package/dist/clients/TorrentClient.js +341 -0
  24. package/dist/clients/TorrentClient.js.map +1 -0
  25. package/dist/clients/Transmission.d.ts +43 -0
  26. package/dist/clients/Transmission.js +404 -0
  27. package/dist/clients/Transmission.js.map +1 -0
  28. package/dist/cmd.d.ts +2 -0
  29. package/dist/cmd.js +128 -0
  30. package/dist/cmd.js.map +1 -0
  31. package/dist/configSchema.d.ts +1 -0
  32. package/dist/configSchema.js +2 -0
  33. package/dist/configSchema.js.map +1 -0
  34. package/dist/configuration.d.ts +63 -0
  35. package/dist/configuration.js +321 -0
  36. package/dist/configuration.js.map +1 -0
  37. package/dist/constants.d.ts +108 -0
  38. package/dist/constants.js +251 -0
  39. package/dist/constants.js.map +1 -0
  40. package/dist/dataFiles.d.ts +8 -0
  41. package/dist/dataFiles.js +223 -0
  42. package/dist/dataFiles.js.map +1 -0
  43. package/dist/db.d.ts +3 -0
  44. package/dist/db.js +216 -0
  45. package/dist/db.js.map +1 -0
  46. package/dist/dbConfig.d.ts +4 -0
  47. package/dist/dbConfig.js +67 -0
  48. package/dist/dbConfig.js.map +1 -0
  49. package/dist/decide.d.ts +25 -0
  50. package/dist/decide.js +553 -0
  51. package/dist/decide.js.map +1 -0
  52. package/dist/diff.d.ts +1 -0
  53. package/dist/diff.js +24 -0
  54. package/dist/diff.js.map +1 -0
  55. package/dist/errors.d.ts +3 -0
  56. package/dist/errors.js +7 -0
  57. package/dist/errors.js.map +1 -0
  58. package/dist/indexers.d.ts +105 -0
  59. package/dist/indexers.js +248 -0
  60. package/dist/indexers.js.map +1 -0
  61. package/dist/inject.d.ts +2 -0
  62. package/dist/inject.js +594 -0
  63. package/dist/inject.js.map +1 -0
  64. package/dist/jobs.d.ts +29 -0
  65. package/dist/jobs.js +151 -0
  66. package/dist/jobs.js.map +1 -0
  67. package/dist/logger.d.ts +29 -0
  68. package/dist/logger.js +157 -0
  69. package/dist/logger.js.map +1 -0
  70. package/dist/migrations/00-initialSchema.d.ts +9 -0
  71. package/dist/migrations/00-initialSchema.js +30 -0
  72. package/dist/migrations/00-initialSchema.js.map +1 -0
  73. package/dist/migrations/01-jobs.d.ts +9 -0
  74. package/dist/migrations/01-jobs.js +12 -0
  75. package/dist/migrations/01-jobs.js.map +1 -0
  76. package/dist/migrations/02-timestamps.d.ts +9 -0
  77. package/dist/migrations/02-timestamps.js +21 -0
  78. package/dist/migrations/02-timestamps.js.map +1 -0
  79. package/dist/migrations/03-rateLimits.d.ts +9 -0
  80. package/dist/migrations/03-rateLimits.js +14 -0
  81. package/dist/migrations/03-rateLimits.js.map +1 -0
  82. package/dist/migrations/04-auth.d.ts +9 -0
  83. package/dist/migrations/04-auth.js +13 -0
  84. package/dist/migrations/04-auth.js.map +1 -0
  85. package/dist/migrations/05-caps.d.ts +9 -0
  86. package/dist/migrations/05-caps.js +16 -0
  87. package/dist/migrations/05-caps.js.map +1 -0
  88. package/dist/migrations/06-uniqueDecisions.d.ts +9 -0
  89. package/dist/migrations/06-uniqueDecisions.js +29 -0
  90. package/dist/migrations/06-uniqueDecisions.js.map +1 -0
  91. package/dist/migrations/07-limits.d.ts +9 -0
  92. package/dist/migrations/07-limits.js +12 -0
  93. package/dist/migrations/07-limits.js.map +1 -0
  94. package/dist/migrations/08-rss.d.ts +9 -0
  95. package/dist/migrations/08-rss.js +15 -0
  96. package/dist/migrations/08-rss.js.map +1 -0
  97. package/dist/migrations/09-clientAndDataSearchees.d.ts +9 -0
  98. package/dist/migrations/09-clientAndDataSearchees.js +34 -0
  99. package/dist/migrations/09-clientAndDataSearchees.js.map +1 -0
  100. package/dist/migrations/10-indexerNameAudioBookCaps.d.ts +9 -0
  101. package/dist/migrations/10-indexerNameAudioBookCaps.js +18 -0
  102. package/dist/migrations/10-indexerNameAudioBookCaps.js.map +1 -0
  103. package/dist/migrations/11-trackers.d.ts +9 -0
  104. package/dist/migrations/11-trackers.js +38 -0
  105. package/dist/migrations/11-trackers.js.map +1 -0
  106. package/dist/migrations/12-user-auth.d.ts +9 -0
  107. package/dist/migrations/12-user-auth.js +22 -0
  108. package/dist/migrations/12-user-auth.js.map +1 -0
  109. package/dist/migrations/13-settings.d.ts +9 -0
  110. package/dist/migrations/13-settings.js +23 -0
  111. package/dist/migrations/13-settings.js.map +1 -0
  112. package/dist/migrations/14-indexer-enabled-flag.d.ts +9 -0
  113. package/dist/migrations/14-indexer-enabled-flag.js +12 -0
  114. package/dist/migrations/14-indexer-enabled-flag.js.map +1 -0
  115. package/dist/migrations/15-remove-url-unique-constraint.d.ts +9 -0
  116. package/dist/migrations/15-remove-url-unique-constraint.js +14 -0
  117. package/dist/migrations/15-remove-url-unique-constraint.js.map +1 -0
  118. package/dist/migrations/16-prune-inactive-indexers.d.ts +9 -0
  119. package/dist/migrations/16-prune-inactive-indexers.js +17 -0
  120. package/dist/migrations/16-prune-inactive-indexers.js.map +1 -0
  121. package/dist/migrations/migrations.d.ts +13 -0
  122. package/dist/migrations/migrations.js +41 -0
  123. package/dist/migrations/migrations.js.map +1 -0
  124. package/dist/parseTorrent.d.ts +53 -0
  125. package/dist/parseTorrent.js +128 -0
  126. package/dist/parseTorrent.js.map +1 -0
  127. package/dist/pipeline.d.ts +41 -0
  128. package/dist/pipeline.js +574 -0
  129. package/dist/pipeline.js.map +1 -0
  130. package/dist/preFilter.d.ts +25 -0
  131. package/dist/preFilter.js +250 -0
  132. package/dist/preFilter.js.map +1 -0
  133. package/dist/problems/linking.d.ts +2 -0
  134. package/dist/problems/linking.js +80 -0
  135. package/dist/problems/linking.js.map +1 -0
  136. package/dist/problems/path.d.ts +22 -0
  137. package/dist/problems/path.js +96 -0
  138. package/dist/problems/path.js.map +1 -0
  139. package/dist/problems.d.ts +13 -0
  140. package/dist/problems.js +48 -0
  141. package/dist/problems.js.map +1 -0
  142. package/dist/pushNotifier.d.ts +19 -0
  143. package/dist/pushNotifier.js +137 -0
  144. package/dist/pushNotifier.js.map +1 -0
  145. package/dist/routes/baseApi.d.ts +2 -0
  146. package/dist/routes/baseApi.js +354 -0
  147. package/dist/routes/baseApi.js.map +1 -0
  148. package/dist/routes/indexerApi.d.ts +6 -0
  149. package/dist/routes/indexerApi.js +165 -0
  150. package/dist/routes/indexerApi.js.map +1 -0
  151. package/dist/routes/staticFrontendPlugin.d.ts +4 -0
  152. package/dist/routes/staticFrontendPlugin.js +61 -0
  153. package/dist/routes/staticFrontendPlugin.js.map +1 -0
  154. package/dist/runtimeConfig.d.ts +6 -0
  155. package/dist/runtimeConfig.js +27 -0
  156. package/dist/runtimeConfig.js.map +1 -0
  157. package/dist/searchee.d.ts +108 -0
  158. package/dist/searchee.js +689 -0
  159. package/dist/searchee.js.map +1 -0
  160. package/dist/server.d.ts +4 -0
  161. package/dist/server.js +65 -0
  162. package/dist/server.js.map +1 -0
  163. package/dist/services/indexerService.d.ts +96 -0
  164. package/dist/services/indexerService.js +287 -0
  165. package/dist/services/indexerService.js.map +1 -0
  166. package/dist/sessionCookies.d.ts +5 -0
  167. package/dist/sessionCookies.js +27 -0
  168. package/dist/sessionCookies.js.map +1 -0
  169. package/dist/startup.d.ts +25 -0
  170. package/dist/startup.js +157 -0
  171. package/dist/startup.js.map +1 -0
  172. package/dist/torrent.d.ts +69 -0
  173. package/dist/torrent.js +641 -0
  174. package/dist/torrent.js.map +1 -0
  175. package/dist/torznab.d.ts +60 -0
  176. package/dist/torznab.js +711 -0
  177. package/dist/torznab.js.map +1 -0
  178. package/dist/trpc/fastifyAdapter.d.ts +2 -0
  179. package/dist/trpc/fastifyAdapter.js +9 -0
  180. package/dist/trpc/fastifyAdapter.js.map +1 -0
  181. package/dist/trpc/index.d.ts +49 -0
  182. package/dist/trpc/index.js +53 -0
  183. package/dist/trpc/index.js.map +1 -0
  184. package/dist/trpc/routers/auth.d.ts +43 -0
  185. package/dist/trpc/routers/auth.js +116 -0
  186. package/dist/trpc/routers/auth.js.map +1 -0
  187. package/dist/trpc/routers/clients.d.ts +21 -0
  188. package/dist/trpc/routers/clients.js +65 -0
  189. package/dist/trpc/routers/clients.js.map +1 -0
  190. package/dist/trpc/routers/health.d.ts +14 -0
  191. package/dist/trpc/routers/health.js +20 -0
  192. package/dist/trpc/routers/health.js.map +1 -0
  193. package/dist/trpc/routers/index.d.ts +391 -0
  194. package/dist/trpc/routers/index.js +23 -0
  195. package/dist/trpc/routers/index.js.map +1 -0
  196. package/dist/trpc/routers/indexers.d.ts +75 -0
  197. package/dist/trpc/routers/indexers.js +79 -0
  198. package/dist/trpc/routers/indexers.js.map +1 -0
  199. package/dist/trpc/routers/jobs.d.ts +33 -0
  200. package/dist/trpc/routers/jobs.js +84 -0
  201. package/dist/trpc/routers/jobs.js.map +1 -0
  202. package/dist/trpc/routers/logs.d.ts +27 -0
  203. package/dist/trpc/routers/logs.js +91 -0
  204. package/dist/trpc/routers/logs.js.map +1 -0
  205. package/dist/trpc/routers/searchees.d.ts +51 -0
  206. package/dist/trpc/routers/searchees.js +156 -0
  207. package/dist/trpc/routers/searchees.js.map +1 -0
  208. package/dist/trpc/routers/settings.d.ts +83 -0
  209. package/dist/trpc/routers/settings.js +92 -0
  210. package/dist/trpc/routers/settings.js.map +1 -0
  211. package/dist/trpc/routers/stats.d.ts +42 -0
  212. package/dist/trpc/routers/stats.js +102 -0
  213. package/dist/trpc/routers/stats.js.map +1 -0
  214. package/dist/userAuth.d.ts +21 -0
  215. package/dist/userAuth.js +86 -0
  216. package/dist/userAuth.js.map +1 -0
  217. package/dist/utils/authUtils.d.ts +10 -0
  218. package/dist/utils/authUtils.js +24 -0
  219. package/dist/utils/authUtils.js.map +1 -0
  220. package/dist/utils/logWatcher.d.ts +28 -0
  221. package/dist/utils/logWatcher.js +218 -0
  222. package/dist/utils/logWatcher.js.map +1 -0
  223. package/dist/utils/object.d.ts +1 -0
  224. package/dist/utils/object.js +4 -0
  225. package/dist/utils/object.js.map +1 -0
  226. package/dist/utils.d.ts +175 -0
  227. package/dist/utils.js +660 -0
  228. package/dist/utils.js.map +1 -0
  229. package/package.json +2 -2
@@ -0,0 +1,404 @@
1
+ import { readdir } from "fs/promises";
2
+ import ms from "ms";
3
+ import { basename } from "path";
4
+ import { inspect } from "util";
5
+ import { InjectionResult, TORRENT_TAG, USER_AGENT, } from "../constants.js";
6
+ import { db } from "../db.js";
7
+ import { CrossSeedError } from "../errors.js";
8
+ import { Label, logger } from "../logger.js";
9
+ import { resultOf, resultOfErr } from "../Result.js";
10
+ import { getRuntimeConfig } from "../runtimeConfig.js";
11
+ import { createSearcheeFromDB, parseTitle, updateSearcheeClientDB, } from "../searchee.js";
12
+ import { extractCredentialsFromUrl, humanReadableSize, sanitizeInfoHash, wait, } from "../utils.js";
13
+ import { shouldResumeFromNonRelevantFiles, clientSearcheeModified, getMaxRemainingBytes, getResumeStopTime, organizeTrackers, resumeErrSleepTime, resumeSleepTime, shouldRecheck, } from "./TorrentClient.js";
14
+ const XTransmissionSessionId = "X-Transmission-Session-Id";
15
+ function doesAlreadyExist(args) {
16
+ return "torrent-duplicate" in args;
17
+ }
18
+ export default class Transmission {
19
+ xTransmissionSessionId;
20
+ url;
21
+ clientHost;
22
+ clientPriority;
23
+ clientType = Label.TRANSMISSION;
24
+ readonly;
25
+ label;
26
+ constructor(url, clientHost, priority, readonly) {
27
+ this.url = url;
28
+ this.clientHost = clientHost;
29
+ this.clientPriority = priority;
30
+ this.readonly = readonly;
31
+ this.label = `${this.clientType}@${this.clientHost}`;
32
+ }
33
+ async request(method, args = {}, retries = 1, timeout = 0) {
34
+ const msg = `Calling method ${method} with params ${inspect(args, { depth: null, compact: true })}`;
35
+ const message = msg.length > 1000 ? `${msg.slice(0, 1000)}...` : msg;
36
+ logger.verbose({ label: this.label, message });
37
+ const { username, password, href } = extractCredentialsFromUrl(this.url).unwrapOrThrow(new CrossSeedError(`[${this.label}] Transmission rpc url must be percent-encoded`));
38
+ const headers = new Headers({ "User-Agent": USER_AGENT });
39
+ headers.set("Content-Type", "application/json");
40
+ if (this.xTransmissionSessionId) {
41
+ headers.set(XTransmissionSessionId, this.xTransmissionSessionId);
42
+ }
43
+ if (username && password) {
44
+ const credentials = Buffer.from(`${username}:${password}`).toString("base64");
45
+ headers.set("Authorization", `Basic ${credentials}`);
46
+ }
47
+ const response = await fetch(href, {
48
+ method: "POST",
49
+ body: JSON.stringify({ method, arguments: args }),
50
+ headers,
51
+ signal: AbortSignal.timeout(timeout || ms("5 minutes")),
52
+ });
53
+ if (response.status === 409) {
54
+ this.xTransmissionSessionId = response.headers.get(XTransmissionSessionId);
55
+ return this.request(method, args, retries - 1);
56
+ }
57
+ try {
58
+ const responseBody = (await response.clone().json());
59
+ if (responseBody.result === "success" ||
60
+ responseBody.result === "duplicate torrent" // slight hack but best solution for now
61
+ ) {
62
+ return responseBody.arguments;
63
+ }
64
+ else {
65
+ throw new Error(`Transmission responded with error: "${responseBody.result}"`);
66
+ }
67
+ }
68
+ catch (e) {
69
+ if (e instanceof SyntaxError) {
70
+ logger.error({
71
+ label: this.label,
72
+ message: `Transmission returned non-JSON response`,
73
+ });
74
+ logger.debug({
75
+ label: this.label,
76
+ message: response.clone().text(),
77
+ });
78
+ }
79
+ else {
80
+ logger.error({
81
+ label: this.label,
82
+ message: `Transmission responded with an error: ${e.message}`,
83
+ });
84
+ logger.debug(e);
85
+ }
86
+ throw e;
87
+ }
88
+ }
89
+ async validateConfig() {
90
+ const { torrentDir } = getRuntimeConfig();
91
+ try {
92
+ await this.request("session-get", {}, 1, ms("10 seconds"));
93
+ }
94
+ catch (e) {
95
+ throw new CrossSeedError(`[${this.label}] Failed to reach Transmission at ${this.clientHost}: ${e.message}`);
96
+ }
97
+ logger.info({
98
+ label: this.label,
99
+ message: `Logged in successfully${this.readonly ? " (readonly)" : ""}`,
100
+ });
101
+ if (!torrentDir)
102
+ return;
103
+ if (!(await readdir(torrentDir)).some((f) => f.endsWith(".torrent"))) {
104
+ throw new CrossSeedError(`[${this.label}] Invalid torrentDir, if no torrents are in client set to null for now: https://www.cross-seed.org/docs/basics/options#torrentdir`);
105
+ }
106
+ }
107
+ async checkOriginalTorrent(data, onlyCompleted) {
108
+ let queryResponse;
109
+ try {
110
+ queryResponse = await this.request("torrent-get", {
111
+ fields: ["downloadDir", "percentDone"],
112
+ ids: [data.infoHash],
113
+ });
114
+ }
115
+ catch {
116
+ return resultOfErr(InjectionResult.FAILURE);
117
+ }
118
+ if (queryResponse.torrents.length === 0) {
119
+ return resultOfErr(InjectionResult.FAILURE);
120
+ }
121
+ const [{ downloadDir, percentDone }] = queryResponse.torrents;
122
+ if (onlyCompleted && percentDone < 1) {
123
+ return resultOfErr(InjectionResult.TORRENT_NOT_COMPLETE);
124
+ }
125
+ return resultOf({ downloadDir });
126
+ }
127
+ async getDownloadDir(meta, options) {
128
+ const result = await this.checkOriginalTorrent(meta, options.onlyCompleted);
129
+ return result
130
+ .mapOk((r) => r.downloadDir)
131
+ .mapErr((err) => (err === "FAILURE" ? "UNKNOWN_ERROR" : err));
132
+ }
133
+ async getAllDownloadDirs(options) {
134
+ let torrents = (await this.request("torrent-get", {
135
+ fields: ["hashString", "downloadDir", "percentDone"],
136
+ })).torrents;
137
+ if (options.onlyCompleted) {
138
+ torrents = torrents.filter((torrent) => torrent.percentDone === 1);
139
+ }
140
+ return torrents.reduce((acc, { hashString, downloadDir }) => {
141
+ acc.set(hashString, downloadDir);
142
+ return acc;
143
+ }, new Map());
144
+ }
145
+ async isTorrentInClient(inputHash) {
146
+ const infoHash = inputHash.toLowerCase();
147
+ try {
148
+ const torrents = (await this.request("torrent-get", {
149
+ fields: ["hashString"],
150
+ })).torrents;
151
+ if (!torrents.length)
152
+ throw new Error("No torrents found");
153
+ for (const torrent of torrents) {
154
+ if (torrent.hashString.toLowerCase() === infoHash) {
155
+ return resultOf(true);
156
+ }
157
+ }
158
+ return resultOf(false);
159
+ }
160
+ catch (e) {
161
+ return resultOfErr(e);
162
+ }
163
+ }
164
+ async isTorrentComplete(infoHash) {
165
+ const queryResponse = await this.request("torrent-get", {
166
+ fields: ["percentDone"],
167
+ ids: [infoHash],
168
+ });
169
+ if (queryResponse.torrents.length === 0) {
170
+ return resultOfErr("NOT_FOUND");
171
+ }
172
+ const [{ percentDone }] = queryResponse.torrents;
173
+ return resultOf(percentDone === 1);
174
+ }
175
+ async isTorrentChecking(infoHash) {
176
+ const queryResponse = await this.request("torrent-get", {
177
+ fields: ["status"],
178
+ ids: [infoHash],
179
+ });
180
+ if (queryResponse.torrents.length === 0) {
181
+ return resultOfErr("NOT_FOUND");
182
+ }
183
+ const [{ status }] = queryResponse.torrents;
184
+ return resultOf([1, 2].includes(status));
185
+ }
186
+ async getAllTorrents() {
187
+ const res = await this.request("torrent-get", {
188
+ fields: ["hashString", "labels"],
189
+ });
190
+ return res.torrents.map((torrent) => ({
191
+ infoHash: torrent.hashString,
192
+ tags: torrent.labels,
193
+ }));
194
+ }
195
+ async getClientSearchees(options) {
196
+ const searchees = [];
197
+ const newSearchees = [];
198
+ const infoHashes = new Set();
199
+ let torrents;
200
+ try {
201
+ torrents = (await this.request("torrent-get", {
202
+ fields: [
203
+ "hashString",
204
+ "name",
205
+ "files",
206
+ "totalSize",
207
+ "downloadDir",
208
+ "labels",
209
+ "trackers",
210
+ ],
211
+ })).torrents;
212
+ }
213
+ catch (e) {
214
+ logger.error({
215
+ label: this.label,
216
+ message: `Failed to get torrents from client: ${e.message}`,
217
+ });
218
+ logger.debug(e);
219
+ return { searchees, newSearchees };
220
+ }
221
+ if (!torrents.length) {
222
+ logger.error({
223
+ label: this.label,
224
+ message: "No torrents found in client",
225
+ });
226
+ return { searchees, newSearchees };
227
+ }
228
+ for (const torrent of torrents) {
229
+ const infoHash = torrent.hashString.toLowerCase();
230
+ infoHashes.add(infoHash);
231
+ const dbTorrent = await db("client_searchee")
232
+ .where("info_hash", infoHash)
233
+ .where("client_host", this.clientHost)
234
+ .first();
235
+ const { name } = torrent;
236
+ const savePath = torrent.downloadDir;
237
+ const tags = torrent.labels;
238
+ const modified = clientSearcheeModified(this.label, dbTorrent, name, savePath, {
239
+ tags,
240
+ });
241
+ const refresh = options?.refresh === undefined
242
+ ? false
243
+ : options.refresh.length === 0
244
+ ? true
245
+ : options.refresh.includes(infoHash);
246
+ if (!modified && !refresh) {
247
+ if (!options?.newSearcheesOnly) {
248
+ searchees.push(createSearcheeFromDB(dbTorrent));
249
+ }
250
+ continue;
251
+ }
252
+ const files = torrent.files.map((file) => ({
253
+ name: basename(file.name),
254
+ path: file.name,
255
+ length: file.length,
256
+ }));
257
+ if (!files.length) {
258
+ logger.verbose({
259
+ label: this.label,
260
+ message: `No files found for ${torrent.name} [${sanitizeInfoHash(infoHash)}]: skipping`,
261
+ });
262
+ continue;
263
+ }
264
+ const trackers = organizeTrackers(torrent.trackers.map((tracker) => ({
265
+ url: tracker.announce,
266
+ tier: tracker.tier,
267
+ })));
268
+ const title = parseTitle(name, files) ?? name;
269
+ const length = torrent.totalSize;
270
+ const searchee = {
271
+ infoHash,
272
+ name,
273
+ title,
274
+ files,
275
+ length,
276
+ clientHost: this.clientHost,
277
+ savePath,
278
+ tags,
279
+ trackers,
280
+ };
281
+ newSearchees.push(searchee);
282
+ searchees.push(searchee);
283
+ }
284
+ await updateSearcheeClientDB(this.clientHost, newSearchees, infoHashes);
285
+ return { searchees, newSearchees };
286
+ }
287
+ async recheckTorrent(infoHash) {
288
+ // Pause first as it may resume after recheck automatically
289
+ await this.request("torrent-stop", {
290
+ ids: [infoHash],
291
+ });
292
+ await this.request("torrent-verify", {
293
+ ids: [infoHash],
294
+ });
295
+ }
296
+ async resumeInjection(meta, decision, options) {
297
+ const infoHash = meta.infoHash;
298
+ let sleepTime = resumeSleepTime;
299
+ const stopTime = getResumeStopTime();
300
+ let stop = false;
301
+ while (Date.now() < stopTime) {
302
+ if (options.checkOnce) {
303
+ if (stop)
304
+ return;
305
+ stop = true;
306
+ }
307
+ await wait(sleepTime);
308
+ const queryResponse = await this.request("torrent-get", {
309
+ fields: ["leftUntilDone", "name", "status"],
310
+ ids: [infoHash],
311
+ });
312
+ if (queryResponse.torrents.length === 0) {
313
+ sleepTime = resumeErrSleepTime; // Dropping connections or restart
314
+ continue;
315
+ }
316
+ const [{ leftUntilDone, name, status }] = queryResponse.torrents;
317
+ if ([1, 2].includes(status)) {
318
+ continue;
319
+ }
320
+ const torrentLog = `${name} [${sanitizeInfoHash(infoHash)}]`;
321
+ if (status !== 0) {
322
+ logger.warn({
323
+ label: this.label,
324
+ message: `Will not resume ${torrentLog}: status is ${status}`,
325
+ });
326
+ return;
327
+ }
328
+ const maxRemainingBytes = getMaxRemainingBytes(meta, decision, {
329
+ torrentLog,
330
+ label: this.label,
331
+ });
332
+ if (leftUntilDone > maxRemainingBytes) {
333
+ if (!shouldResumeFromNonRelevantFiles(meta, leftUntilDone, decision, {
334
+ torrentLog,
335
+ label: this.label,
336
+ })) {
337
+ logger.warn({
338
+ label: this.label,
339
+ message: `autoResumeMaxDownload will not resume ${torrentLog}: remainingSize ${humanReadableSize(leftUntilDone, { binary: true })} > ${humanReadableSize(maxRemainingBytes, { binary: true })} limit`,
340
+ });
341
+ return;
342
+ }
343
+ }
344
+ logger.info({
345
+ label: this.label,
346
+ message: `Resuming ${torrentLog}: ${humanReadableSize(leftUntilDone, { binary: true })} remaining`,
347
+ });
348
+ await this.request("torrent-start", {
349
+ ids: [infoHash],
350
+ });
351
+ return;
352
+ }
353
+ logger.warn({
354
+ label: this.label,
355
+ message: `Will not resume torrent ${infoHash}: timeout`,
356
+ });
357
+ }
358
+ async inject(newTorrent, searchee, decision, options) {
359
+ const existsRes = await this.isTorrentInClient(newTorrent.infoHash);
360
+ if (existsRes.isErr())
361
+ return InjectionResult.FAILURE;
362
+ if (existsRes.unwrap())
363
+ return InjectionResult.ALREADY_EXISTS;
364
+ let destinationDir;
365
+ if (options.destinationDir) {
366
+ destinationDir = options.destinationDir;
367
+ }
368
+ else {
369
+ const result = await this.getDownloadDir(searchee, { onlyCompleted: options.onlyCompleted });
370
+ if (result.isOk()) {
371
+ destinationDir = result.unwrap();
372
+ }
373
+ else {
374
+ if (result.unwrapErr() === "TORRENT_NOT_COMPLETE") {
375
+ return InjectionResult.TORRENT_NOT_COMPLETE;
376
+ }
377
+ return InjectionResult.FAILURE;
378
+ }
379
+ }
380
+ let addResponse;
381
+ try {
382
+ const toRecheck = shouldRecheck(newTorrent, decision);
383
+ addResponse = await this.request("torrent-add", {
384
+ "download-dir": destinationDir,
385
+ metainfo: newTorrent.encode().toString("base64"),
386
+ paused: toRecheck,
387
+ labels: [TORRENT_TAG],
388
+ });
389
+ if (toRecheck) {
390
+ void this.resumeInjection(newTorrent, decision, {
391
+ checkOnce: false,
392
+ });
393
+ }
394
+ }
395
+ catch {
396
+ return InjectionResult.FAILURE;
397
+ }
398
+ if (doesAlreadyExist(addResponse)) {
399
+ return InjectionResult.ALREADY_EXISTS;
400
+ }
401
+ return InjectionResult.SUCCESS;
402
+ }
403
+ }
404
+ //# sourceMappingURL=Transmission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Transmission.js","sourceRoot":"","sources":["../../src/clients/Transmission.ts"],"names":[],"mappings":"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"}
package/dist/cmd.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cmd.js ADDED
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env node
2
+ import chalk from "chalk";
3
+ import { Option, program } from "commander";
4
+ import { getApiKey, resetApiKey } from "./auth.js";
5
+ import { PROGRAM_NAME, PROGRAM_VERSION } from "./constants.js";
6
+ import { db } from "./db.js";
7
+ import { updateTorrentCache } from "./decide.js";
8
+ import { diffCmd } from "./diff.js";
9
+ import { clearIndexerFailures } from "./indexers.js";
10
+ import { injectSavedTorrents, restoreFromTorrentCache } from "./inject.js";
11
+ import { jobsLoop } from "./jobs.js";
12
+ import { bulkSearch, scanRssFeeds } from "./pipeline.js";
13
+ import { sendTestNotification } from "./pushNotifier.js";
14
+ import { serve } from "./server.js";
15
+ import { withFullRuntime, withMinimalRuntime } from "./startup.js";
16
+ import { indexTorrentsAndDataDirs, parseTorrentFromPath } from "./torrent.js";
17
+ import { resetUsers } from "./userAuth.js";
18
+ const verboseOption = new Option("-v, --verbose", "Log verbose output").default(false);
19
+ program.name(PROGRAM_NAME);
20
+ program.description(chalk.yellow.bold(`${PROGRAM_NAME} v${PROGRAM_VERSION}`));
21
+ program.version(PROGRAM_VERSION, "-V, --version", "output the current version");
22
+ program
23
+ .command("update-torrent-cache-trackers")
24
+ .description("Update announce urls in the torrent cache")
25
+ .usage("<old-announce-url> <new-announce-url>")
26
+ .argument("old-announce-url", 'A substring of the announce url to replace, e.g. update-torrent-cache-trackers "old.example.com" "new.example.com"')
27
+ .argument("new-announce-url", 'A substring of the new announce url to replace the old one with, e.g. update-torrent-cache-trackers "myoldpasskey" "mynewpasskey"')
28
+ .action(withMinimalRuntime(updateTorrentCache));
29
+ program
30
+ .command("diff")
31
+ .description("Analyze two torrent files for cross-seed compatibility")
32
+ .argument("searchee")
33
+ .argument("candidate")
34
+ .action(withMinimalRuntime(diffCmd, { migrate: false }));
35
+ program
36
+ .command("tree")
37
+ .description("Print a torrent's file tree")
38
+ .argument("torrent")
39
+ .action(withMinimalRuntime(async (torrentPath) => {
40
+ console.log("Use `cross-seed diff` to compare two .torrent files");
41
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
42
+ const { category, isSingleFileTorrent, raw, tags, ...meta } = await parseTorrentFromPath(torrentPath);
43
+ console.log(meta);
44
+ }, { migrate: false }));
45
+ program
46
+ .command("clear-indexer-failures")
47
+ .description("Clear the cached details of indexers (failures and caps)")
48
+ .action(withMinimalRuntime(clearIndexerFailures));
49
+ program
50
+ .command("clear-cache")
51
+ .description("Clear the cache without causing torrents to be re-snatched and reset the timestamps for excludeOlder and excludeRecentSearch")
52
+ .action(withMinimalRuntime(async () => {
53
+ console.log("Clearing cache...");
54
+ await db("decision").whereNull("info_hash").del();
55
+ await db("timestamp").del();
56
+ }));
57
+ program
58
+ .command("clear-client-cache")
59
+ .description("Clear cross-seed's cache of your client's torrents. Only necessary if you have recently changed clients or modified the torrents in client and don't want to wait on the cleanup job.")
60
+ .action(withMinimalRuntime(async () => {
61
+ console.log("Clearing client cache...");
62
+ await db("torrent").del();
63
+ await db("client_searchee").del();
64
+ await db("data").del();
65
+ await db("ensemble").del();
66
+ }));
67
+ program
68
+ .command("api-key")
69
+ .description("Show the api key")
70
+ .addOption(new Option("--api-key <key>", "Provide your own API key to override the autogenerated one."))
71
+ .action(withMinimalRuntime(getApiKey));
72
+ program
73
+ .command("reset-api-key")
74
+ .description("Reset the api key")
75
+ .action(withMinimalRuntime(resetApiKey));
76
+ program
77
+ .command("reset-user")
78
+ .description("Delete all users and sessions")
79
+ .action(withMinimalRuntime(resetUsers));
80
+ program
81
+ .command("daemon")
82
+ .description("Start the cross-seed daemon")
83
+ .option("-p, --port <port>", "Listen on a custom port", (n) => parseInt(n))
84
+ .option("--host <host>", "Bind to a specific IP address")
85
+ .option("--base-path <path>", "Serve cross-seed behind this base path", "")
86
+ .option("--no-port", "Do not listen on any port")
87
+ .addOption(verboseOption)
88
+ .action(withFullRuntime(async (options) => {
89
+ const serverPromise = serve(options.port, options.host, options.basePath);
90
+ await indexTorrentsAndDataDirs({ startup: true });
91
+ // technically this will never resolve, but it's necessary to keep the process running
92
+ await Promise.all([serverPromise, jobsLoop()]);
93
+ }));
94
+ program
95
+ .command("rss")
96
+ .description("Run an rss scan")
97
+ .addOption(verboseOption)
98
+ .action(withFullRuntime(async () => {
99
+ await indexTorrentsAndDataDirs({ startup: true });
100
+ await scanRssFeeds();
101
+ }));
102
+ program
103
+ .command("search")
104
+ .description("Search for cross-seeds")
105
+ .addOption(new Option("--torrents <torrents...>", "torrent files separated by spaces").hideHelp())
106
+ .addOption(verboseOption)
107
+ .action(withFullRuntime(() => bulkSearch()));
108
+ program
109
+ .command("inject")
110
+ .description("Inject saved cross-seeds into your client (without filtering, see docs)")
111
+ .option("--inject-dir <dir>", "Directory of torrent files to try to inject")
112
+ .option("--ignore-titles", "Searchee and candidate titles do not need to pass the fuzzy matching check (useful if `cross-seed inject` erroneously rejects by title)")
113
+ .option("--no-ignore-titles", "Searchee and candidate titles need to pass the fuzzy matching check (default)")
114
+ .addOption(verboseOption)
115
+ .action(withFullRuntime(injectSavedTorrents));
116
+ program
117
+ .command("restore")
118
+ .description("Use snatched torrents from torrent_cache to attempt to restore cross seeds. Will need to run `cross-seed inject` afterwards with dataDirs configured.")
119
+ .addOption(verboseOption)
120
+ .action(withFullRuntime(restoreFromTorrentCache));
121
+ program
122
+ .command("test-notification")
123
+ .description("Send a test notification")
124
+ .addOption(verboseOption)
125
+ .action(withFullRuntime(sendTestNotification));
126
+ program.showHelpAfterError("(add --help for additional information)");
127
+ await program.parseAsync();
128
+ //# sourceMappingURL=cmd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cmd.js","sourceRoot":"","sources":["../src/cmd.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export { RUNTIME_CONFIG_SCHEMA, RUNTIME_CONFIG_OVERRIDES_SCHEMA, parseRuntimeConfig, parseRuntimeConfigOverrides, } from "@cross-seed/shared/configSchema";
@@ -0,0 +1,2 @@
1
+ export { RUNTIME_CONFIG_SCHEMA, RUNTIME_CONFIG_OVERRIDES_SCHEMA, parseRuntimeConfig, parseRuntimeConfigOverrides, } from "@cross-seed/shared/configSchema";
2
+ //# sourceMappingURL=configSchema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configSchema.js","sourceRoot":"","sources":["../src/configSchema.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,qBAAqB,EACrB,+BAA+B,EAC/B,kBAAkB,EAClB,2BAA2B,GAC3B,MAAM,iCAAiC,CAAC"}
@@ -0,0 +1,63 @@
1
+ import { Action, MatchMode } from "./constants.js";
2
+ import { RuntimeConfig } from "./runtimeConfig.js";
3
+ export interface FileConfig {
4
+ action?: Action;
5
+ pconfigVersion?: number;
6
+ delay?: number;
7
+ includeSingleEpisodes?: boolean;
8
+ outputDir?: string;
9
+ injectDir?: string;
10
+ ignoreTitles?: boolean;
11
+ includeNonVideos?: boolean;
12
+ seasonFromEpisodes?: number;
13
+ fuzzySizeThreshold?: number;
14
+ excludeOlder?: string;
15
+ excludeRecentSearch?: string;
16
+ useClientTorrents?: boolean;
17
+ dataDirs?: string[];
18
+ matchMode?: MatchMode;
19
+ skipRecheck?: boolean;
20
+ autoResumeMaxDownload?: number;
21
+ ignoreNonRelevantFilesToResume?: boolean;
22
+ linkDir?: string;
23
+ linkDirs?: string[];
24
+ linkType?: string;
25
+ flatLinking?: boolean;
26
+ maxDataDepth?: number;
27
+ linkCategory?: string;
28
+ torrentDir?: string;
29
+ torznab?: string[];
30
+ torrentClients?: string[];
31
+ qbittorrentUrl?: string;
32
+ rtorrentRpcUrl?: string;
33
+ transmissionRpcUrl?: string;
34
+ delugeRpcUrl?: string;
35
+ duplicateCategories?: boolean;
36
+ notificationWebhookUrls?: string[];
37
+ notificationWebhookUrl?: string;
38
+ port?: number;
39
+ host?: string;
40
+ searchCadence?: string;
41
+ rssCadence?: string;
42
+ snatchTimeout?: string;
43
+ searchTimeout?: string;
44
+ searchLimit?: number;
45
+ blockList?: string[];
46
+ apiKey?: string;
47
+ sonarr?: string[];
48
+ radarr?: string[];
49
+ }
50
+ export declare const UNPARSABLE_CONFIG_MESSAGE: string;
51
+ /**
52
+ * Returns the appDir relevant to the OS/Environment. Due to initialization of
53
+ * the SQLiteDB during read of db.ts - will need to create appDir in this function if
54
+ * it does not exist (ENOENT)
55
+ *
56
+ * @return a string representing the absolute path to cross-seed config directory
57
+ */
58
+ export declare function appDir(): string;
59
+ export declare function createAppDirHierarchy(): void;
60
+ export declare function getDefaultRuntimeConfig(): RuntimeConfig;
61
+ export declare function stripDefaults(config: Partial<RuntimeConfig> | RuntimeConfig): Partial<RuntimeConfig>;
62
+ export declare function transformFileConfig(fileConfig: FileConfig): Partial<RuntimeConfig>;
63
+ export declare function getFileConfig(): Promise<FileConfig | undefined>;