Skip to content

Commit

Permalink
Add TNT
Browse files Browse the repository at this point in the history
  • Loading branch information
Morea committed Jan 13, 2024
1 parent da0e32d commit 5fad0d4
Show file tree
Hide file tree
Showing 9 changed files with 470 additions and 70 deletions.
1 change: 1 addition & 0 deletions Find Unique Titles/config/userscript.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export const UserScriptConfig: IWebpackUserScript = {
"https://torrentseeds.org/categories/*",
"https://www.morethantv.me/torrents/browse*",
"https://jpopsuki.eu/torrents.php*",
"https://tntracker.org/*",
],
require: [
`https://cdn.jsdelivr.net/npm/jquery@${pkg.dependencies.jquery}/dist/jquery.min.js`,
Expand Down
226 changes: 195 additions & 31 deletions Find Unique Titles/dist/find.unique.titles.user.js

Large diffs are not rendered by default.

11 changes: 4 additions & 7 deletions Find Unique Titles/src/trackers/IPT.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
parseResolution,
parseSize,
parseTags,
parseYear,
parseYearAndTitle,
} from "../utils/utils";
import {
Expand All @@ -20,16 +21,12 @@ import { fetchAndParseHtml } from "common/http";
const parseCategory = (element: HTMLElement): Category => {
let categoryImg = element.children[0].querySelector("img")!!;
const categoryLogo = categoryImg.src!!;
const alt = categoryImg.alt
if (categoryLogo.includes("Movies-") || alt.includes("Movie")) return Category.MOVIE;
const alt = categoryImg.alt;
if (categoryLogo.includes("Movies-") || alt.includes("Movie"))
return Category.MOVIE;
if (categoryLogo.includes("TV-")) return Category.TV;
if (categoryLogo.includes("Music-")) return Category.MUSIC;
};
const parseYear = (title: string) => {
const regex = /-(\d{4})-/;
const match = title.match(regex);
if (match) return match[1];
};
export default class CG implements tracker {
canBeUsedAsSource(): boolean {
return true;
Expand Down
73 changes: 59 additions & 14 deletions Find Unique Titles/src/trackers/RED.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,28 @@ import {
tracker,
} from "./tracker";
import { fetchAndParseHtml } from "common/http";
import { logger } from "common/logger";

const parseTorrents = (html: HTMLElement) => {
const groups = Array.from(html.querySelectorAll(".group_info strong"));
const torrents = [];
for (let group of groups) {
const yearAndTitle = group?.textContent?.split(" - ");
if (yearAndTitle) {
torrents.push({
year: parseInt(yearAndTitle[0], 10),
title: yearAndTitle[1],
});
}
}
return torrents;
};

function titlesAreEqual(first: string, second: string) {
first = first.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
second = second.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
return first.toLowerCase() == second.toLowerCase();
}

export default class RED implements tracker {
canBeUsedAsSource(): boolean {
Expand Down Expand Up @@ -40,28 +62,51 @@ export default class RED implements tracker {
musicRequest.type != MusicReleaseType.SINGLE
)
return SearchResult.NOT_ALLOWED;
if (!musicRequest.artists || !musicRequest.titles || !musicRequest.year)
if (!musicRequest.artists || !musicRequest.titles || !musicRequest.year) {
logger.debug(
"[{0}] Not enough data to check request: {1}",
this.name(),
request
);
return SearchResult.NOT_CHECKED;
}
for (let artist of musicRequest.artists) {
for (let title of musicRequest.titles) {
if (artist === "VA") {
artist = ""
artist = "";
}
if (artist) {
const queryUrl = `https://redacted.ch/artist.php?artistname=${encodeURIComponent(
artist
)}`;
const result = await fetchAndParseHtml(queryUrl);
if (
result.textContent?.includes(
"Your search did not match anything."
) ||
result.querySelector("#search_terms")
) {
return SearchResult.NOT_EXIST;
}
const torrents = parseTorrents(result);
logger.debug(
"[{0}] Parsed following torrents for artist: {1}: {2}",
this.name(),
artist,
torrents
);
for (let torrent of torrents) {
if (
torrent.year == request.year &&
titlesAreEqual(title, torrent.title)
) {
return SearchResult.EXIST;
}
}
}
const queryUrl = `https://redacted.ch/torrents.php?artistname=${encodeURIComponent(
artist
)}&groupname=${encodeURIComponent(title)}&year=${
musicRequest.year
}&order_by=time&order_way=desc&group_results=1&filter_cat%5B1%5D=1&action=advanced&searchsubmit=1`;
const result = await fetchAndParseHtml(queryUrl);
if (
!result.textContent?.includes("Your search did not match anything.")
)
return SearchResult.EXIST;
}
}
return SearchResult.NOT_EXIST;

return SearchResult.EXIST;
}

insertTrackersSelect(select: HTMLElement): void {}
Expand Down
154 changes: 154 additions & 0 deletions Find Unique Titles/src/trackers/TNT.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import {
parseCodec,
parseContainerAndFormat,
parseResolution,
parseTags,
parseYear,
parseYearAndTitle,
} from "../utils/utils";
import {
Category,
MetaData,
MusicReleaseType,
Request,
SearchResult,
tracker,
} from "./tracker";
import { addChild } from "common/dom";
import { fetchAndParseJson, sleep } from "common/http";
import { logger } from "common/logger";

const parseCategory = (category: number) => {
if (
[24, 18, 17, 20, 19, 34, 36, 45, 22, 37, 35, 43, 38, 39, 46].includes(
category
)
)
return Category.MOVIE;
if ([27, 28, 16, 2, 29, 40, 41, 42].includes(category)) return Category.TV;
if ([10, 12, 13, 14].includes(category)) return Category.GAME;
if ([1].includes(category)) return Category.AUDIOBOOK;
if ([8].includes(category)) return Category.BOOK;
if ([2, 41].includes(category)) return Category.ANIME;
if ([44, 25, 26].includes(category)) return Category.MUSIC;
};

const getTorrentTitle = (element: HTMLElement) => {
const h5 = element.children[1].querySelector("h5")!!;
const newTag = h5.querySelector(".newTag");
if (newTag) {
h5.removeChild(newTag);
}
return h5!!.textContent!!;
};

export default class TNT implements tracker {
canBeUsedAsSource(): boolean {
return true;
}

canBeUsedAsTarget(): boolean {
return false;
}

canRun(url: string): boolean {
return url.includes("tntracker.org") && url.includes('/?perPage=');
}

async *getSearchRequest(): AsyncGenerator<MetaData | Request, void, void> {
logger.debug(`[{0}] Parsing titles to check`, this.name());
const elements = Array.from(
document.querySelectorAll("#table_gen_wrapper .sTable tbody tr")
);
yield {
total: elements.length,
};
for (let element of elements) {
const torrentTitle = getTorrentTitle(element);
logger.debug("[TNT] Checking torrent: {0}", torrentTitle);
const torrentId = element.children[1]
.querySelector("a")!!
.href.split("/")
.pop();
const token = JSON.parse(
localStorage.getItem("ngStorage-token")!!
) as string;
const data = await fetchAndParseJson(
`https://tntracker.org/api/torrent?id=${torrentId}`,
{
headers: {
Authorization: token,
},
}
);
const imdbId = "tt" + data["imdb"];
const size = data.size / 1024 / 1024;
const category = parseCategory(data.category);
let title;
let year = undefined;
let request: Request = {
dom: [element as HTMLElement],
category,
};
if (category == Category.MOVIE) {
({ title, year } = parseYearAndTitle(torrentTitle));
request = {
...request,
torrents: [
{
size,
tags: parseTags(torrentTitle),
dom: element as HTMLElement,
resolution: parseResolution(torrentTitle),
container: parseCodec(torrentTitle),
},
],
year,
title: title?.replace(".", " "),
imdbId,
};
} else if (category == Category.MUSIC) {
const splittedTitle = torrentTitle.split("-")!!;
const artists = [splittedTitle[0].replaceAll("_", " ")];
const titles = [splittedTitle[1].replaceAll("_", " ")];
const year = parseYear(torrentTitle);
const { container, format } = parseContainerAndFormat(torrentTitle);
request = {
...request,
torrents: [
{
dom: element,
size,
format,
container,
},
],
artists,
titles,
year,
type: MusicReleaseType.ALBUM,
};
}
yield request;
}
}

name(): string {
return "TNT";
}

async search(request: Request): Promise<SearchResult> {
return SearchResult.NOT_CHECKED;
}

async insertTrackersSelect(select: HTMLElement): Promise<void> {
await sleep(3000);
if (document.getElementById("find-unique-titles")) return;
const form = document.getElementById("search")!!.parentElement;
const wrapper = document.createElement("div");
wrapper.classList.add("selector");
wrapper.id = "find-unique-titles";
addChild(wrapper, select);
addChild(form as HTMLElement, wrapper);
}
}
20 changes: 11 additions & 9 deletions Find Unique Titles/src/trackers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,30 @@ import BHD from "./BHD";
import BLU from "./BLU";
import BTarg from "./BTarg";
import CG from "./CG";
import CHD from "./CHD";
import CLANSUD from "./CLAN-SUD";
import CinemaZ from "./CinemaZ";
import FL from "./FL";
import GPW from "./GPW";
import HDB from "./HDB";
import HDSky from "./HDSky";
import HDT from "./HDT";
import IPT from "./IPT";
import JPTV from "./JPTV";
import JPop from "./JPop";
import KG from "./KG";
import MTV from "./MTV";
import MTeam from "./MTeam";
import NewInsane from "./NewInsane";
import PTP from "./PTP";
import Pter from "./Pter";
import RED from "./RED";
import SC from "./SC";
import TiK from "./TiK";
import TL from "./TL";
import MTeam from "./MTeam";
import nCore from "./nCore";
import CHD from "./CHD";
import HDSky from "./HDSky";
import Pter from "./Pter";
import TNT from "./TNT";
import TSeeds from "./TSeeds";
import MTV from "./MTV";
import JPop from "./JPop";
import RED from "./RED";
import TiK from "./TiK";
import nCore from "./nCore";

export {
PTP,
Expand Down Expand Up @@ -58,4 +59,5 @@ export {
MTV,
JPop,
RED,
TNT,
};
20 changes: 14 additions & 6 deletions Find Unique Titles/src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,16 @@ export const parseTags = (title: string) => {

export const parseYearAndTitle = (title: string | undefined) => {
if (!title) return { title: undefined, year: undefined };
const regex = /^(.*?)\s+\(?(\d{4})\)?\s+(.*)/;
const match = title.match(regex);
const regexes = [/^(.*?)\s+\(?(\d{4})\)?\s+(.*)/, /(.+?)\.(\d\d\d\d)/];
for (let regex of regexes) {
const match = title.match(regex);

if (match) {
const title = match[1].trim();
const year = parseInt(match[2], 10);
if (match) {
const title = match[1].trim();
const year = parseInt(match[2], 10);

return { title, year };
return { title, year };
}
}

return { title: undefined, year: undefined };
Expand Down Expand Up @@ -144,3 +146,9 @@ export const parseContainerAndFormat = (

return result;
};

export const parseYear = (title: string) => {
const regex = /-(\d{4})-/;
const match = title.match(regex);
if (match) return parseInt(match[1], 10);
};
9 changes: 7 additions & 2 deletions common/src/http/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import GM_fetch from "@trim21/gm-fetch";
import { logger } from "../logger/index.js";
import GM_fetch from "@trim21/gm-fetch";

const parser = new DOMParser();

Expand All @@ -9,7 +9,7 @@ export const fetchUrl = async (
wait = 1000
) => {
await sleep(wait);
logger.debug("Will fetch {0}", input)
logger.debug("Will fetch {0}", input);
const res = await GM_fetch(input, options);
return await res.text();
};
Expand All @@ -19,6 +19,11 @@ export const fetchAndParseHtml = async (query_url: string) => {
return parser.parseFromString(response, "text/html").body;
};

export const fetchAndParseJson = async (query_url: string, options={}) => {
const response = await fetchUrl(query_url, options);
return JSON.parse(response);
};

export const sleep = (ms: number) => {
return new Promise((resolve) => setTimeout(resolve, ms));
};
Loading

0 comments on commit 5fad0d4

Please sign in to comment.