Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/zakkarry/cross-seed
Browse files Browse the repository at this point in the history
  • Loading branch information
zakkarry committed Sep 25, 2023
2 parents 4a15f17 + 7955bc7 commit c0d368e
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 60 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
with:
images: |
ghcr.io/${{ github.repository_owner }}/cross-seed
${{ secrets.DOCKERHUB_USERNAME }}/cross-seed
crossseed/cross-seed
tags: |
type=semver,pattern=version-{{version}}
type=semver,pattern={{version}}
Expand Down
2 changes: 1 addition & 1 deletion .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cross-seed",
"version": "5.4.5",
"version": "5.5.0",
"description": "Query Jackett for cross-seedable torrents",
"scripts": {
"test": "true",
Expand Down
4 changes: 3 additions & 1 deletion src/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ export async function performAction(
// Candidate is single, nested file
if (candidateParentDir != ".") {
if (!existsSync(path.join(linkDir, candidateParentDir))) {
mkdirSync(path.join(linkDir, candidateParentDir), { recursive: true });
mkdirSync(path.join(linkDir, candidateParentDir), {
recursive: true,
});
}
correctedlinkDir = path.join(linkDir, candidateParentDir);
}
Expand Down
1 change: 1 addition & 0 deletions src/cmd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ createCommandWithSharedOptions("daemon", "Start the cross-seed daemon")
setRuntimeConfig(runtimeConfig);
initializeLogger();
initializePushNotifier();
logger.info(`${PROGRAM_NAME} v${PROGRAM_VERSION}`);
logger.verbose({
label: Label.CONFIGDUMP,
message: inspect(runtimeConfig),
Expand Down
6 changes: 2 additions & 4 deletions src/config.template.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ module.exports = {
includeEpisodes: false,

/**
* Search for single episodes (not from season packs)
* during data based searches.
* Whether to include single episode torrents in the search (not from season packs).
* Like `includeEpisodes` but slightly more restrictive.
*/
includeSingleEpisodes: false,

Expand Down Expand Up @@ -166,8 +166,6 @@ module.exports = {
* cross-seed will send POST requests to this url
* with a JSON payload of { title, body }.
* Conforms to the caronc/apprise REST API.
* If necessary, supply your username and password inside the url like so:
* "http://username:password@localhost:8000/notify/cross-seed"
*/
notificationWebhookUrl: undefined,

Expand Down
53 changes: 9 additions & 44 deletions src/pushNotifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,54 +20,19 @@ interface PushNotification {

export class PushNotifier {
url: string;
username: string | undefined;
password: string | undefined;

constructor(url: string) {
const urlObj = new URL(url);

if (urlObj.username && urlObj.password) {
this.username = urlObj.username;
this.password = urlObj.password;

// Remove the username and password from the URL
urlObj.username = "";
urlObj.password = "";

this.url = urlObj.toString();
} else {
constructor(url: string) {
this.url = url;
}
}

async notify({ title = "cross-seed", body, ...rest }: PushNotification): Promise<void> {
notify({ title = "cross-seed", body, ...rest }: PushNotification): void {
if (this.url) {
const headers = new Headers();
headers.append("Content-Type", "application/json");

if (this.username && this.password) {
const credentials = `${this.username}:${this.password}`;
const basicAuth = "Basic " + btoa(credentials);
headers.append("Authorization", basicAuth);
}

logger.verbose(`Notification request send to ${this.url}`);

try {
const response = await fetch(this.url, {
method: "POST",
headers,
body: JSON.stringify({ title, body, ...rest }),
});

const responseText = await response.text();
response.ok
? logger.verbose(`Notifiaction server response:\n${responseText}`)
: logger.error(`Notifiaction server error: ${response.status}, ${response.statusText}`);

} catch (error) {
logger.error({ message: "Failed to send push notification", error });
}
fetch(this.url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title, body, ...rest }),
}).catch(() => {
logger.error({ message: "Failed to send push notification" });
});
}
}
}
Expand Down
40 changes: 34 additions & 6 deletions src/torrent.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import fs, { promises as fsPromises } from "fs";
import Fuse from "fuse.js";
import fs, { promises as fsPromises } from "fs";
import fetch, { Response } from "node-fetch";
import path, { join } from "path";
import { inspect } from "util";
import { USER_AGENT } from "./constants.js";
import {
USER_AGENT,
EP_REGEX,
SEASON_REGEX,
MOVIE_REGEX,
} from "./constants.js";
import { db } from "./db.js";
import { CrossSeedError } from "./errors.js";
import { logger, logOnce } from "./logger.js";
import { Metafile } from "./parseTorrent.js";
import { Result, resultOf, resultOfErr } from "./Result.js";
import { getRuntimeConfig } from "./runtimeConfig.js";
import { createSearcheeFromTorrentFile, Searchee } from "./searchee.js";
import { stripExtension } from "./utils.js";
import { reformatTitleForSearching, stripExtension } from "./utils.js";

export interface TorrentLocator {
infoHash?: string;
Expand Down Expand Up @@ -201,15 +206,38 @@ export async function getTorrentByFuzzyName(
name: string
): Promise<null | Metafile> {
const allNames = await db("torrent").select("name", "file_path");
const fullMatch = reformatTitleForSearching(name).replace(
/[^a-z0-9]/gi,
""
).toLowerCase();

// Attempt to filter torrents in DB to match incoming torrent before fuzzy check
let filteredNames = [];
if (fullMatch) {
filteredNames = allNames.filter((dbName) => {
const dbMatch = reformatTitleForSearching(dbName.name).replace(
/[^a-z0-9]/gi,
""
).toLowerCase();
if (!dbMatch) return false;
return fullMatch === dbMatch;
});
}

// If none match, proceed with fuzzy name check on all names.
filteredNames = filteredNames.length > 0 ? filteredNames : allNames;

// @ts-expect-error fuse types are confused
const potentialMatches = new Fuse(allNames, {
const potentialMatches = new Fuse(filteredNames, {
keys: ["name"],
distance: 6,
threshold: 0.25,
threshold: 0.6,
}).search(name);

// Valid matches exist
if (potentialMatches.length === 0) return null;
const [firstMatch] = potentialMatches;

const firstMatch = potentialMatches[0];
return parseTorrentFromFilename(firstMatch.item.file_path);
}

Expand Down

0 comments on commit c0d368e

Please sign in to comment.