cross-seed 6.0.0-9 → 6.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.
Files changed (70) hide show
  1. package/dist/action.js +177 -68
  2. package/dist/action.js.map +1 -1
  3. package/dist/arr.js +62 -54
  4. package/dist/arr.js.map +1 -1
  5. package/dist/clients/Deluge.js +70 -46
  6. package/dist/clients/Deluge.js.map +1 -1
  7. package/dist/clients/QBittorrent.js +110 -68
  8. package/dist/clients/QBittorrent.js.map +1 -1
  9. package/dist/clients/RTorrent.js +45 -22
  10. package/dist/clients/RTorrent.js.map +1 -1
  11. package/dist/clients/TorrentClient.js +14 -1
  12. package/dist/clients/TorrentClient.js.map +1 -1
  13. package/dist/clients/Transmission.js +29 -9
  14. package/dist/clients/Transmission.js.map +1 -1
  15. package/dist/cmd.js +46 -23
  16. package/dist/cmd.js.map +1 -1
  17. package/dist/config.template.cjs +53 -57
  18. package/dist/config.template.cjs.map +1 -1
  19. package/dist/configSchema.js +89 -25
  20. package/dist/configSchema.js.map +1 -1
  21. package/dist/configuration.js +4 -1
  22. package/dist/configuration.js.map +1 -1
  23. package/dist/constants.js +69 -10
  24. package/dist/constants.js.map +1 -1
  25. package/dist/dataFiles.js +4 -5
  26. package/dist/dataFiles.js.map +1 -1
  27. package/dist/db.js +2 -1
  28. package/dist/db.js.map +1 -1
  29. package/dist/decide.js +231 -146
  30. package/dist/decide.js.map +1 -1
  31. package/dist/diff.js +13 -3
  32. package/dist/diff.js.map +1 -1
  33. package/dist/errors.js.map +1 -1
  34. package/dist/indexers.js +94 -33
  35. package/dist/indexers.js.map +1 -1
  36. package/dist/inject.js +448 -0
  37. package/dist/inject.js.map +1 -0
  38. package/dist/jobs.js +13 -6
  39. package/dist/jobs.js.map +1 -1
  40. package/dist/logger.js +27 -9
  41. package/dist/logger.js.map +1 -1
  42. package/dist/migrations/00-initialSchema.js.map +1 -1
  43. package/dist/migrations/05-caps.js.map +1 -1
  44. package/dist/migrations/06-uniqueDecisions.js +29 -0
  45. package/dist/migrations/06-uniqueDecisions.js.map +1 -0
  46. package/dist/migrations/07-limits.js +12 -0
  47. package/dist/migrations/07-limits.js.map +1 -0
  48. package/dist/migrations/migrations.js +4 -0
  49. package/dist/migrations/migrations.js.map +1 -1
  50. package/dist/parseTorrent.js +6 -0
  51. package/dist/parseTorrent.js.map +1 -1
  52. package/dist/pipeline.js +224 -108
  53. package/dist/pipeline.js.map +1 -1
  54. package/dist/preFilter.js +122 -55
  55. package/dist/preFilter.js.map +1 -1
  56. package/dist/pushNotifier.js +7 -5
  57. package/dist/pushNotifier.js.map +1 -1
  58. package/dist/searchee.js +198 -17
  59. package/dist/searchee.js.map +1 -1
  60. package/dist/server.js +106 -54
  61. package/dist/server.js.map +1 -1
  62. package/dist/startup.js +16 -7
  63. package/dist/startup.js.map +1 -1
  64. package/dist/torrent.js +100 -37
  65. package/dist/torrent.js.map +1 -1
  66. package/dist/torznab.js +323 -153
  67. package/dist/torznab.js.map +1 -1
  68. package/dist/utils.js +228 -43
  69. package/dist/utils.js.map +1 -1
  70. package/package.json +11 -6
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  // If you find yourself always using the same command-line flag, you can set it
3
3
  // here as a default.
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
4
  module.exports = {
6
5
  /**
7
6
  * WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
@@ -31,30 +30,30 @@ module.exports = {
31
30
  * URL(s) to your Sonarr instance(s), included in the same way as torznab
32
31
  * URLs but for your Sonarr: note that api is not at the end. see below.
33
32
  *
34
- * You should order these in most likely to match -> least likely order.
33
+ * You should order these in most likely to match -> the least likely order.
35
34
  * They are searched sequentially as they are listed.
36
35
  *
37
36
  * This apikey parameter comes from Sonarr
38
37
  *
39
38
  * Example: sonarr: ["http://sonarr:8989/?apikey=12345"],
40
39
  *
41
- * sonarr: ["http://sonarr:8989/?apikey=12345",
42
- * "http://sonarr4k:8989/?apikey=12345"],
40
+ * sonarr: ["http://sonarr:8989/?apikey=12345",
41
+ * "http://sonarr4k:8989/?apikey=12345"],
43
42
  */
44
43
  sonarr: undefined,
45
44
  /**
46
45
  * URL(s) to your Radarr instance(s), included in the same way as torznab
47
- * URLs but for your Sonarr: note that api is not at the end. see below.
46
+ * URLs but for your Radarr: note that api is not at the end. see below.
48
47
  *
49
- * You should order these in most likely to match -> least likely order.
48
+ * You should order these in most likely to match -> the least likely order.
50
49
  * They are searched sequentially as they are listed.
51
50
  *
52
- * This apikey parameter comes from Sonarr
51
+ * This apikey parameter comes from Radarr
53
52
  *
54
53
  * Example: radarr: ["http://radarr:7878/?apikey=12345"],
55
54
  *
56
- * radarr: ["http://radarr:7878/?apikey=12345",
57
- * "http://radarr4k:7878/?apikey=12345"],
55
+ * radarr: ["http://radarr:7878/?apikey=12345",
56
+ * "http://radarr4k:7878/?apikey=12345"],
58
57
  */
59
58
  radarr: undefined,
60
59
  /**
@@ -111,33 +110,33 @@ module.exports = {
111
110
  /**
112
111
  * Pause at least this many seconds in between each search. Higher is safer
113
112
  * for you and friendlier for trackers.
114
- * Minimum value of 10.
113
+ * Minimum value of 30.
115
114
  */
116
115
  delay: 30,
117
116
  /**
118
- * To search with already downloaded data, you can enter in the directories
117
+ * To search with already downloaded data, you can enter the directories
119
118
  * to your downloaded torrent data to find matches, rather than relying
120
119
  * entirely on the .torrent files themselves for matching.
121
120
  *
122
- * If directories are entered, they must all be on the one line and they
121
+ * If directories are entered, they must all be in a single option, and they
123
122
  * need to be surrounded by brackets.
123
+ *
124
124
  * Windows users will need to use double backslash in all paths in this
125
125
  * config.
126
126
  *
127
127
  * example:
128
128
  * dataDirs: ["/downloads/movies", "/downloads/packs"],
129
- * or for windows users
129
+ * or for Windows users
130
130
  * dataDirs: ["C:\\My Data\\Downloads\\Movies"],
131
131
  */
132
132
  dataDirs: [],
133
133
  /**
134
134
  * Defines what qBittorrent or Deluge category to set on linked torrents
135
- * Default is "cross-seed-link".
136
135
  *
137
136
  * qBittorrent: If you have linking enabled, all torrents will be injected
138
137
  * to this category.
139
138
  *
140
- * Default is "cross-seed-data".
139
+ * Default is "cross-seed-link".
141
140
  */
142
141
  linkCategory: "cross-seed-link",
143
142
  /**
@@ -168,7 +167,7 @@ module.exports = {
168
167
  /**
169
168
  * Enabling this will link files using v5's flat folder style.
170
169
  *
171
- * Each individual Torznab tracker's cross-seeds, otherwise, will have it's
170
+ * Each individual Torznab tracker's cross-seeds, otherwise, will have its
172
171
  * own folder with the tracker's name and it's links within it.
173
172
  *
174
173
  * If using Automatic Torrent Management in qBittorrent, please read:
@@ -195,7 +194,7 @@ module.exports = {
195
194
  * searchees. Setting this to higher values will result in more searchees
196
195
  * and more API hits to your indexers.
197
196
  */
198
- maxDataDepth: 1,
197
+ maxDataDepth: 2,
199
198
  /**
200
199
  * Directory containing .torrent files.
201
200
  * For qBittorrent, this is BT_Backup.
@@ -214,47 +213,39 @@ module.exports = {
214
213
  */
215
214
  outputDir: ".",
216
215
  /**
217
- * Whether to search for all episode torrents, including those from season
218
- * packs.
219
- * This option overrides includeSingleEpisodes when set to true.
220
- */
221
- includeEpisodes: false,
222
- /**
223
- * Whether to include single episode torrents in the search (not those from
216
+ * Whether to include single episode torrents in a search (not those from
224
217
  * season packs).
225
- * Like `includeEpisodes` but slightly more restrictive.
218
+ *
219
+ * This setting does not affect matching episodes from rss and
220
+ * announce.
226
221
  */
227
222
  includeSingleEpisodes: false,
228
223
  /**
229
- * Include torrents which contain non-video files.
230
- * This option does not override includeEpisodes or includeSingleEpisodes.
224
+ * Include torrents which are comprised of non-video files.
231
225
  *
232
- * If this option is set to false, any folders or torrents containing ANY
233
- * non-video files will automatically be excluded from cross-seed searches.
226
+ * If this option is set to false, any folders or torrents whose
227
+ * totalNonVideoFilesSize / totalSize > fuzzySizeThreshold
228
+ * will be excluded.
234
229
  *
235
- * For example, if you have .srt or .nfo files inside your folders/torrents
236
- * you would set this as true.
230
+ * For example, if you have .srt or .nfo files inside a torrent, using
231
+ * false will still allow the torrent to be considered for cross-seeding
232
+ * while disallowing torrents that are music, games, books, etc.
237
233
  * For full disc based folders (not .ISO) you may wish to set this as true.
238
- * You may also want to set this as false to exclude things like music,
239
- * games, or books.
240
- *
241
- * To search for everything except episodes, use:
242
234
  *
243
- * includeEpisodes: false
244
- * includeSingleEpisodes: false
245
- * includeNonVideos: true
235
+ * To search for all video media except individual episodes, use:
246
236
  *
247
- * To search for everything including episodes, use:
237
+ * includeSingleEpisodes: false
238
+ * includeNonVideos: false
248
239
  *
249
- * includeEpisodes: true
250
- * includeNonVideos: true
240
+ * To search for all video media including individual episodes, use:
251
241
  *
252
- * To search for everything except season pack episodes (data-based) use:
242
+ * includeSingleEpisodes: true
243
+ * includeNonVideos: false
253
244
  *
254
- * includeEpisodes: false
255
- * includeSingleEpisodes: true
256
- * includeNonVideos: true
245
+ * To search for absolutely ALL types of content, including non-video, configure
246
+ * your episode settings based on the above examples and use:
257
247
  *
248
+ * includeNonVideos: true
258
249
  */
259
250
  includeNonVideos: false,
260
251
  /**
@@ -272,9 +263,10 @@ module.exports = {
272
263
  /**
273
264
  * Exclude torrents first seen by cross-seed more than this long ago.
274
265
  * Examples:
275
- * "10 minutes"
276
- * "1 day"
277
- * "0" - this will search everything exactly once, never more.
266
+ * "5 days"
267
+ * "2 weeks"
268
+ *
269
+ * This value must be in the range of 2-5 times your excludeRecentSearch
278
270
  */
279
271
  excludeOlder: "2 weeks",
280
272
  /**
@@ -283,11 +275,13 @@ module.exports = {
283
275
  * Doesn't exclude previously failed searches.
284
276
  * Examples:
285
277
  * "2 days"
286
- * "1 year"
278
+ * "5 days"
279
+ *
280
+ * This value must be 2-5x less than excludeOlder.
287
281
  */
288
282
  excludeRecentSearch: "3 days",
289
283
  /**
290
- * What action to take upon a match being found.
284
+ * Which action to take upon a match being found.
291
285
  * Options: "save", "inject".
292
286
  */
293
287
  action: "inject",
@@ -298,7 +292,7 @@ module.exports = {
298
292
  *
299
293
  * qBittorrent: This will apply the category's original category as a tag.
300
294
  *
301
- * Example: if you have a original label/category called "Movies", this will
295
+ * Example: if you have an original label/category called "Movies", this will
302
296
  * automatically inject cross-seeds to "Movies.cross-seed".
303
297
  */
304
298
  duplicateCategories: false,
@@ -316,6 +310,8 @@ module.exports = {
316
310
  * Examples:
317
311
  * "2 weeks"
318
312
  * "3 days"
313
+ *
314
+ * This value must be at least 3x less than your excludeRecentSearch
319
315
  */
320
316
  searchCadence: "1 day",
321
317
  /**
@@ -325,7 +321,7 @@ module.exports = {
325
321
  * "30 seconds"
326
322
  * null
327
323
  */
328
- snatchTimeout: undefined,
324
+ snatchTimeout: "30 seconds",
329
325
  /**
330
326
  * Fail search requests that haven't responded after this long.
331
327
  * Set to null for an infinite timeout.
@@ -333,7 +329,7 @@ module.exports = {
333
329
  * "30 seconds"
334
330
  * null
335
331
  */
336
- searchTimeout: undefined,
332
+ searchTimeout: "2 minutes",
337
333
  /**
338
334
  * The number of searches to make in one run/batch.
339
335
  * If more than this many searches are queued,
@@ -354,10 +350,10 @@ module.exports = {
354
350
  *
355
351
  * examples:
356
352
  *
357
- * blockList: ["-excludedGroup", "-excludedGroup2"],
358
- * blocklist: ["x265"],
359
- * blocklist: ["Release.Name"],
360
- * blocklist: ["3317e6485454354751555555366a8308c1e92093"],
353
+ * blockList: ["-excludedGroup", "-excludedGroup2"],
354
+ * blocklist: ["x265"],
355
+ * blocklist: ["Release.Name"],
356
+ * blocklist: ["3317e6485454354751555555366a8308c1e92093"],
361
357
  */
362
358
  blockList: undefined,
363
359
  };
@@ -1 +1 @@
1
- {"version":3,"file":"config.template.cjs","sourceRoot":"","sources":["../src/config.template.cjs"],"names":[],"mappings":";AAAA,+EAA+E;AAC/E,qBAAqB;;AAErB,MAAM,CAAC,OAAO,GAAG;IAChB;;;;;;;;QAQI;IAEJ;;;;;OAKG;IACH,MAAM,EAAE,SAAS;IAEjB;;;;;;OAMG;IACH,OAAO,EAAE,EAAE;IAEX;;;;;;;;;;;;;OAaG;IACH,MAAM,EAAE,SAAS;IAEjB;;;;;;;;;;;;;OAaG;IACH,MAAM,EAAE,SAAS;IAEjB;;;;OAIG;IACH,IAAI,EAAE,SAAS;IAEf;;OAEG;IACH,IAAI,EAAE,IAAI;IAEV;;;OAGG;IACH,sBAAsB,EAAE,SAAS;IAEjC;;;;OAIG;IACH,cAAc,EAAE,SAAS;IAEzB;;;;;;;;;OASG;IACH,cAAc,EAAE,SAAS;IAEzB;;;;;;OAMG;IACH,kBAAkB,EAAE,SAAS;IAE7B;;;;;;OAMG;IACH,YAAY,EAAE,SAAS;IAEvB;;OAEG;IAEH;;;;OAIG;IAEH,KAAK,EAAE,EAAE;IAET;;;;;;;;;;;;;;OAcG;IAEH,QAAQ,EAAE,EAAE;IAEZ;;;;;;;;OAQG;IACH,YAAY,EAAE,iBAAiB;IAE/B;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,EAAE,SAAS;IAElB;;;;;OAKG;IACH,QAAQ,EAAE,UAAU;IAEpB;;;;;;;;;;OAUG;IACH,WAAW,EAAE,KAAK;IAElB;;;;;;;;;;;OAWG;IACH,SAAS,EAAE,MAAM;IAEjB;;;;OAIG;IACH,YAAY,EAAE,CAAC;IAEf;;;;;;;;;OASG;IACH,UAAU,EAAE,2BAA2B;IAEvC;;;;OAIG;IACH,SAAS,EAAE,GAAG;IAEd;;;;OAIG;IACH,eAAe,EAAE,KAAK;IAEtB;;;;OAIG;IACH,qBAAqB,EAAE,KAAK;IAE5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,gBAAgB,EAAE,KAAK;IAEvB;;;;;;OAMG;IACH,kBAAkB,EAAE,IAAI;IAExB;;;OAGG;IAEH;;;;;;OAMG;IACH,YAAY,EAAE,SAAS;IAEvB;;;;;;;OAOG;IACH,mBAAmB,EAAE,QAAQ;IAE7B;;;OAGG;IACH,MAAM,EAAE,QAAQ;IAEhB;;;;;;;;;OASG;IACH,mBAAmB,EAAE,KAAK;IAE1B;;;;;;OAMG;IACH,UAAU,EAAE,YAAY;IAExB;;;;;;OAMG;IACH,aAAa,EAAE,OAAO;IAEtB;;;;;;OAMG;IACH,aAAa,EAAE,SAAS;IAExB;;;;;;OAMG;IACH,aAAa,EAAE,SAAS;IAExB;;;;;;;;;OASG;IACH,WAAW,EAAE,GAAG;IAEhB;;;;;;;;;;;;;OAaG;IACH,SAAS,EAAE,SAAS;CACpB,CAAC"}
1
+ {"version":3,"file":"config.template.cjs","sourceRoot":"","sources":["../src/config.template.cjs"],"names":[],"mappings":";AAAA,+EAA+E;AAC/E,qBAAqB;AAErB,MAAM,CAAC,OAAO,GAAG;IAChB;;;;;;;;QAQI;IAEJ;;;;;OAKG;IACH,MAAM,EAAE,SAAS;IAEjB;;;;;;OAMG;IACH,OAAO,EAAE,EAAE;IAEX;;;;;;;;;;;;;OAaG;IACH,MAAM,EAAE,SAAS;IAEjB;;;;;;;;;;;;;OAaG;IACH,MAAM,EAAE,SAAS;IAEjB;;;;OAIG;IACH,IAAI,EAAE,SAAS;IAEf;;OAEG;IACH,IAAI,EAAE,IAAI;IAEV;;;OAGG;IACH,sBAAsB,EAAE,SAAS;IAEjC;;;;OAIG;IACH,cAAc,EAAE,SAAS;IAEzB;;;;;;;;;OASG;IACH,cAAc,EAAE,SAAS;IAEzB;;;;;;OAMG;IACH,kBAAkB,EAAE,SAAS;IAE7B;;;;;;OAMG;IACH,YAAY,EAAE,SAAS;IAEvB;;OAEG;IAEH;;;;OAIG;IACH,KAAK,EAAE,EAAE;IAET;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,EAAE,EAAE;IAEZ;;;;;;;OAOG;IACH,YAAY,EAAE,iBAAiB;IAE/B;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,EAAE,SAAS;IAElB;;;;;OAKG;IACH,QAAQ,EAAE,UAAU;IAEpB;;;;;;;;;;OAUG;IACH,WAAW,EAAE,KAAK;IAElB;;;;;;;;;;;OAWG;IACH,SAAS,EAAE,MAAM;IAEjB;;;;OAIG;IACH,YAAY,EAAE,CAAC;IAEf;;;;;;;;;OASG;IACH,UAAU,EAAE,2BAA2B;IAEvC;;;;OAIG;IACH,SAAS,EAAE,GAAG;IAEd;;;;;;OAMG;IACH,qBAAqB,EAAE,KAAK;IAE5B;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,gBAAgB,EAAE,KAAK;IAEvB;;;;;;OAMG;IACH,kBAAkB,EAAE,IAAI;IAExB;;;OAGG;IAEH;;;;;;;OAOG;IACH,YAAY,EAAE,SAAS;IAEvB;;;;;;;;;OASG;IACH,mBAAmB,EAAE,QAAQ;IAE7B;;;OAGG;IACH,MAAM,EAAE,QAAQ;IAEhB;;;;;;;;;OASG;IACH,mBAAmB,EAAE,KAAK;IAE1B;;;;;;OAMG;IACH,UAAU,EAAE,YAAY;IAExB;;;;;;;;OAQG;IACH,aAAa,EAAE,OAAO;IAEtB;;;;;;OAMG;IACH,aAAa,EAAE,YAAY;IAE3B;;;;;;OAMG;IACH,aAAa,EAAE,WAAW;IAE1B;;;;;;;;;OASG;IACH,WAAW,EAAE,GAAG;IAEhB;;;;;;;;;;;;;OAaG;IACH,SAAS,EAAE,SAAS;CACpB,CAAC"}
@@ -1,20 +1,29 @@
1
1
  import ms from "ms";
2
+ import { isAbsolute, relative, resolve } from "path";
2
3
  import { z } from "zod";
3
- import { Action, LinkType, MatchMode } from "./constants.js";
4
+ import { Action, LinkType, MatchMode, NEWLINE_INDENT } from "./constants.js";
4
5
  import { logger } from "./logger.js";
5
- import { resolve, relative, isAbsolute } from "path";
6
6
  /**
7
7
  * error messages and map returned upon Zod validation failure
8
8
  */
9
9
  const ZodErrorMessages = {
10
10
  vercel: "format does not follow vercel's `ms` style ( https://github.com/vercel/ms#examples )",
11
11
  emptyString: "cannot have an empty string. If you want to unset it, use null or undefined.",
12
- delay: "delay is in seconds, you can't travel back in time.",
13
- fuzzySizeThreshold: "fuzzySizeThreshold must be between 0 and 1.",
12
+ delayNegative: "delay is in seconds, you can't travel back in time.",
13
+ delayUnsupported: `delay must be 30 seconds to 1 hour.${NEWLINE_INDENT}To even out search loads please see the following documentation:${NEWLINE_INDENT}(https://www.cross-seed.org/docs/basics/daemon#set-up-periodic-searches)`,
14
+ rssCadenceUnsupported: "rssCadence must be 10-120 minutes",
15
+ searchCadenceUnsupported: "searchCadence must be at least 1 day.",
16
+ searchCadenceExcludeRecent: "excludeRecentSearch must be at least 3x searchCadence.",
17
+ excludeRecentOlder: "excludeOlder and excludeRecentSearch must be defined for searching. excludeOlder must be 2-5x excludeRecentSearch.",
18
+ fuzzySizeThreshold: "fuzzySizeThreshold must be between 0 and 1 with a maximum of 0.1 when using searchCadence or rssCadence",
14
19
  injectUrl: "You need to specify rtorrentRpcUrl, transmissionRpcUrl, qbittorrentUrl, or delugeRpcUrl when using 'inject'",
15
20
  qBitAutoTMM: "If using Automatic Torrent Management in qBittorrent, please read: https://www.cross-seed.org/docs/v6-migration#qbittorrent",
21
+ includeSingleEpisodes: "includeSingleEpisodes is not recommended when using announce, please read: https://www.cross-seed.org/docs/v6-migration#updated-includesingleepisodes-behavior",
22
+ needsTorrentDir: "You need to set torrentDir for rss and announce matching to work.",
23
+ needsInject: "You need to use the 'inject' action for partial matching.",
16
24
  needsLinkDir: "You need to set a linkDir (and have your data accessible) for risky or partial matching to work.",
17
25
  linkDirInDataDir: "You cannot have your linkDir inside of your dataDirs. Please adjust your paths to correct this.",
26
+ outputDirInInputDir: "You cannot have your outputDir inside of your torrentDir/dataDirs. Please adjust your paths to correct this.",
18
27
  };
19
28
  /**
20
29
  * custom zod error map for logging
@@ -61,15 +70,15 @@ function transformDurationString(durationStr, ctx) {
61
70
  return duration;
62
71
  }
63
72
  /**
64
- * check a potential child path being inside a array of parent paths
65
- * @param linkDir path of the potential child (linkDir)
66
- * @param dataDirs array of dataDir paths
67
- * @returns true if `linkDir` is inside any dataDir at any nesting level, false otherwise.
73
+ * check a potential child path being inside an array of parent paths
74
+ * @param childDir path of the potential child (e.g. linkDir)
75
+ * @param parentDirs array of parentDir paths (e.g. dataDirs)
76
+ * @returns true if `childDir` is inside any `parentDirs` at any nesting level, false otherwise.
68
77
  */
69
- function isChildPath(linkDir, dataDirs) {
70
- return dataDirs.some((datadir) => {
71
- const resolvedParent = resolve(datadir);
72
- const resolvedChild = resolve(linkDir);
78
+ function isChildPath(childDir, parentDirs) {
79
+ return parentDirs.some((parentDir) => {
80
+ const resolvedParent = resolve(parentDir);
81
+ const resolvedChild = resolve(childDir);
73
82
  const relativePath = relative(resolvedParent, resolvedChild);
74
83
  // if the path does not start with '..' and is not absolute
75
84
  return !(relativePath.startsWith("..") || isAbsolute(relativePath));
@@ -81,9 +90,13 @@ function isChildPath(linkDir, dataDirs) {
81
90
  */
82
91
  export const VALIDATION_SCHEMA = z
83
92
  .object({
84
- delay: z.number().nonnegative({
85
- message: ZodErrorMessages.delay,
86
- }),
93
+ delay: z
94
+ .number()
95
+ .nonnegative({
96
+ message: ZodErrorMessages.delayNegative,
97
+ })
98
+ .gte(process.env.DEV ? 0 : 30, ZodErrorMessages.delayUnsupported)
99
+ .lte(3600, ZodErrorMessages.delayUnsupported),
87
100
  torznab: z.array(z.string().url()),
88
101
  dataDirs: z.array(z.string()).nullish(),
89
102
  matchMode: z.nativeEnum(MatchMode),
@@ -97,7 +110,7 @@ export const VALIDATION_SCHEMA = z
97
110
  maxDataDepth: z.number().gte(1),
98
111
  torrentDir: z.string().nullable(),
99
112
  outputDir: z.string(),
100
- includeEpisodes: z.boolean(),
113
+ injectDir: z.string().optional(),
101
114
  includeSingleEpisodes: z.boolean(),
102
115
  includeNonVideos: z.boolean(),
103
116
  fuzzySizeThreshold: z.number().positive().lte(1, {
@@ -107,12 +120,24 @@ export const VALIDATION_SCHEMA = z
107
120
  .string()
108
121
  .min(1, { message: ZodErrorMessages.emptyString })
109
122
  .transform(transformDurationString)
110
- .nullish(),
123
+ .nullish()
124
+ .or(z
125
+ .boolean()
126
+ .refine((value) => value !== true, {
127
+ message: "Expected string, received boolean (true)",
128
+ })
129
+ .transform(() => null)),
111
130
  excludeRecentSearch: z
112
131
  .string()
113
132
  .min(1, { message: ZodErrorMessages.emptyString })
114
133
  .transform(transformDurationString)
115
- .nullish(),
134
+ .nullish()
135
+ .or(z
136
+ .boolean()
137
+ .refine((value) => value !== true, {
138
+ message: "Expected string, received boolean (true)",
139
+ })
140
+ .transform(() => null)),
116
141
  action: z.nativeEnum(Action),
117
142
  qbittorrentUrl: z.string().url().nullish(),
118
143
  rtorrentRpcUrl: z.string().url().nullish(),
@@ -131,12 +156,16 @@ export const VALIDATION_SCHEMA = z
131
156
  .string()
132
157
  .min(1, { message: ZodErrorMessages.emptyString })
133
158
  .transform(transformDurationString)
134
- .nullish(),
159
+ .nullish()
160
+ .refine((cadence) => process.env.DEV ||
161
+ !cadence ||
162
+ (cadence >= ms("10 minutes") && cadence <= ms("2 hours")), ZodErrorMessages.rssCadenceUnsupported),
135
163
  searchCadence: z
136
164
  .string()
137
165
  .min(1, { message: ZodErrorMessages.emptyString })
138
166
  .transform(transformDurationString)
139
- .nullish(),
167
+ .nullish()
168
+ .refine((cadence) => process.env.DEV || !cadence || cadence >= ms("1 day"), ZodErrorMessages.searchCadenceUnsupported),
140
169
  snatchTimeout: z
141
170
  .string()
142
171
  .min(1, { message: ZodErrorMessages.emptyString })
@@ -155,10 +184,26 @@ export const VALIDATION_SCHEMA = z
155
184
  .nullish()
156
185
  .transform((value) => (Array.isArray(value) ? value : [])),
157
186
  apiKey: z.string().min(24).nullish(),
158
- radarr: z.array(z.string().url()).nullish(),
159
- sonarr: z.array(z.string().url()).nullish(),
187
+ radarr: z
188
+ .array(z.string().url())
189
+ .nullish()
190
+ .transform((value) => value ?? []),
191
+ sonarr: z
192
+ .array(z.string().url())
193
+ .nullish()
194
+ .transform((value) => value ?? []),
160
195
  })
161
196
  .strict()
197
+ .refine((config) => !config.searchCadence ||
198
+ !config.excludeRecentSearch ||
199
+ 3 * config.searchCadence <= config.excludeRecentSearch, ZodErrorMessages.searchCadenceExcludeRecent)
200
+ .refine((config) => !config.searchCadence ||
201
+ (config.excludeOlder &&
202
+ config.excludeRecentSearch &&
203
+ config.excludeOlder >= 2 * config.excludeRecentSearch &&
204
+ config.excludeOlder <= 5 * config.excludeRecentSearch), ZodErrorMessages.excludeRecentOlder)
205
+ .refine((config) => config.fuzzySizeThreshold <= 0.1 ||
206
+ (!config.searchCadence && !config.rssCadence), ZodErrorMessages.fuzzySizeThreshold)
162
207
  .refine((config) => {
163
208
  if (config.action === Action.INJECT &&
164
209
  config.qbittorrentUrl &&
@@ -168,16 +213,35 @@ export const VALIDATION_SCHEMA = z
168
213
  }
169
214
  return true;
170
215
  })
171
- .refine((config) => !(config.action === Action.INJECT &&
216
+ .refine((config) => {
217
+ if (config.includeSingleEpisodes && config.rssCadence) {
218
+ logger.warn(ZodErrorMessages.includeSingleEpisodes);
219
+ }
220
+ return true;
221
+ })
222
+ .refine((config) => !((config.action === Action.INJECT || config.injectDir) &&
172
223
  !config.rtorrentRpcUrl &&
173
224
  !config.qbittorrentUrl &&
174
225
  !config.transmissionRpcUrl &&
175
226
  !config.delugeRpcUrl), ZodErrorMessages.injectUrl)
176
- .refine((config) => config.matchMode === MatchMode.SAFE || config.linkDir, ZodErrorMessages.needsLinkDir)
227
+ .refine((config) => process.env.DEV ||
228
+ config.action === Action.INJECT ||
229
+ config.matchMode !== MatchMode.PARTIAL, ZodErrorMessages.needsInject)
230
+ .refine((config) => config.torrentDir || !config.rssCadence, ZodErrorMessages.needsTorrentDir)
231
+ .refine((config) => config.linkDir || config.matchMode === MatchMode.SAFE, ZodErrorMessages.needsLinkDir)
177
232
  .refine((config) => {
178
233
  if (config.linkDir && config.dataDirs) {
179
234
  return !isChildPath(config.linkDir, config.dataDirs);
180
235
  }
181
236
  return true;
182
- }, ZodErrorMessages.linkDirInDataDir);
237
+ }, ZodErrorMessages.linkDirInDataDir)
238
+ .refine((config) => {
239
+ if (config.torrentDir) {
240
+ return !isChildPath(config.outputDir, [
241
+ config.torrentDir,
242
+ ...(config.dataDirs ?? []),
243
+ ]);
244
+ }
245
+ return true;
246
+ }, ZodErrorMessages.outputDirInInputDir);
183
247
  //# sourceMappingURL=configSchema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"configSchema.js","sourceRoot":"","sources":["../src/configSchema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"configSchema.js","sourceRoot":"","sources":["../src/configSchema.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import chalk from "chalk";
2
- import { accessSync, copyFileSync, existsSync, mkdirSync, constants } from "fs";
2
+ import { accessSync, constants, copyFileSync, existsSync, mkdirSync } from "fs";
3
3
  import { createRequire } from "module";
4
4
  import path from "path";
5
5
  import { pathToFileURL } from "url";
@@ -23,6 +23,9 @@ export function appDir() {
23
23
  accessSync(appDir, constants.R_OK | constants.W_OK);
24
24
  }
25
25
  catch (e) {
26
+ if (e.code === "ENOENT") {
27
+ return appDir;
28
+ }
26
29
  const dockerMessage = process.env.DOCKER_ENV === "true"
27
30
  ? ` Use chown to set the owner to ${process.getuid()}:${process.getgid()}`
28
31
  : "";
@@ -1 +1 @@
1
- {"version":3,"file":"configuration.js","sourceRoot":"","sources":["../src/configuration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,cAAc,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAyClD,MAAM,CAAC,MAAM,yBAAyB,GAAG;;;;;;;CAOxC,CAAC,IAAI,EAAE,CAAC;AAET,MAAM,UAAU,MAAM;IACrB,MAAM,MAAM,GACX,OAAO,CAAC,GAAG,CAAC,UAAU;QACtB,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO;YAC5B,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,YAAa,EAAE,cAAc,CAAC,IAAI,CAAC;YAC9D,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,IAAK,EAAE,IAAI,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAChE,IAAI,CAAC;QACJ,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IACrD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACZ,MAAM,aAAa,GAClB,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,MAAM;YAChC,CAAC,CAAC,kCAAkC,OAAO,CAAC,MAAO,EAAE,IAAI,OAAO,CAAC,MAAO,EAAE,EAAE;YAC5E,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,cAAc,CACvB,qEAAqE,aAAa,EAAE,CACpF,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED,MAAM,UAAU,YAAY;IAC3B,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,eAAe,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,cAAc;IAC7B,YAAY,EAAE,CAAC;IACf,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,WAAW,CAAC,CAAC;IAC9C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IACxD,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;QAClD,OAAO;IACR,CAAC;IACD,YAAY,CAAC,IAAI,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,+BAA+B,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IAClC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC;QACvC,cAAc,EAAE,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,WAAW,CAAC,CAAC;IAEpD,IAAI,CAAC;QACJ,OAAO,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IACrE,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACZ,IAAI,CAAC,CAAC,IAAI,KAAK,sBAAsB,EAAE,CAAC;YACvC,OAAO,EAAE,CAAC;QACX,CAAC;aAAM,IAAI,CAAC,YAAY,WAAW,EAAE,CAAC;YACrC,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7D,MAAM,IAAI,cAAc,CACvB,KAAK,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,yBAAyB,EAAE,CAC1D,CAAC;QACH,CAAC;aAAM,CAAC;YACP,MAAM,CAAC,CAAC;QACT,CAAC;IACF,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"configuration.js","sourceRoot":"","sources":["../src/configuration.ts"],"names":[],"mappings":"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"}
package/dist/constants.js CHANGED
@@ -6,17 +6,56 @@ export const PROGRAM_VERSION = packageDotJson.version;
6
6
  export const USER_AGENT = `CrossSeed/${PROGRAM_VERSION}`;
7
7
  export const TORRENT_TAG = "cross-seed";
8
8
  export const TORRENT_CATEGORY_SUFFIX = `.cross-seed`;
9
- export const EP_REGEX = /^(?<title>.+?)[_.\s-]+(?:(?<season>S\d+)?[_.\s-]{0,3}(?<episode>(?:E|(?<=S\d+[_\s-]{1,3}))\d+(?:[\s-]?E?\d+)?(?![pix]))(?!\d+[pix])|(?<date>(?<year>(?:19|20)\d{2})[_.\s-](?<month>\d{2})[_.\s-](?<day>\d{2})))/i;
10
- export const SEASON_REGEX = /^(?<title>.+?)[[_.\s-]+(?<season>S\d+)(?:[_.\s~-]*?(?<seasonmax>S?\d+))?(?=[\]_.\s](?!E\d+))/i;
9
+ export const NEWLINE_INDENT = "\n\t\t\t\t";
10
+ export const EP_REGEX = /^(?<title>.+?)[_.\s-]+(?:(?<season>S\d+)?[_.\s-]{0,3}(?!(?:19|20)\d{2})(?<episode>(?:E|(?<=S\d+[_\s-]{1,3}))\d+(?:[\s-]?(?!(?:19|20)\d{2})E?\d+)?(?![pix]))(?!\d+[pix])|(?<date>(?<year>(?:19|20)\d{2})[_.\s-](?<month>\d{2})[_.\s-](?<day>\d{2})))/i;
11
+ export const IS_MULTI_EP_REGEX = /E\d+(?:[-.]?S\d+E\d|[-.]?E\d|[-.]\d)/i;
12
+ export const SEASON_REGEX = /^(?<title>.+?)[[_.\s-]+(?<season>S\d+)(?:[_.\s~-]*?(?<seasonmax>S?\d+))?(?=\b(?!E\d+))/i;
11
13
  export const MOVIE_REGEX = /^(?<title>.+?)-?[_.\s][[(]?(?<year>(?:18|19|20)\d{2})[)\]]?(?![pix])/i;
12
- export const ANIME_REGEX = /^(?:\[(?<group>.*?)\][_.\s-]?)?(?:\[?(?<title>.+?)[_.\s-]?(?:\(?(?:\d{1,2}(?:st|nd|rd|th))?\s?Season)?[_.\s-]?\]?)(?:[([~/|-]\s?(?!\d{1,4})(?<altTitle>.+?)[)\]~-]?\s?)?[_.\s-]?(?:[[(]?(?<year>(?:19|20)\d{2})[)\]]?)?[[_.\s-](?:S\d{1,2})?[_.\s-]{0,3}(?:#|EP?|(?:SP))?[_.\s-]{0,3}(?<release>\d{1,4})/i;
13
- export const RELEASE_GROUP_REGEX = /(?<=-)(?:\W|\b)(?!(?:\d{3,4}[ip]))(?!\d+\b)(?:\W|\b)(?<group>[\w ]+?)(?:\[.+\])?(?:\))?(?=(?:\.\w{1,5})?$)/i;
14
- export const RESOLUTION_REGEX = /\b(?<res>\d{3,4}[ipx])\b/i;
14
+ export const ANIME_REGEX = /^(?:\[(?<group>.*?)\][_\s-]?)?(?:\[?(?<title>.+?)[_\s-]?(?:\(?(?:\d{1,2}(?:st|nd|rd|th))?\s?Season)?[_\s-]?\]?)(?:[([~/|-]\s?(?!\d{1,4})(?<altTitle>.+?)[)\]~-]?\s?)?[_\s-]?(?:[[(]?(?<year>(?:19|20)\d{2})[)\]]?)?[[_\s-](?:S\d{1,2})?[_\s-]{0,3}(?:#|EP?|(?:SP))?[_\s-]{0,3}(?!\d+[a-uw-z])(?<release>\d{1,4})(?!\.[0-46-9])/i;
15
+ export const RELEASE_GROUP_REGEX = /(?<=-)(?:\W|\b)(?!(?:\d{3,4}[ip]))(?!\d+\b)(?:\W|\b)(?<group>[\w .]+?)(?:\[.+\])?(?:\))?(?:\s\[.+\])?$/i;
16
+ export const ANIME_GROUP_REGEX = /^\s*\[(?<group>.+?)\]/i;
17
+ export const RESOLUTION_REGEX = /\b(?<res>\d{3,4}[pix](?:\d{3,4}[pi]?)?)\b/i;
15
18
  export const RES_STRICT_REGEX = /(?<res>(?:2160|1080|720)[pi])/;
16
- export const REPACK_PROPER_REGEX = /(?:\b(?<type>(?:REPACK|PROPER|\d\v\d)\d?))|(?<arrtype>(?:Proper|v\d))\b/;
17
- export const SCENE_TITLE_REGEX = /^(?:\w{0,5}-)?(?<title>.*)/i;
18
- export const ARR_DIR_REGEX = /^(?!.*(?:(\d{3,4}[ipx])|([xh]26[4-6])|(?:(he)|a)vc))[\p{L}\s:\w'’!().,&–+-]+(?:\(\d{4}\))?\s?(?:\{(?:tm|tv|im)db(?:id)?-\w+\})?$/iu;
19
+ export const YEARS_REGEX = /(?<year>(?:19|20)\d{2})(?![pix])/gi;
20
+ export const REPACK_PROPER_REGEX = /(?:\b(?<type>(?:REPACK|PROPER|\d\v\d)\d?))\b/i;
21
+ export const ARR_PROPER_REGEX = /(?:\b(?<arrtype>(?:Proper|v\d)))\b/;
22
+ export const SCENE_TITLE_REGEX = /^(?:[a-z0-9]{0,5}-)?(?<title>.*)/;
23
+ export const ARR_DIR_REGEX = /^(?<title>(?!.*(?:(\d{3,4}[ipx])|([xh.]+26[4-6])|(dvd)|(mpeg)|(xvid)|(?:(he)|a)vc))[\p{L}\s:\w'’!();.,&–+-]+(?:\(\d{4}\))?)(?<id>\s[{[](?:tm|tv|im)db(?:id)?-\w+?[}\]])?$/iu;
24
+ export const SONARR_SUBFOLDERS_REGEX = /^(?:S(?:eason )?(?<seasonNum>\d{1,4}))$/i;
25
+ export const NON_UNICODE_ALPHANUM_REGEX = /[^\p{L}\p{N}]+/giu;
26
+ export const CALIBRE_INDEXNUM_REGEX = /\s?\(\d+\)$/;
27
+ export const SAVED_TORRENTS_INFO_REGEX = /^\[(?<mediaType>.+?)\]\[(?<tracker>.+?)\](?<name>.+?)(?:\[[^\]]*?\])?\.torrent$/i;
28
+ export const BAD_GROUP_PARSE_REGEX = /^(?<badmatch>(?:dl|DDP?|aac|eac3|atmos|dts|ma|hd|[heav.c]{3.5}|[xh.]{1,2}[2456]|[0-9]+[ip]?|dxva|full|blu|ray|s(?:eason)?\W\d+|\W){3,})$/i;
29
+ export const JSON_VALUES_REGEX = /".+?"\s*:\s*"(?<value>.+?)"\s*(?:,|})/g;
30
+ // Needs to be handled through helper functions since there are variations
31
+ const SOURCE_REGEXES = {
32
+ AMZN: /\b(amzn|amazon(hd)?)\b[ ._-]web[ ._-]?(dl|rip)?\b/i,
33
+ DSNP: /\b(dsnp|dsny|disney)\b/i,
34
+ NF: /\b(nf|netflix(u?hd)?)\b/i,
35
+ HULU: /\b(hulu)\b/i,
36
+ ATVP: /\b(atvp|aptv)\b/i,
37
+ HBO: /\b(hbo)(?![ ._-]max)\b|\b(hmax|hbom|hbo[ ._-]max)\b/i,
38
+ PCOK: /\b(pcok)\b/i,
39
+ PMTP: /\b(pmtp|Paramount Plus)\b/i,
40
+ };
41
+ export function parseSource(title) {
42
+ for (const [source, regex] of Object.entries(SOURCE_REGEXES)) {
43
+ if (regex.test(title))
44
+ return source;
45
+ }
46
+ return null;
47
+ }
48
+ export function sourceRegexRemove(title) {
49
+ const originalLength = title.length;
50
+ for (const regex of Object.values(SOURCE_REGEXES)) {
51
+ const newTitle = title.replace(regex, "");
52
+ if (newTitle.length !== originalLength)
53
+ return newTitle;
54
+ }
55
+ return title;
56
+ }
19
57
  export const VIDEO_EXTENSIONS = [".mkv", ".mp4", ".avi", ".ts"];
58
+ export const VIDEO_DISC_EXTENSIONS = [".m2ts", ".ifo", ".vob", ".bup"];
20
59
  export const AUDIO_EXTENSIONS = [
21
60
  ".wav",
22
61
  ".aiff",
@@ -53,9 +92,11 @@ export const ALL_EXTENSIONS = [
53
92
  ...VIDEO_EXTENSIONS,
54
93
  ...AUDIO_EXTENSIONS,
55
94
  ...BOOK_EXTENSIONS,
95
+ ...VIDEO_DISC_EXTENSIONS,
56
96
  ];
57
- export const IGNORED_FOLDERS_REGEX = /^(S(eason )?\d{1,4}|((CD|DVD|DISC)\d{1,2}))$/i;
58
97
  export const TORRENT_CACHE_FOLDER = "torrent_cache";
98
+ export const UNKNOWN_TRACKER = "UnknownTracker";
99
+ export const LEVENSHTEIN_DIVISOR = 3;
59
100
  export var Action;
60
101
  (function (Action) {
61
102
  Action["SAVE"] = "save";
@@ -84,18 +125,36 @@ export var Decision;
84
125
  Decision["DOWNLOAD_FAILED"] = "DOWNLOAD_FAILED";
85
126
  Decision["MAGNET_LINK"] = "MAGNET_LINK";
86
127
  Decision["RATE_LIMITED"] = "RATE_LIMITED";
128
+ /**
129
+ * Searchee and Candidate info hash matches. Usually happens with public
130
+ * torrents and torrents added by radarr/sonarr before cross-seed on announces.
131
+ * Useful for the inject job as we ignore INFO_HASH_ALREADY_EXISTS and
132
+ * for reporting a 204 announce status code instead of 200 from exists.
133
+ */
134
+ Decision["SAME_INFO_HASH"] = "SAME_INFO_HASH";
135
+ /**
136
+ * Checked after SAME_INFO_HASH.
137
+ */
87
138
  Decision["INFO_HASH_ALREADY_EXISTS"] = "INFO_HASH_ALREADY_EXISTS";
88
139
  Decision["FILE_TREE_MISMATCH"] = "FILE_TREE_MISMATCH";
89
140
  Decision["RELEASE_GROUP_MISMATCH"] = "RELEASE_GROUP_MISMATCH";
90
141
  Decision["BLOCKED_RELEASE"] = "BLOCKED_RELEASE";
91
142
  Decision["PROPER_REPACK_MISMATCH"] = "PROPER_REPACK_MISMATCH";
92
143
  Decision["RESOLUTION_MISMATCH"] = "RESOLUTION_MISMATCH";
144
+ Decision["SOURCE_MISMATCH"] = "SOURCE_MISMATCH";
93
145
  })(Decision || (Decision = {}));
94
- export function isDecisionAnyMatch(decision) {
146
+ export function isAnyMatchedDecision(decision) {
95
147
  return (decision === Decision.MATCH ||
96
148
  decision === Decision.MATCH_SIZE_ONLY ||
97
149
  decision === Decision.MATCH_PARTIAL);
98
150
  }
151
+ export function isStaticDecision(decision) {
152
+ return (decision === Decision.RELEASE_GROUP_MISMATCH ||
153
+ decision === Decision.RESOLUTION_MISMATCH ||
154
+ decision === Decision.SOURCE_MISMATCH ||
155
+ decision === Decision.PROPER_REPACK_MISMATCH ||
156
+ decision === Decision.MAGNET_LINK);
157
+ }
99
158
  export var MatchMode;
100
159
  (function (MatchMode) {
101
160
  MatchMode["SAFE"] = "safe";