cross-seed 6.0.0-2 → 6.0.0-20
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/dist/Result.js +17 -11
- package/dist/Result.js.map +1 -1
- package/dist/action.js +141 -45
- package/dist/action.js.map +1 -1
- package/dist/arr.js +200 -0
- package/dist/arr.js.map +1 -0
- package/dist/clients/Deluge.js +121 -61
- package/dist/clients/Deluge.js.map +1 -1
- package/dist/clients/QBittorrent.js +70 -64
- package/dist/clients/QBittorrent.js.map +1 -1
- package/dist/clients/RTorrent.js +9 -9
- package/dist/clients/RTorrent.js.map +1 -1
- package/dist/clients/TorrentClient.js.map +1 -1
- package/dist/clients/Transmission.js +9 -9
- package/dist/clients/Transmission.js.map +1 -1
- package/dist/cmd.js +11 -7
- package/dist/cmd.js.map +1 -1
- package/dist/config.template.cjs +68 -36
- package/dist/config.template.cjs.map +1 -1
- package/dist/configSchema.js +42 -8
- package/dist/configSchema.js.map +1 -1
- package/dist/configuration.js.map +1 -1
- package/dist/constants.js +89 -6
- package/dist/constants.js.map +1 -1
- package/dist/dataFiles.js +4 -5
- package/dist/dataFiles.js.map +1 -1
- package/dist/decide.js +128 -90
- package/dist/decide.js.map +1 -1
- package/dist/errors.js +5 -2
- package/dist/errors.js.map +1 -1
- package/dist/indexers.js +31 -4
- package/dist/indexers.js.map +1 -1
- package/dist/jobs.js +2 -0
- package/dist/jobs.js.map +1 -1
- package/dist/logger.js +18 -5
- package/dist/logger.js.map +1 -1
- package/dist/migrations/05-caps.js +16 -0
- package/dist/migrations/05-caps.js.map +1 -0
- package/dist/migrations/migrations.js +9 -1
- package/dist/migrations/migrations.js.map +1 -1
- package/dist/pipeline.js +165 -81
- package/dist/pipeline.js.map +1 -1
- package/dist/preFilter.js +89 -36
- package/dist/preFilter.js.map +1 -1
- package/dist/pushNotifier.js +2 -1
- package/dist/pushNotifier.js.map +1 -1
- package/dist/runtimeConfig.js.map +1 -1
- package/dist/searchee.js +149 -10
- package/dist/searchee.js.map +1 -1
- package/dist/server.js +10 -10
- package/dist/server.js.map +1 -1
- package/dist/startup.js +2 -0
- package/dist/startup.js.map +1 -1
- package/dist/torrent.js +86 -28
- package/dist/torrent.js.map +1 -1
- package/dist/torznab.js +250 -88
- package/dist/torznab.js.map +1 -1
- package/dist/utils.js +84 -21
- package/dist/utils.js.map +1 -1
- package/package.json +3 -1
@@ -3,8 +3,16 @@ import jobs from "./01-jobs.js";
|
|
3
3
|
import timestamps from "./02-timestamps.js";
|
4
4
|
import rateLimits from "./03-rateLimits.js";
|
5
5
|
import auth from "./04-auth.js";
|
6
|
+
import caps from "./05-caps.js";
|
6
7
|
export const migrations = {
|
7
|
-
getMigrations: () => Promise.resolve([
|
8
|
+
getMigrations: () => Promise.resolve([
|
9
|
+
initialSchema,
|
10
|
+
jobs,
|
11
|
+
timestamps,
|
12
|
+
rateLimits,
|
13
|
+
auth,
|
14
|
+
caps,
|
15
|
+
]),
|
8
16
|
getMigrationName: (migration) => migration.name,
|
9
17
|
getMigration: (migration) => migration,
|
10
18
|
};
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/migrations/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,uBAAuB,CAAC;AAClD,OAAO,IAAI,MAAM,cAAc,CAAC;AAChC,OAAO,UAAU,MAAM,oBAAoB,CAAC;AAC5C,OAAO,UAAU,MAAM,oBAAoB,CAAC;AAC5C,OAAO,IAAI,MAAM,cAAc,CAAC;AAEhC,MAAM,CAAC,MAAM,UAAU,GAAG;IACzB,aAAa,EAAE,GAAG,EAAE,CACnB,OAAO,CAAC,OAAO,CAAC,
|
1
|
+
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/migrations/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,uBAAuB,CAAC;AAClD,OAAO,IAAI,MAAM,cAAc,CAAC;AAChC,OAAO,UAAU,MAAM,oBAAoB,CAAC;AAC5C,OAAO,UAAU,MAAM,oBAAoB,CAAC;AAC5C,OAAO,IAAI,MAAM,cAAc,CAAC;AAChC,OAAO,IAAI,MAAM,cAAc,CAAC;AAEhC,MAAM,CAAC,MAAM,UAAU,GAAG;IACzB,aAAa,EAAE,GAAG,EAAE,CACnB,OAAO,CAAC,OAAO,CAAC;QACf,aAAa;QACb,IAAI;QACJ,UAAU;QACV,UAAU;QACV,IAAI;QACJ,IAAI;KACJ,CAAC;IACH,gBAAgB,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI;IAC/C,YAAY,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS;CACtC,CAAC"}
|
package/dist/pipeline.js
CHANGED
@@ -3,19 +3,20 @@ import fs from "fs";
|
|
3
3
|
import { zip } from "lodash-es";
|
4
4
|
import ms from "ms";
|
5
5
|
import { performAction, performActions } from "./action.js";
|
6
|
-
import { Decision, InjectionResult, } from "./constants.js";
|
6
|
+
import { Decision, InjectionResult, isAnyMatchedDecision, SaveResult, } from "./constants.js";
|
7
7
|
import { findPotentialNestedRoots, findSearcheesFromAllDataDirs, } from "./dataFiles.js";
|
8
8
|
import { db } from "./db.js";
|
9
9
|
import { assessCandidate } from "./decide.js";
|
10
10
|
import { IndexerStatus, updateIndexerStatus, updateSearchTimestamps, } from "./indexers.js";
|
11
11
|
import { Label, logger } from "./logger.js";
|
12
|
-
import { filterByContent,
|
12
|
+
import { filterByContent, filterDupesFromSimilar, filterTimestamps, } from "./preFilter.js";
|
13
13
|
import { sendResultsNotification } from "./pushNotifier.js";
|
14
|
+
import { isOk } from "./Result.js";
|
14
15
|
import { getRuntimeConfig } from "./runtimeConfig.js";
|
15
16
|
import { createSearcheeFromMetafile, createSearcheeFromPath, createSearcheeFromTorrentFile, } from "./searchee.js";
|
16
|
-
import { getInfoHashesToExclude, getTorrentByCriteria,
|
17
|
-
import { queryRssFeeds, searchTorznab } from "./torznab.js";
|
18
|
-
import {
|
17
|
+
import { getInfoHashesToExclude, getTorrentByCriteria, getSimilarTorrentsByName, indexNewTorrents, loadTorrentDirLight, } from "./torrent.js";
|
18
|
+
import { getSearchString, queryRssFeeds, searchTorznab, } from "./torznab.js";
|
19
|
+
import { getLogString, isTruthy, wait } from "./utils.js";
|
19
20
|
async function assessCandidates(candidates, searchee, hashesToExclude) {
|
20
21
|
const assessments = [];
|
21
22
|
for (const result of candidates) {
|
@@ -24,21 +25,15 @@ async function assessCandidates(candidates, searchee, hashesToExclude) {
|
|
24
25
|
}
|
25
26
|
return assessments;
|
26
27
|
}
|
27
|
-
async function findOnOtherSites(searchee, hashesToExclude) {
|
28
|
+
async function findOnOtherSites(searchee, hashesToExclude, cachedSearch, progress) {
|
28
29
|
// make sure searchee is in database
|
29
30
|
await db("searchee")
|
30
31
|
.insert({ name: searchee.name })
|
31
32
|
.onConflict("name")
|
32
33
|
.ignore();
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
}
|
37
|
-
catch (e) {
|
38
|
-
logger.error(`error searching for ${searchee.name}`);
|
39
|
-
logger.debug(e);
|
40
|
-
return { searchedIndexers: 0, matches: 0 };
|
41
|
-
}
|
34
|
+
const response = await searchTorznab(searchee, cachedSearch, progress);
|
35
|
+
const searchedIndexers = response.length - cachedSearch.indexerCandidates.length;
|
36
|
+
cachedSearch.indexerCandidates = response;
|
42
37
|
const results = response.flatMap((e) => e.candidates.map((candidate) => ({
|
43
38
|
...candidate,
|
44
39
|
indexerId: e.indexerId,
|
@@ -55,141 +50,230 @@ async function findOnOtherSites(searchee, hashesToExclude) {
|
|
55
50
|
rateLimited: new Set(),
|
56
51
|
notRateLimited: new Set(response.map((r) => r.indexerId)),
|
57
52
|
});
|
58
|
-
const matches = assessments.filter((e) => e.assessment.decision
|
59
|
-
e.assessment.decision === Decision.MATCH_SIZE_ONLY ||
|
60
|
-
e.assessment.decision === Decision.MATCH_PARTIAL);
|
53
|
+
const matches = assessments.filter((e) => isAnyMatchedDecision(e.assessment.decision));
|
61
54
|
const actionResults = await performActions(searchee, matches);
|
62
55
|
if (actionResults.includes(InjectionResult.TORRENT_NOT_COMPLETE)) {
|
63
56
|
// If the torrent is not complete, "cancel the search"
|
64
|
-
return {
|
57
|
+
return { searchedIndexers: 0, matches: 0 };
|
65
58
|
}
|
66
59
|
await updateSearchTimestamps(searchee.name, Array.from(notRateLimited));
|
67
60
|
await updateIndexerStatus(IndexerStatus.RATE_LIMITED, Date.now() + ms("1 hour"), Array.from(rateLimited));
|
68
61
|
const zipped = zip(matches.map((m) => m.assessment), matches.map((m) => m.tracker), actionResults);
|
69
|
-
sendResultsNotification(searchee, zipped
|
70
|
-
return { matches: matches.length
|
62
|
+
sendResultsNotification(searchee, zipped);
|
63
|
+
return { searchedIndexers, matches: matches.length };
|
71
64
|
}
|
72
|
-
async function findMatchesBatch(
|
65
|
+
async function findMatchesBatch(searchees, hashesToExclude) {
|
73
66
|
const { delay } = getRuntimeConfig();
|
74
67
|
let totalFound = 0;
|
75
|
-
|
68
|
+
let prevSearchTime = 0;
|
69
|
+
const cachedSearch = { q: null, indexerCandidates: [] };
|
70
|
+
for (const [i, searchee] of searchees.entries()) {
|
71
|
+
const progress = chalk.blue(`(${i + 1}/${searchees.length}) `);
|
76
72
|
try {
|
77
|
-
const
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
const
|
73
|
+
const sleepTime = delay * 1000 - (Date.now() - prevSearchTime);
|
74
|
+
if (sleepTime > 0) {
|
75
|
+
await new Promise((r) => setTimeout(r, sleepTime));
|
76
|
+
}
|
77
|
+
const searchTime = Date.now();
|
78
|
+
const { searchedIndexers, matches } = await findOnOtherSites(searchee, hashesToExclude, cachedSearch, progress);
|
82
79
|
totalFound += matches;
|
83
|
-
// if all indexers were rate limited, don't sleep
|
80
|
+
// if all indexers were rate limited or cached, don't sleep
|
84
81
|
if (searchedIndexers === 0)
|
85
82
|
continue;
|
86
|
-
|
83
|
+
prevSearchTime = searchTime;
|
87
84
|
}
|
88
85
|
catch (e) {
|
89
|
-
|
86
|
+
const searcheeLog = getLogString(searchee, chalk.bold.white);
|
87
|
+
logger.error({
|
88
|
+
label: searchee.label,
|
89
|
+
message: `${progress}Error searching for ${searcheeLog}`,
|
90
|
+
});
|
90
91
|
logger.debug(e);
|
91
92
|
}
|
92
93
|
}
|
93
94
|
return totalFound;
|
94
95
|
}
|
95
96
|
export async function searchForLocalTorrentByCriteria(criteria) {
|
96
|
-
const { maxDataDepth } = getRuntimeConfig();
|
97
|
-
let
|
97
|
+
const { delay, maxDataDepth } = getRuntimeConfig();
|
98
|
+
let rawSearchees;
|
98
99
|
if (criteria.path) {
|
99
100
|
const searcheeResults = await Promise.all(findPotentialNestedRoots(criteria.path, maxDataDepth).map(createSearcheeFromPath));
|
100
|
-
|
101
|
+
rawSearchees = searcheeResults.filter(isOk).map((t) => t.unwrap());
|
101
102
|
}
|
102
103
|
else {
|
103
|
-
|
104
|
+
rawSearchees = [await getTorrentByCriteria(criteria)];
|
104
105
|
}
|
106
|
+
const searchees = rawSearchees.map((searchee) => ({
|
107
|
+
...searchee,
|
108
|
+
label: Label.WEBHOOK,
|
109
|
+
}));
|
105
110
|
const hashesToExclude = await getInfoHashesToExclude();
|
106
|
-
let
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
const
|
111
|
-
|
112
|
-
|
113
|
-
|
111
|
+
let totalFound = 0;
|
112
|
+
let filtered = 0;
|
113
|
+
const cachedSearch = { q: null, indexerCandidates: [] };
|
114
|
+
for (const [i, searchee] of searchees.entries()) {
|
115
|
+
const progress = chalk.blue(`(${i + 1}/${searchees.length}) `);
|
116
|
+
try {
|
117
|
+
if (!filterByContent(searchee)) {
|
118
|
+
filtered++;
|
119
|
+
continue;
|
120
|
+
}
|
121
|
+
const sleep = wait(delay * 1000);
|
122
|
+
const { matches, searchedIndexers } = await findOnOtherSites(searchee, hashesToExclude, cachedSearch, progress);
|
123
|
+
totalFound += matches;
|
124
|
+
// if all indexers were rate limited, don't sleep
|
125
|
+
if (searchedIndexers === 0 || i === searchees.length - 1)
|
126
|
+
continue;
|
127
|
+
await sleep;
|
128
|
+
}
|
129
|
+
catch (e) {
|
130
|
+
const searcheeLog = getLogString(searchee, chalk.bold.white);
|
131
|
+
logger.error({
|
132
|
+
label: searchee.label,
|
133
|
+
message: `${progress}Error searching for ${searcheeLog}`,
|
134
|
+
});
|
135
|
+
logger.debug(e);
|
136
|
+
}
|
137
|
+
}
|
138
|
+
if (filtered === searchees.length)
|
139
|
+
return null;
|
140
|
+
return totalFound;
|
114
141
|
}
|
115
|
-
export async function checkNewCandidateMatch(candidate) {
|
116
|
-
const
|
117
|
-
|
142
|
+
export async function checkNewCandidateMatch(candidate, searcheeLabel) {
|
143
|
+
const candidateLog = `${candidate.name} from ${candidate.tracker}`;
|
144
|
+
const { keys, metas } = await getSimilarTorrentsByName(candidate.name);
|
145
|
+
const method = keys.length ? `[${keys}]` : "Fuse fallback";
|
146
|
+
if (!metas.length) {
|
118
147
|
logger.verbose({
|
119
|
-
label:
|
120
|
-
message: `Did not find an existing entry for ${
|
148
|
+
label: searcheeLabel,
|
149
|
+
message: `Did not find an existing entry using ${method} for ${candidateLog}`,
|
121
150
|
});
|
122
151
|
return null;
|
123
152
|
}
|
124
|
-
const
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
const assessment = await assessCandidate(candidate, searchee, hashesToExclude);
|
134
|
-
if (assessment.decision !== Decision.MATCH &&
|
135
|
-
assessment.decision !== Decision.MATCH_SIZE_ONLY &&
|
136
|
-
assessment.decision !== Decision.MATCH_PARTIAL) {
|
153
|
+
const searchees = filterDupesFromSimilar(metas
|
154
|
+
.map(createSearcheeFromMetafile)
|
155
|
+
.map((searchee) => ({ ...searchee, label: searcheeLabel }))
|
156
|
+
.filter(filterByContent));
|
157
|
+
if (!searchees.length) {
|
158
|
+
logger.verbose({
|
159
|
+
label: searcheeLabel,
|
160
|
+
message: `No valid entries found using ${method} for ${candidateLog}`,
|
161
|
+
});
|
137
162
|
return null;
|
138
163
|
}
|
139
|
-
|
140
|
-
|
164
|
+
logger.verbose({
|
165
|
+
label: searcheeLabel,
|
166
|
+
message: `Unique entries [${searchees.map((m) => m.name)}] using ${method} for ${candidateLog}`,
|
167
|
+
});
|
168
|
+
const hashesToExclude = await getInfoHashesToExclude();
|
169
|
+
let result = null;
|
170
|
+
searchees.sort((a, b) => b.files.length - a.files.length);
|
171
|
+
for (const searchee of searchees) {
|
172
|
+
await db("searchee")
|
173
|
+
.insert({ name: searchee.name })
|
174
|
+
.onConflict("name")
|
175
|
+
.ignore();
|
176
|
+
const assessment = await assessCandidate(candidate, searchee, hashesToExclude);
|
177
|
+
if (!isAnyMatchedDecision(assessment.decision)) {
|
178
|
+
continue;
|
179
|
+
}
|
180
|
+
result = await performAction(assessment.metafile, assessment.decision, searchee, candidate.tracker);
|
181
|
+
sendResultsNotification(searchee, [
|
182
|
+
[assessment, candidate.tracker, result],
|
183
|
+
]);
|
184
|
+
if (result === SaveResult.SAVED ||
|
185
|
+
result === InjectionResult.SUCCESS ||
|
186
|
+
result === InjectionResult.ALREADY_EXISTS) {
|
187
|
+
break;
|
188
|
+
}
|
189
|
+
}
|
141
190
|
return result;
|
142
191
|
}
|
143
|
-
async function findSearchableTorrents() {
|
192
|
+
async function findSearchableTorrents(searcheeLabel) {
|
144
193
|
const { torrents, dataDirs, torrentDir, searchLimit } = getRuntimeConfig();
|
145
|
-
|
194
|
+
const rawSearchees = [];
|
146
195
|
if (Array.isArray(torrents)) {
|
147
196
|
const searcheeResults = await Promise.all(torrents.map(createSearcheeFromTorrentFile));
|
148
|
-
|
149
|
-
.filter((t) => t.isOk())
|
150
|
-
.map((t) => t.unwrapOrThrow());
|
197
|
+
rawSearchees.push(...searcheeResults.filter(isOk).map((r) => r.unwrap()));
|
151
198
|
}
|
152
199
|
else {
|
153
200
|
if (typeof torrentDir === "string") {
|
154
|
-
|
201
|
+
rawSearchees.push(...(await loadTorrentDirLight(torrentDir)));
|
155
202
|
}
|
156
203
|
if (Array.isArray(dataDirs)) {
|
157
204
|
const searcheeResults = await Promise.all(findSearcheesFromAllDataDirs().map(createSearcheeFromPath));
|
158
|
-
|
159
|
-
.filter((t) => t.isOk())
|
160
|
-
.map((t) => t.unwrapOrThrow()));
|
205
|
+
rawSearchees.push(...searcheeResults.filter(isOk).map((r) => r.unwrap()));
|
161
206
|
}
|
162
207
|
}
|
208
|
+
const allSearchees = rawSearchees.map((searchee) => ({
|
209
|
+
...searchee,
|
210
|
+
label: searcheeLabel,
|
211
|
+
}));
|
163
212
|
const hashesToExclude = allSearchees
|
164
213
|
.map((t) => t.infoHash)
|
165
214
|
.filter(isTruthy);
|
166
|
-
|
215
|
+
// Group the exact same search queries together for easy cache use later
|
216
|
+
const grouping = new Map();
|
217
|
+
for (const searchee of allSearchees.filter(filterByContent)) {
|
218
|
+
const key = await getSearchString(searchee);
|
219
|
+
if (!grouping.has(key)) {
|
220
|
+
grouping.set(key, []);
|
221
|
+
}
|
222
|
+
grouping.get(key).push(searchee);
|
223
|
+
}
|
224
|
+
const keysToDelete = [];
|
225
|
+
for (const [key, groupedSearchees] of grouping) {
|
226
|
+
// If one searchee needs to be searched, use the candidates for all
|
227
|
+
const searchees = filterDupesFromSimilar(groupedSearchees);
|
228
|
+
const results = await Promise.all(searchees.map(filterTimestamps));
|
229
|
+
if (!results.some(isTruthy)) {
|
230
|
+
keysToDelete.push(key);
|
231
|
+
continue;
|
232
|
+
}
|
233
|
+
// Prefer infoHash
|
234
|
+
searchees.sort((a, b) => {
|
235
|
+
if (a.infoHash && !b.infoHash)
|
236
|
+
return -1;
|
237
|
+
if (!a.infoHash && b.infoHash)
|
238
|
+
return 1;
|
239
|
+
return 0;
|
240
|
+
});
|
241
|
+
// Sort by most number files (less chance of partial)
|
242
|
+
searchees.sort((a, b) => {
|
243
|
+
return b.files.length - a.files.length;
|
244
|
+
});
|
245
|
+
grouping.set(key, searchees);
|
246
|
+
}
|
247
|
+
for (const key of keysToDelete) {
|
248
|
+
grouping.delete(key);
|
249
|
+
}
|
250
|
+
let finalSearchees = Array.from(grouping.values()).flat();
|
167
251
|
logger.info({
|
168
252
|
label: Label.SEARCH,
|
169
|
-
message: `Found ${allSearchees.length} torrents, ${
|
253
|
+
message: `Found ${allSearchees.length} torrents, ${finalSearchees.length} suitable to search for matches using ${grouping.size} unique queries`,
|
170
254
|
});
|
171
|
-
if (searchLimit &&
|
255
|
+
if (searchLimit && finalSearchees.length > searchLimit) {
|
172
256
|
logger.info({
|
173
257
|
label: Label.SEARCH,
|
174
258
|
message: `Limited to ${searchLimit} searches`,
|
175
259
|
});
|
176
|
-
|
260
|
+
finalSearchees = finalSearchees.slice(0, searchLimit);
|
177
261
|
}
|
178
|
-
return {
|
262
|
+
return { searchees: finalSearchees, hashesToExclude };
|
179
263
|
}
|
180
264
|
export async function main() {
|
181
265
|
const { outputDir, linkDir } = getRuntimeConfig();
|
182
|
-
const {
|
266
|
+
const { searchees, hashesToExclude } = await findSearchableTorrents(Label.SEARCH);
|
183
267
|
if (!fs.existsSync(outputDir)) {
|
184
268
|
fs.mkdirSync(outputDir, { recursive: true });
|
185
269
|
}
|
186
270
|
if (linkDir && !fs.existsSync(linkDir)) {
|
187
271
|
fs.mkdirSync(linkDir, { recursive: true });
|
188
272
|
}
|
189
|
-
const totalFound = await findMatchesBatch(
|
273
|
+
const totalFound = await findMatchesBatch(searchees, hashesToExclude);
|
190
274
|
logger.info({
|
191
275
|
label: Label.SEARCH,
|
192
|
-
message: chalk.cyan(`Found ${chalk.bold.white(totalFound)} cross seeds from ${chalk.bold.white(
|
276
|
+
message: chalk.cyan(`Found ${chalk.bold.white(totalFound)} cross seeds from ${chalk.bold.white(searchees.length)} original torrents`),
|
193
277
|
});
|
194
278
|
}
|
195
279
|
export async function scanRssFeeds() {
|
@@ -215,7 +299,7 @@ export async function scanRssFeeds() {
|
|
215
299
|
label: Label.RSS,
|
216
300
|
message: `Processing release ${i + 1}/${candidatesSinceLastTime.length}`,
|
217
301
|
});
|
218
|
-
await checkNewCandidateMatch(candidate);
|
302
|
+
await checkNewCandidateMatch(candidate, Label.RSS);
|
219
303
|
}
|
220
304
|
logger.info({ label: Label.RSS, message: "Scan complete" });
|
221
305
|
}
|
package/dist/pipeline.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"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"}
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"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"}
|
package/dist/preFilter.js
CHANGED
@@ -1,43 +1,56 @@
|
|
1
1
|
import ms from "ms";
|
2
|
-
import { extname } from "path";
|
3
|
-
import {
|
2
|
+
import { extname, basename, dirname } from "path";
|
3
|
+
import { statSync } from "fs";
|
4
|
+
import { ARR_DIR_REGEX, EP_REGEX, SONARR_SUBFOLDERS_REGEX, SEASON_REGEX, VIDEO_EXTENSIONS, } from "./constants.js";
|
4
5
|
import { db } from "./db.js";
|
5
6
|
import { getEnabledIndexers } from "./indexers.js";
|
6
7
|
import { Label, logger } from "./logger.js";
|
7
8
|
import { getRuntimeConfig } from "./runtimeConfig.js";
|
8
|
-
import {
|
9
|
-
import
|
9
|
+
import { indexerDoesSupportMediaType } from "./torznab.js";
|
10
|
+
import { getLogString, getMediaType, humanReadableDate, nMsAgo, } from "./utils.js";
|
11
|
+
import chalk from "chalk";
|
12
|
+
function logReason(reason, searchee) {
|
13
|
+
logger.verbose({
|
14
|
+
label: Label.PREFILTER,
|
15
|
+
message: `${getLogString(searchee, chalk.reset)} was not selected for searching because ${reason}`,
|
16
|
+
});
|
17
|
+
}
|
10
18
|
export function filterByContent(searchee) {
|
11
|
-
const {
|
12
|
-
function logReason(reason) {
|
13
|
-
logger.verbose({
|
14
|
-
label: Label.PREFILTER,
|
15
|
-
message: `Torrent ${searchee.name} was not selected for searching because ${reason}`,
|
16
|
-
});
|
17
|
-
}
|
19
|
+
const { fuzzySizeThreshold, includeNonVideos, includeSingleEpisodes, blockList, } = getRuntimeConfig();
|
18
20
|
const blockedNote = findBlockedStringInReleaseMaybe(searchee, blockList);
|
19
21
|
if (blockedNote) {
|
20
|
-
logReason(`it matched the blocklist - ("${blockedNote}")
|
22
|
+
logReason(`it matched the blocklist - ("${blockedNote}")`, searchee);
|
21
23
|
return false;
|
22
24
|
}
|
23
|
-
|
24
|
-
const isSeasonPackEpisode = searchee.path &&
|
25
|
+
if (searchee.path &&
|
25
26
|
searchee.files.length === 1 &&
|
26
|
-
SEASON_REGEX.test(
|
27
|
-
|
28
|
-
|
29
|
-
isSingleEpisodeTorrent &&
|
30
|
-
!isSeasonPackEpisode) {
|
31
|
-
logReason("it is a single episode");
|
27
|
+
(SEASON_REGEX.test(basename(dirname(searchee.path))) ||
|
28
|
+
SONARR_SUBFOLDERS_REGEX.test(basename(dirname(searchee.path))))) {
|
29
|
+
logReason("it is a season pack episode", searchee);
|
32
30
|
return false;
|
33
31
|
}
|
34
|
-
if (!
|
35
|
-
|
32
|
+
if (!includeSingleEpisodes &&
|
33
|
+
![Label.ANNOUNCE, Label.RSS].includes(searchee.label) &&
|
34
|
+
EP_REGEX.test(searchee.name)) {
|
35
|
+
logReason("it is a single episode", searchee);
|
36
36
|
return false;
|
37
37
|
}
|
38
|
-
const
|
39
|
-
|
40
|
-
|
38
|
+
const nonVideoSizeRatio = searchee.files.reduce((acc, cur) => {
|
39
|
+
if (!VIDEO_EXTENSIONS.includes(extname(cur.name))) {
|
40
|
+
return acc + cur.length;
|
41
|
+
}
|
42
|
+
return acc;
|
43
|
+
}, 0) / searchee.length;
|
44
|
+
if (!includeNonVideos && nonVideoSizeRatio > fuzzySizeThreshold) {
|
45
|
+
logReason(`nonVideoSizeRatio ${nonVideoSizeRatio} > ${fuzzySizeThreshold} fuzzySizeThreshold`, searchee);
|
46
|
+
return false;
|
47
|
+
}
|
48
|
+
if (searchee.path &&
|
49
|
+
statSync(searchee.path).isDirectory() &&
|
50
|
+
ARR_DIR_REGEX.test(basename(searchee.path)) &&
|
51
|
+
!(searchee.files.length > 1 &&
|
52
|
+
SONARR_SUBFOLDERS_REGEX.test(basename(searchee.path)))) {
|
53
|
+
logReason("it looks like an arr movie/series directory", searchee);
|
41
54
|
return false;
|
42
55
|
}
|
43
56
|
return true;
|
@@ -48,13 +61,27 @@ export function findBlockedStringInReleaseMaybe(searchee, blockList) {
|
|
48
61
|
blockedStr === searchee.infoHash);
|
49
62
|
});
|
50
63
|
}
|
51
|
-
|
64
|
+
/**
|
65
|
+
* Filters duplicates from searchees that should be for different candidates,
|
66
|
+
* e.g. all searchees created by cross-seed.
|
67
|
+
* @param searchees - An array of searchees to filter duplicates from.
|
68
|
+
* @returns An array of searchees with duplicates removed, preferring infoHash.
|
69
|
+
*/
|
70
|
+
export function filterDupesByName(searchees) {
|
52
71
|
const duplicateMap = searchees.reduce((acc, cur) => {
|
53
72
|
const entry = acc.get(cur.name);
|
54
73
|
if (entry === undefined) {
|
55
74
|
acc.set(cur.name, cur);
|
75
|
+
return acc;
|
56
76
|
}
|
57
|
-
|
77
|
+
if (cur.files.length > entry.files.length) {
|
78
|
+
acc.set(cur.name, cur);
|
79
|
+
return acc;
|
80
|
+
}
|
81
|
+
if (cur.files.length < entry.files.length) {
|
82
|
+
return acc;
|
83
|
+
}
|
84
|
+
if (cur.infoHash && !entry.infoHash) {
|
58
85
|
acc.set(cur.name, cur);
|
59
86
|
}
|
60
87
|
return acc;
|
@@ -69,9 +96,39 @@ export function filterDupes(searchees) {
|
|
69
96
|
}
|
70
97
|
return filtered;
|
71
98
|
}
|
99
|
+
/**
|
100
|
+
* Filters duplicates from searchees that are for the same candidates,
|
101
|
+
* e.g. searchees for the same media but different resolutions.
|
102
|
+
* @param searchees - An array of searchees for a specific media.
|
103
|
+
* @returns An array of searchees that are unique from a matching perspective.
|
104
|
+
*/
|
105
|
+
export function filterDupesFromSimilar(searchees) {
|
106
|
+
const filteredSearchees = [];
|
107
|
+
for (const searchee of searchees) {
|
108
|
+
const isDupe = filteredSearchees.some((s) => {
|
109
|
+
if (searchee.length !== s.length)
|
110
|
+
return false;
|
111
|
+
if (searchee.files.length !== s.files.length)
|
112
|
+
return false;
|
113
|
+
const potentialFiles = s.files.map((f) => f.length);
|
114
|
+
return searchee.files.every((file) => {
|
115
|
+
const index = potentialFiles.indexOf(file.length);
|
116
|
+
if (index === -1)
|
117
|
+
return false;
|
118
|
+
potentialFiles.splice(index, 1);
|
119
|
+
return true;
|
120
|
+
});
|
121
|
+
});
|
122
|
+
if (!isDupe) {
|
123
|
+
filteredSearchees.push(searchee);
|
124
|
+
}
|
125
|
+
}
|
126
|
+
return filteredSearchees;
|
127
|
+
}
|
72
128
|
export async function filterTimestamps(searchee) {
|
73
129
|
const { excludeOlder, excludeRecentSearch } = getRuntimeConfig();
|
74
130
|
const enabledIndexers = await getEnabledIndexers();
|
131
|
+
const mediaType = getMediaType(searchee);
|
75
132
|
const timestampDataSql = (await db("searchee")
|
76
133
|
// @ts-expect-error crossJoin supports string
|
77
134
|
.crossJoin("indexer")
|
@@ -80,7 +137,9 @@ export async function filterTimestamps(searchee) {
|
|
80
137
|
"timestamp.searchee_id": "searchee.id",
|
81
138
|
})
|
82
139
|
.where("searchee.name", searchee.name)
|
83
|
-
.whereIn("indexer.id", enabledIndexers
|
140
|
+
.whereIn("indexer.id", enabledIndexers
|
141
|
+
.filter((indexer) => indexerDoesSupportMediaType(mediaType, JSON.parse(indexer.categories)))
|
142
|
+
.map((indexer) => indexer.id))
|
84
143
|
.min({
|
85
144
|
first_searched_any: db.raw("coalesce(timestamp.first_searched, 9223372036854775807)"),
|
86
145
|
})
|
@@ -89,22 +148,16 @@ export async function filterTimestamps(searchee) {
|
|
89
148
|
})
|
90
149
|
.first());
|
91
150
|
const { first_searched_any, last_searched_all } = timestampDataSql;
|
92
|
-
function logReason(reason) {
|
93
|
-
logger.verbose({
|
94
|
-
label: Label.PREFILTER,
|
95
|
-
message: `Torrent ${searchee.name} was not selected for searching because ${reason}`,
|
96
|
-
});
|
97
|
-
}
|
98
151
|
if (typeof excludeOlder === "number" &&
|
99
152
|
first_searched_any &&
|
100
153
|
first_searched_any < nMsAgo(excludeOlder)) {
|
101
|
-
logReason(`its first search timestamp ${humanReadableDate(first_searched_any)} is older than ${ms(excludeOlder, { long: true })} ago
|
154
|
+
logReason(`its first search timestamp ${humanReadableDate(first_searched_any)} is older than ${ms(excludeOlder, { long: true })} ago`, searchee);
|
102
155
|
return false;
|
103
156
|
}
|
104
157
|
if (typeof excludeRecentSearch === "number" &&
|
105
158
|
last_searched_all &&
|
106
159
|
last_searched_all > nMsAgo(excludeRecentSearch)) {
|
107
|
-
logReason(`its last search timestamp ${humanReadableDate(last_searched_all)} is newer than ${ms(excludeRecentSearch, { long: true })} ago
|
160
|
+
logReason(`its last search timestamp ${humanReadableDate(last_searched_all)} is newer than ${ms(excludeRecentSearch, { long: true })} ago`, searchee);
|
108
161
|
return false;
|
109
162
|
}
|
110
163
|
return true;
|