cross-seed 3.4.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -5
- package/dist/cache.js +13 -0
- package/dist/cache.js.map +1 -0
- package/dist/cmd.js +35 -22
- package/dist/cmd.js.map +1 -1
- package/dist/config.template.cjs +35 -20
- package/dist/config.template.cjs.map +1 -1
- package/dist/config.template.docker.cjs +39 -23
- package/dist/config.template.docker.cjs.map +1 -1
- package/dist/configuration.js.map +1 -1
- package/dist/db.js +11 -28
- package/dist/db.js.map +1 -1
- package/dist/decide.js +37 -21
- package/dist/decide.js.map +1 -1
- package/dist/errors.js +8 -0
- package/dist/errors.js.map +1 -1
- package/dist/jobs.js +73 -0
- package/dist/jobs.js.map +1 -0
- package/dist/logger.js +6 -2
- package/dist/logger.js.map +1 -1
- package/dist/migrations/00-initialSchema.js +74 -0
- package/dist/migrations/00-initialSchema.js.map +1 -0
- package/dist/migrations/01-jobs.js +17 -0
- package/dist/migrations/01-jobs.js.map +1 -0
- package/dist/migrations/migrations.js +9 -0
- package/dist/migrations/migrations.js.map +1 -0
- package/dist/pipeline.js +85 -59
- package/dist/pipeline.js.map +1 -1
- package/dist/preFilter.js +20 -18
- package/dist/preFilter.js.map +1 -1
- package/dist/runtimeConfig.js +0 -1
- package/dist/runtimeConfig.js.map +1 -1
- package/dist/server.js +5 -4
- package/dist/server.js.map +1 -1
- package/dist/signalHandlers.js +7 -2
- package/dist/signalHandlers.js.map +1 -1
- package/dist/startup.js +0 -2
- package/dist/startup.js.map +1 -1
- package/dist/torrent.js +41 -18
- package/dist/torrent.js.map +1 -1
- package/dist/torznab.js +2 -2
- package/dist/torznab.js.map +1 -1
- package/dist/utils.js +16 -4
- package/dist/utils.js.map +1 -1
- package/package.json +5 -3
- package/dist/jackett.js +0 -64
- package/dist/jackett.js.map +0 -1
package/dist/errors.js
CHANGED
@@ -8,4 +8,12 @@ export class CrossSeedError extends Error {
|
|
8
8
|
logger.error(this.message);
|
9
9
|
}
|
10
10
|
}
|
11
|
+
export function exitOnCrossSeedErrors(e) {
|
12
|
+
if (e instanceof CrossSeedError) {
|
13
|
+
e.print();
|
14
|
+
process.exitCode = 1;
|
15
|
+
return;
|
16
|
+
}
|
17
|
+
throw e;
|
18
|
+
}
|
11
19
|
//# sourceMappingURL=errors.js.map
|
package/dist/errors.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,OAAO,cAAe,SAAQ,KAAK;IACxC,YAAY,OAAe;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,OAAO,IAAI,CAAC,KAAK,CAAC;IACnB,CAAC;IAED,KAAK;QACJ,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;CACD"}
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,OAAO,cAAe,SAAQ,KAAK;IACxC,YAAY,OAAe;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,OAAO,IAAI,CAAC,KAAK,CAAC;IACnB,CAAC;IAED,KAAK;QACJ,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;CACD;AAED,MAAM,UAAU,qBAAqB,CAAC,CAAC;IACtC,IAAI,CAAC,YAAY,cAAc,EAAE;QAChC,CAAC,CAAC,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;KACP;IACD,MAAM,CAAC,CAAC;AACT,CAAC"}
|
package/dist/jobs.js
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
import ms from "ms";
|
2
|
+
import { db } from "./db.js";
|
3
|
+
import { main, scanRssFeeds } from "./pipeline.js";
|
4
|
+
import { exitOnCrossSeedErrors } from "./errors.js";
|
5
|
+
import { Label, logger } from "./logger.js";
|
6
|
+
import { getRuntimeConfig } from "./runtimeConfig.js";
|
7
|
+
class Job {
|
8
|
+
constructor(name, cadence, exec) {
|
9
|
+
this.name = name;
|
10
|
+
this.cadence = cadence;
|
11
|
+
this.exec = exec;
|
12
|
+
this.isActive = false;
|
13
|
+
}
|
14
|
+
async run() {
|
15
|
+
if (!this.isActive) {
|
16
|
+
this.isActive = true;
|
17
|
+
try {
|
18
|
+
logger.info({
|
19
|
+
label: Label.SCHEDULER,
|
20
|
+
message: `starting job: ${this.name}`,
|
21
|
+
});
|
22
|
+
await this.exec();
|
23
|
+
}
|
24
|
+
finally {
|
25
|
+
this.isActive = false;
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
const getJobs = () => {
|
31
|
+
const { rssCadence, searchCadence } = getRuntimeConfig();
|
32
|
+
return [
|
33
|
+
rssCadence && new Job("rss", rssCadence, scanRssFeeds),
|
34
|
+
searchCadence && new Job("search", searchCadence, main),
|
35
|
+
].filter(Boolean);
|
36
|
+
};
|
37
|
+
export async function jobsLoop() {
|
38
|
+
const jobs = getJobs();
|
39
|
+
async function loop() {
|
40
|
+
var _a;
|
41
|
+
const now = Date.now();
|
42
|
+
for (const job of jobs) {
|
43
|
+
const lastRun = (_a = (await db("job_log")
|
44
|
+
.select("last_run")
|
45
|
+
.where({ name: job.name })
|
46
|
+
.first())) === null || _a === void 0 ? void 0 : _a.last_run;
|
47
|
+
// if it's never been run, you are eligible immediately
|
48
|
+
const eligibilityTs = lastRun ? lastRun + job.cadence : now;
|
49
|
+
const lastRunStr = lastRun ? `${ms(now - lastRun)} ago` : "never";
|
50
|
+
const nextRunStr = ms(eligibilityTs - now);
|
51
|
+
logger.verbose({
|
52
|
+
label: Label.SCHEDULER,
|
53
|
+
message: `${job.name}: last run ${lastRunStr}, next run in ${nextRunStr}`,
|
54
|
+
});
|
55
|
+
if (now >= eligibilityTs) {
|
56
|
+
job.run()
|
57
|
+
.then(async () => {
|
58
|
+
// upon success, update the log
|
59
|
+
await db("job_log")
|
60
|
+
.insert({ name: job.name, last_run: now })
|
61
|
+
.onConflict("name")
|
62
|
+
.merge();
|
63
|
+
})
|
64
|
+
.catch(exitOnCrossSeedErrors)
|
65
|
+
.catch((e) => void logger.error(e));
|
66
|
+
}
|
67
|
+
}
|
68
|
+
}
|
69
|
+
const interval = setInterval(loop, ms("1 minute"));
|
70
|
+
loop();
|
71
|
+
return () => clearInterval(interval);
|
72
|
+
}
|
73
|
+
//# sourceMappingURL=jobs.js.map
|
package/dist/jobs.js.map
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"jobs.js","sourceRoot":"","sources":["../src/jobs.ts"],"names":[],"mappings":"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"}
|
package/dist/logger.js
CHANGED
@@ -10,10 +10,14 @@ export var Label;
|
|
10
10
|
Label["DECIDE"] = "decide";
|
11
11
|
Label["PREFILTER"] = "prefilter";
|
12
12
|
Label["CONFIGDUMP"] = "configdump";
|
13
|
-
Label["JACKETT"] = "jackett";
|
14
13
|
Label["TORZNAB"] = "torznab";
|
15
14
|
Label["SERVER"] = "server";
|
16
15
|
Label["STARTUP"] = "startup";
|
16
|
+
Label["SCHEDULER"] = "scheduler";
|
17
|
+
Label["SEARCH"] = "search";
|
18
|
+
Label["RSS"] = "rss";
|
19
|
+
Label["PERF"] = "perf";
|
20
|
+
Label["REVERSE_LOOKUP"] = "reverselookup";
|
17
21
|
})(Label = Label || (Label = {}));
|
18
22
|
export let logger;
|
19
23
|
const redactionMsg = "[REDACTED]";
|
@@ -36,7 +40,7 @@ function redactUrlPassword(message, urlStr) {
|
|
36
40
|
}
|
37
41
|
function redactMessage(message) {
|
38
42
|
const runtimeConfig = getRuntimeConfig();
|
39
|
-
|
43
|
+
// redact torznab api keys
|
40
44
|
message = message.replace(/apikey=[a-zA-Z0-9]+/g, `apikey=${redactionMsg}`);
|
41
45
|
for (const [key, urlStr] of Object.entries(runtimeConfig)) {
|
42
46
|
if (key.endsWith("Url") && urlStr) {
|
package/dist/logger.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,eAAe,MAAM,2BAA2B,CAAC;AAExD,MAAM,CAAN,IAAY,
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,74 @@
|
|
1
|
+
import { getCacheFileData, renameCacheFile } from "../cache.js";
|
2
|
+
async function up(knex) {
|
3
|
+
await knex.schema.createTable("searchee", (table) => {
|
4
|
+
table.increments("id").primary();
|
5
|
+
table.string("name").unique();
|
6
|
+
table.integer("first_searched");
|
7
|
+
table.integer("last_searched");
|
8
|
+
});
|
9
|
+
await knex.schema.createTable("decision", (table) => {
|
10
|
+
table.increments("id").primary();
|
11
|
+
table.integer("searchee_id").references("id").inTable("searchee");
|
12
|
+
table.string("guid");
|
13
|
+
table.string("info_hash");
|
14
|
+
table.string("decision");
|
15
|
+
table.integer("first_seen");
|
16
|
+
table.integer("last_seen");
|
17
|
+
});
|
18
|
+
await knex.schema.createTable("torrent", (table) => {
|
19
|
+
table.increments("id").primary();
|
20
|
+
table.string("info_hash");
|
21
|
+
table.string("name");
|
22
|
+
table.string("file_path").unique();
|
23
|
+
});
|
24
|
+
const cacheData = await getCacheFileData();
|
25
|
+
if (!cacheData)
|
26
|
+
return;
|
27
|
+
await knex.transaction(async (trx) => {
|
28
|
+
const chunkSize = 100;
|
29
|
+
const searcheeRows = Object.entries(cacheData.searchees).map(([name, { firstSearched, lastSearched }]) => ({
|
30
|
+
name,
|
31
|
+
first_searched: firstSearched,
|
32
|
+
last_searched: lastSearched,
|
33
|
+
}));
|
34
|
+
await trx.batchInsert("searchee", searcheeRows, chunkSize);
|
35
|
+
const dbSearchees = await trx.select("*").from("searchee");
|
36
|
+
const normalizedDecisions = Object.entries(cacheData.decisions).flatMap(([searcheeName, results]) => Object.entries(results).flatMap(([guid, decisionEntry]) => {
|
37
|
+
// searchee may not exist if cache contains decisions
|
38
|
+
// from early versions of the cache
|
39
|
+
const searchee = dbSearchees.find((searchee) => searchee.name === searcheeName);
|
40
|
+
return searchee
|
41
|
+
? [
|
42
|
+
{
|
43
|
+
searchee_id: searchee.id,
|
44
|
+
guid,
|
45
|
+
decision: decisionEntry.decision,
|
46
|
+
last_seen: decisionEntry.lastSeen,
|
47
|
+
first_seen: decisionEntry.firstSeen,
|
48
|
+
info_hash: decisionEntry.infoHash,
|
49
|
+
},
|
50
|
+
]
|
51
|
+
: [];
|
52
|
+
}));
|
53
|
+
const torrentRows = cacheData.indexedTorrents.map((e) => ({
|
54
|
+
info_hash: e.infoHash,
|
55
|
+
name: e.name,
|
56
|
+
file_path: e.filepath,
|
57
|
+
}));
|
58
|
+
await trx.batchInsert("decision", normalizedDecisions, chunkSize);
|
59
|
+
await trx.batchInsert("torrent", torrentRows, chunkSize);
|
60
|
+
});
|
61
|
+
await renameCacheFile();
|
62
|
+
}
|
63
|
+
async function down(knex) {
|
64
|
+
await knex.schema.dropTable("searchee");
|
65
|
+
await knex.schema.dropTable("decision");
|
66
|
+
await knex.schema.dropTable("torrent");
|
67
|
+
}
|
68
|
+
export default {
|
69
|
+
name: "00-initialSchema",
|
70
|
+
up,
|
71
|
+
down,
|
72
|
+
config: { transaction: true },
|
73
|
+
};
|
74
|
+
//# sourceMappingURL=00-initialSchema.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"00-initialSchema.js","sourceRoot":"","sources":["../../src/migrations/00-initialSchema.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import { join } from "path";
|
2
|
+
import { appDir } from "../configuration.js";
|
3
|
+
async function up(knex) {
|
4
|
+
const connection = await knex.client.acquireConnection();
|
5
|
+
await connection.backup(join(appDir(), "cross-seed.pre-jobs.backup.db"));
|
6
|
+
await knex.client.releaseConnection(connection);
|
7
|
+
await knex.schema.createTable("job_log", (table) => {
|
8
|
+
table.increments("id").primary();
|
9
|
+
table.string("name").unique();
|
10
|
+
table.integer("last_run");
|
11
|
+
});
|
12
|
+
}
|
13
|
+
async function down(knex) {
|
14
|
+
await knex.schema.dropTable("job_log");
|
15
|
+
}
|
16
|
+
export default { name: "01-jobs", up, down };
|
17
|
+
//# sourceMappingURL=01-jobs.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"01-jobs.js","sourceRoot":"","sources":["../../src/migrations/01-jobs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,KAAK,UAAU,EAAE,CAAC,IAAe;IAChC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;IACzD,MAAM,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,+BAA+B,CAAC,CAAC,CAAC;IACzE,MAAM,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAEhD,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;QAClD,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QACjC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;QAC9B,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,IAAI,CAAC,IAAe;IAClC,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;AACxC,CAAC;AAED,eAAe,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC"}
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import initialSchema from "./00-initialSchema.js";
|
2
|
+
import jobs from "./01-jobs.js";
|
3
|
+
// The first step of any migration should be to back up the database.
|
4
|
+
export const migrations = {
|
5
|
+
getMigrations: () => Promise.resolve([initialSchema, jobs]),
|
6
|
+
getMigrationName: (migration) => migration.name,
|
7
|
+
getMigration: (migration) => migration,
|
8
|
+
};
|
9
|
+
//# sourceMappingURL=migrations.js.map
|
@@ -0,0 +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;AAEhC,qEAAqE;AAErE,MAAM,CAAC,MAAM,UAAU,GAAG;IACzB,aAAa,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IAC3D,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
@@ -2,24 +2,23 @@ import chalk from "chalk";
|
|
2
2
|
import fs from "fs";
|
3
3
|
import { getClient } from "./clients/TorrentClient.js";
|
4
4
|
import { Action, Decision, InjectionResult } from "./constants.js";
|
5
|
-
import db from "./db.js";
|
6
5
|
import { assessCandidate } from "./decide.js";
|
7
|
-
import { searchJackett } from "./jackett.js";
|
8
6
|
import { Label, logger } from "./logger.js";
|
9
7
|
import { filterByContent, filterDupes, filterTimestamps } from "./preFilter.js";
|
10
8
|
import { pushNotifier } from "./pushNotifier.js";
|
11
9
|
import { EmptyNonceOptions, getRuntimeConfig, } from "./runtimeConfig.js";
|
12
10
|
import { createSearcheeFromMetafile, createSearcheeFromTorrentFile, } from "./searchee.js";
|
13
|
-
import {
|
11
|
+
import { db } from "./db.js";
|
12
|
+
import { getInfoHashesToExclude, getTorrentByCriteria, indexNewTorrents, loadTorrentDirLight, saveTorrentFile, } from "./torrent.js";
|
14
13
|
import { getTorznabManager } from "./torznab.js";
|
15
|
-
import { getTag, ok, stripExtension } from "./utils.js";
|
16
|
-
async function performAction(
|
14
|
+
import { filterAsync, getTag, ok, stripExtension } from "./utils.js";
|
15
|
+
async function performAction(newMeta, searchee, tracker, nonceOptions, tag) {
|
17
16
|
const { action } = getRuntimeConfig();
|
18
17
|
let isTorrentIncomplete;
|
19
|
-
const styledName = chalk.green.bold(
|
18
|
+
const styledName = chalk.green.bold(newMeta.name);
|
20
19
|
const styledTracker = chalk.bold(tracker);
|
21
20
|
if (action === Action.INJECT) {
|
22
|
-
const result = await getClient().inject(
|
21
|
+
const result = await getClient().inject(newMeta, searchee, nonceOptions);
|
23
22
|
switch (result) {
|
24
23
|
case InjectionResult.SUCCESS:
|
25
24
|
logger.info(`Found ${styledName} on ${styledTracker} - injected`);
|
@@ -34,22 +33,16 @@ async function performAction(meta, searchee, tracker, nonceOptions, tag) {
|
|
34
33
|
case InjectionResult.FAILURE:
|
35
34
|
default:
|
36
35
|
logger.error(`Found ${styledName} on ${styledTracker} - failed to inject, saving instead`);
|
37
|
-
saveTorrentFile(tracker, tag,
|
36
|
+
saveTorrentFile(tracker, tag, newMeta, nonceOptions);
|
38
37
|
break;
|
39
38
|
}
|
40
39
|
}
|
41
40
|
else {
|
42
|
-
saveTorrentFile(tracker, tag,
|
41
|
+
saveTorrentFile(tracker, tag, newMeta, nonceOptions);
|
43
42
|
logger.info(`Found ${styledName} on ${styledTracker}`);
|
44
43
|
}
|
45
44
|
return { isTorrentIncomplete };
|
46
45
|
}
|
47
|
-
async function searchJackettOrTorznab(name, nonceOptions) {
|
48
|
-
const { torznab } = getRuntimeConfig();
|
49
|
-
return torznab
|
50
|
-
? getTorznabManager().searchTorznab(name, nonceOptions)
|
51
|
-
: searchJackett(name, nonceOptions);
|
52
|
-
}
|
53
46
|
async function findOnOtherSites(searchee, hashesToExclude, nonceOptions = EmptyNonceOptions) {
|
54
47
|
const assessEach = async (result) => ({
|
55
48
|
assessment: await assessCandidate(result, searchee, hashesToExclude),
|
@@ -57,9 +50,14 @@ async function findOnOtherSites(searchee, hashesToExclude, nonceOptions = EmptyN
|
|
57
50
|
});
|
58
51
|
const tag = getTag(searchee.name);
|
59
52
|
const query = stripExtension(searchee.name);
|
53
|
+
// make sure searchee is in database
|
54
|
+
await db("searchee")
|
55
|
+
.insert({ name: searchee.name })
|
56
|
+
.onConflict("name")
|
57
|
+
.ignore();
|
60
58
|
let response;
|
61
59
|
try {
|
62
|
-
response = await
|
60
|
+
response = await getTorznabManager().searchTorznab(query, nonceOptions);
|
63
61
|
}
|
64
62
|
catch (e) {
|
65
63
|
logger.error(`error searching for ${query}`);
|
@@ -68,45 +66,47 @@ async function findOnOtherSites(searchee, hashesToExclude, nonceOptions = EmptyN
|
|
68
66
|
const results = response;
|
69
67
|
const loaded = await Promise.all(results.map(assessEach));
|
70
68
|
const successful = loaded.filter((e) => e.assessment.decision === Decision.MATCH);
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
: ""
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
69
|
+
if (successful.length) {
|
70
|
+
const name = searchee.name;
|
71
|
+
const numTrackers = successful.length;
|
72
|
+
const infoHashes = successful.map((s) => s.assessment.metafile.infoHash);
|
73
|
+
const trackers = successful.map((s) => s.tracker);
|
74
|
+
// @ts-expect-error Intl.ListFormat totally exists on node 12
|
75
|
+
const trackersListStr = new Intl.ListFormat("en", {
|
76
|
+
style: "long",
|
77
|
+
type: "conjunction",
|
78
|
+
}).format(trackers);
|
79
|
+
pushNotifier.notify({
|
80
|
+
body: `Found ${name} on ${numTrackers} trackers: ${trackersListStr}`,
|
81
|
+
extra: { infoHashes, trackers },
|
82
|
+
});
|
83
|
+
}
|
84
84
|
for (const { tracker, assessment } of successful) {
|
85
|
-
const { isTorrentIncomplete } = await performAction(assessment.
|
85
|
+
const { isTorrentIncomplete } = await performAction(assessment.metafile, searchee, tracker, nonceOptions, tag);
|
86
86
|
if (isTorrentIncomplete)
|
87
87
|
return successful.length;
|
88
88
|
}
|
89
|
-
updateSearchTimestamps(searchee.name);
|
89
|
+
await updateSearchTimestamps(searchee.name);
|
90
90
|
return successful.length;
|
91
91
|
}
|
92
|
-
function updateSearchTimestamps(name) {
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
92
|
+
async function updateSearchTimestamps(name) {
|
93
|
+
await db.transaction(async (trx) => {
|
94
|
+
const now = Date.now();
|
95
|
+
const entry = await trx("searchee").where({ name }).first();
|
96
|
+
await trx("searchee")
|
97
|
+
.where({ name })
|
98
|
+
.update({
|
99
|
+
last_searched: now,
|
100
|
+
first_searched: (entry === null || entry === void 0 ? void 0 : entry.first_searched) ? undefined : now,
|
101
|
+
});
|
102
|
+
});
|
103
103
|
}
|
104
104
|
async function findMatchesBatch(samples, hashesToExclude) {
|
105
|
-
const { delay
|
105
|
+
const { delay } = getRuntimeConfig();
|
106
106
|
let totalFound = 0;
|
107
107
|
for (const [i, sample] of samples.entries()) {
|
108
108
|
const sleep = new Promise((r) => setTimeout(r, delay * 1000));
|
109
|
-
const progress = chalk.blue(`[${i + 1
|
109
|
+
const progress = chalk.blue(`[${i + 1}/${samples.length}]`);
|
110
110
|
const name = stripExtension(sample.name);
|
111
111
|
logger.info("%s %s %s", progress, chalk.dim("Searching for"), name);
|
112
112
|
const numFoundPromise = findOnOtherSites(sample, hashesToExclude);
|
@@ -117,7 +117,7 @@ async function findMatchesBatch(samples, hashesToExclude) {
|
|
117
117
|
}
|
118
118
|
export async function searchForLocalTorrentByCriteria(criteria, nonceOptions) {
|
119
119
|
const meta = await getTorrentByCriteria(criteria);
|
120
|
-
const hashesToExclude = getInfoHashesToExclude();
|
120
|
+
const hashesToExclude = await getInfoHashesToExclude();
|
121
121
|
if (!filterByContent(meta))
|
122
122
|
return null;
|
123
123
|
return findOnOtherSites(meta, hashesToExclude, nonceOptions);
|
@@ -129,23 +129,28 @@ export async function checkNewCandidateMatch(candidate) {
|
|
129
129
|
}
|
130
130
|
catch (e) {
|
131
131
|
logger.verbose({
|
132
|
-
label: Label.
|
132
|
+
label: Label.REVERSE_LOOKUP,
|
133
133
|
message: `Did not find an existing entry for ${candidate.name}`,
|
134
134
|
});
|
135
135
|
return false;
|
136
136
|
}
|
137
|
-
const hashesToExclude = getInfoHashesToExclude();
|
137
|
+
const hashesToExclude = await getInfoHashesToExclude();
|
138
138
|
if (!filterByContent(meta))
|
139
139
|
return false;
|
140
140
|
const searchee = createSearcheeFromMetafile(meta);
|
141
|
+
// make sure searchee is in database
|
142
|
+
await db("searchee")
|
143
|
+
.insert({ name: searchee.name })
|
144
|
+
.onConflict("name")
|
145
|
+
.ignore();
|
141
146
|
const assessment = await assessCandidate(candidate, searchee, hashesToExclude);
|
142
147
|
if (assessment.decision !== Decision.MATCH)
|
143
148
|
return false;
|
144
|
-
const { isTorrentIncomplete } = await performAction(
|
149
|
+
const { isTorrentIncomplete } = await performAction(assessment.metafile, searchee, candidate.tracker, EmptyNonceOptions, getTag(candidate.name));
|
145
150
|
return !isTorrentIncomplete;
|
146
151
|
}
|
147
152
|
async function findSearchableTorrents() {
|
148
|
-
const {
|
153
|
+
const { torrents } = getRuntimeConfig();
|
149
154
|
let parsedTorrents;
|
150
155
|
if (Array.isArray(torrents)) {
|
151
156
|
const searcheeResults = await Promise.all(torrents.map(createSearcheeFromTorrentFile));
|
@@ -157,20 +162,41 @@ async function findSearchableTorrents() {
|
|
157
162
|
const hashesToExclude = parsedTorrents
|
158
163
|
.map((t) => t.infoHash)
|
159
164
|
.filter(Boolean);
|
160
|
-
const filteredTorrents = filterDupes(parsedTorrents)
|
161
|
-
|
162
|
-
.
|
163
|
-
|
164
|
-
|
165
|
-
return { samples, hashesToExclude };
|
165
|
+
const filteredTorrents = await filterAsync(filterDupes(parsedTorrents).filter(filterByContent), filterTimestamps);
|
166
|
+
logger.info({
|
167
|
+
label: Label.SEARCH,
|
168
|
+
message: `Found ${parsedTorrents.length} torrents, ${filteredTorrents.length} suitable to search for matches`,
|
169
|
+
});
|
170
|
+
return { samples: filteredTorrents, hashesToExclude };
|
166
171
|
}
|
167
172
|
export async function main() {
|
168
|
-
const {
|
173
|
+
const { outputDir } = getRuntimeConfig();
|
169
174
|
const { samples, hashesToExclude } = await findSearchableTorrents();
|
170
|
-
if (offset > 0)
|
171
|
-
logger.info(`Starting at offset ${offset}`);
|
172
175
|
fs.mkdirSync(outputDir, { recursive: true });
|
173
176
|
const totalFound = await findMatchesBatch(samples, hashesToExclude);
|
174
|
-
logger.info(
|
177
|
+
logger.info({
|
178
|
+
label: Label.SEARCH,
|
179
|
+
message: chalk.cyan(`Found ${chalk.bold.white(totalFound)} cross seeds from ${chalk.bold.white(samples.length)} original torrents`),
|
180
|
+
});
|
181
|
+
}
|
182
|
+
export async function scanRssFeeds() {
|
183
|
+
const candidates = await getTorznabManager().searchTorznab("");
|
184
|
+
logger.verbose({
|
185
|
+
label: Label.RSS,
|
186
|
+
message: `Scan returned ${candidates.length} results`,
|
187
|
+
});
|
188
|
+
logger.verbose({
|
189
|
+
label: Label.RSS,
|
190
|
+
message: "Indexing new torrents...",
|
191
|
+
});
|
192
|
+
await indexNewTorrents();
|
193
|
+
for (const [i, candidate] of candidates.entries()) {
|
194
|
+
logger.verbose({
|
195
|
+
label: Label.RSS,
|
196
|
+
message: `Processing release ${i + 1}/${candidates.length}`,
|
197
|
+
});
|
198
|
+
await checkNewCandidateMatch(candidate);
|
199
|
+
}
|
200
|
+
logger.info({ label: Label.RSS, message: "Scan complete" });
|
175
201
|
}
|
176
202
|
//# sourceMappingURL=pipeline.js.map
|
package/dist/pipeline.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"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"}
|
package/dist/preFilter.js
CHANGED
@@ -1,29 +1,26 @@
|
|
1
1
|
import { uniqBy } from "lodash-es";
|
2
2
|
import path from "path";
|
3
3
|
import { EP_REGEX, EXTENSIONS } from "./constants.js";
|
4
|
-
import db from "./db.js";
|
5
4
|
import { Label, logger } from "./logger.js";
|
6
5
|
import { getRuntimeConfig } from "./runtimeConfig.js";
|
7
|
-
import {
|
6
|
+
import { db } from "./db.js";
|
7
|
+
import { nMsAgo } from "./utils.js";
|
8
8
|
const extensionsWithDots = EXTENSIONS.map((e) => `.${e}`);
|
9
9
|
export function filterByContent(searchee) {
|
10
|
-
const { includeEpisodes,
|
11
|
-
if (searchAll)
|
12
|
-
return true;
|
10
|
+
const { includeEpisodes, includeNonVideos } = getRuntimeConfig();
|
13
11
|
function logReason(reason) {
|
14
12
|
logger.verbose({
|
15
13
|
label: Label.PREFILTER,
|
16
14
|
message: `Torrent ${searchee.name} was not selected for searching because ${reason}`,
|
17
15
|
});
|
18
16
|
}
|
19
|
-
|
20
|
-
|
21
|
-
EP_REGEX.test(searchee.files[0].name)) {
|
17
|
+
const isSingleEpisodeTorrent = searchee.files.length === 1 && EP_REGEX.test(searchee.files[0].name);
|
18
|
+
if (!includeEpisodes && isSingleEpisodeTorrent) {
|
22
19
|
logReason("it is a single episode");
|
23
20
|
return false;
|
24
21
|
}
|
25
|
-
const
|
26
|
-
if (!
|
22
|
+
const allFilesAreVideos = searchee.files.every((file) => extensionsWithDots.includes(path.extname(file.name)));
|
23
|
+
if (!includeNonVideos && !allFilesAreVideos) {
|
27
24
|
logReason("not all files are videos");
|
28
25
|
return false;
|
29
26
|
}
|
@@ -40,25 +37,30 @@ export function filterDupes(searchees) {
|
|
40
37
|
}
|
41
38
|
return filtered;
|
42
39
|
}
|
43
|
-
export function filterTimestamps(searchee) {
|
40
|
+
export async function filterTimestamps(searchee) {
|
44
41
|
const { excludeOlder, excludeRecentSearch } = getRuntimeConfig();
|
45
|
-
const
|
46
|
-
|
42
|
+
const timestampDataSql = await db("searchee")
|
43
|
+
.where({ name: searchee.name })
|
44
|
+
.first();
|
45
|
+
if (!timestampDataSql)
|
47
46
|
return true;
|
48
|
-
const {
|
47
|
+
const { first_searched, last_searched } = timestampDataSql;
|
49
48
|
function logReason(reason) {
|
50
49
|
logger.verbose({
|
51
50
|
label: Label.PREFILTER,
|
52
51
|
message: `Torrent ${searchee.name} was not selected for searching because ${reason}`,
|
53
52
|
});
|
54
53
|
}
|
55
|
-
if (excludeOlder &&
|
56
|
-
|
54
|
+
if (excludeOlder &&
|
55
|
+
first_searched &&
|
56
|
+
first_searched < nMsAgo(excludeOlder)) {
|
57
|
+
logReason(`its first search timestamp ${first_searched} is older than ${excludeOlder} minutes ago`);
|
57
58
|
return false;
|
58
59
|
}
|
59
60
|
if (excludeRecentSearch &&
|
60
|
-
|
61
|
-
|
61
|
+
last_searched &&
|
62
|
+
last_searched > nMsAgo(excludeRecentSearch)) {
|
63
|
+
logReason(`its last search timestamp ${last_searched} is newer than ${excludeRecentSearch} minutes ago`);
|
62
64
|
return false;
|
63
65
|
}
|
64
66
|
return true;
|