diff --git a/Find Unique Titles/config/userscript.config.ts b/Find Unique Titles/config/userscript.config.ts index 5b3ba96..3ac1bde 100644 --- a/Find Unique Titles/config/userscript.config.ts +++ b/Find Unique Titles/config/userscript.config.ts @@ -57,6 +57,8 @@ export const UserScriptConfig: IWebpackUserScript = { "https://www.cinematik.net/browse.php*", "https://pterclub.com/torrents.php*", "https://pterc.com/torrents.php*", + "https://torrentseeds.org/torrents*", + "https://torrentseeds.org/categories/*", ], require: [ `https://cdn.jsdelivr.net/npm/jquery@${pkg.dependencies.jquery}/dist/jquery.min.js`, diff --git a/Find Unique Titles/dist/find.unique.titles.user.js b/Find Unique Titles/dist/find.unique.titles.user.js index 1a7a25a..d1b01d1 100644 --- a/Find Unique Titles/dist/find.unique.titles.user.js +++ b/Find Unique Titles/dist/find.unique.titles.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name Find Unique Titles // @description Find unique titles to cross seed -// @version 0.0.4 +// @version 0.0.5 // @author Mea01 // @match https://cinemageddon.net/browse.php* // @match https://karagarga.in/browse.php* @@ -32,6 +32,8 @@ // @match https://www.cinematik.net/browse.php* // @match https://pterclub.com/torrents.php* // @match https://pterc.com/torrents.php* +// @match https://torrentseeds.org/torrents* +// @match https://torrentseeds.org/categories/* // @grant GM.xmlHttpRequest // @grant GM.setValue // @grant GM.getValue @@ -1186,7 +1188,6 @@ } async canUpload(request) { if (!request.imdbId) return true; - request.imdbId.replace("", ""); const result = await (0, common_searcher__WEBPACK_IMPORTED_MODULE_2__.search)(common_trackers__WEBPACK_IMPORTED_MODULE_3__.KG, { movie_title: "", movie_imdb_id: request.imdbId @@ -1681,6 +1682,91 @@ } } }, + "./src/trackers/TSeeds.ts": (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + __webpack_require__.d(__webpack_exports__, { + default: () => TSeeds + }); + var _utils_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/utils/utils.ts"); + var _tracker__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/trackers/tracker.ts"); + var common_dom__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("../common/dist/dom/index.mjs"); + var common_http__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("../common/dist/http/index.mjs"); + var common_searcher__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("../common/dist/searcher/index.mjs"); + var common_trackers__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("../common/dist/trackers/index.mjs"); + const parseCategory = element => { + const icon = element.querySelector("i.torrent-icon"); + if (!icon) return; + if (icon.classList.contains("fa-female")) return _tracker__WEBPACK_IMPORTED_MODULE_0__.Category.XXX; + if (icon.classList.contains("fa-tv")) return _tracker__WEBPACK_IMPORTED_MODULE_0__.Category.TV; + if (icon.classList.contains("fa-film")) return _tracker__WEBPACK_IMPORTED_MODULE_0__.Category.MOVIE; + if (icon.classList.contains("fa-music")) return _tracker__WEBPACK_IMPORTED_MODULE_0__.Category.MUSIC; + if (icon.classList.contains("fa-basketball-ball")) return _tracker__WEBPACK_IMPORTED_MODULE_0__.Category.SPORT; + if (icon.classList.contains("fa-gamepad")) return _tracker__WEBPACK_IMPORTED_MODULE_0__.Category.GAME; + return; + }; + class TSeeds { + canBeUsedAsSource() { + return true; + } + canBeUsedAsTarget() { + return true; + } + canRun(url) { + return url.includes("torrentseeds.org"); + } + async* getSearchRequest() { + let torrentsSelector = "#torrent-list-table tbody tr"; + if (isCategoryPage()) torrentsSelector = ".cat-torrents table tbody tr"; + let nodes = document.querySelectorAll(torrentsSelector); + yield { + total: nodes.length + }; + for (const element of nodes) { + const category = parseCategory(element); + let imdbId = null; + if (category == _tracker__WEBPACK_IMPORTED_MODULE_0__.Category.MOVIE) { + const link = element.querySelector('a.view-torrent[href*="/torrents/"]'); + let response = await (0, common_http__WEBPACK_IMPORTED_MODULE_1__.fetchAndParseHtml)(link.href); + imdbId = (0, _utils_utils__WEBPACK_IMPORTED_MODULE_2__.parseImdbIdFromLink)(response); + } + let sizeText = element.querySelector(".torrent-listings-size span")?.textContent; + if (isCategoryPage()) sizeText = element.children[7]?.textContent?.trim(); + const size = (0, _utils_utils__WEBPACK_IMPORTED_MODULE_2__.parseSize)(sizeText); + const request = { + torrents: [ { + size, + tags: [], + dom: element + } ], + dom: element, + imdbId, + query: "", + category + }; + yield request; + } + } + name() { + return "TSeeds"; + } + async canUpload(request) { + if (!request.imdbId) return true; + const result = await (0, common_searcher__WEBPACK_IMPORTED_MODULE_3__.search)(common_trackers__WEBPACK_IMPORTED_MODULE_4__.TSeeds, { + movie_title: "", + movie_imdb_id: request.imdbId + }); + return result == common_searcher__WEBPACK_IMPORTED_MODULE_3__.SearchResult.NOT_FOUND; + } + insertTrackersSelect(select) { + if (isCategoryPage()) (0, common_dom__WEBPACK_IMPORTED_MODULE_5__.addChild)(document.querySelector(".table-responsive.cat-torrents .text-center"), select); else { + const wrapper = document.createElement("div"); + wrapper.classList.add("form-group", "col-xs-3"); + wrapper.appendChild(select); + (0, common_dom__WEBPACK_IMPORTED_MODULE_5__.addChild)(document.querySelector("#torrent-list-search div.row"), wrapper); + } + } + } + const isCategoryPage = () => document.location.toString().includes("/categories/"); + }, "./src/trackers/TiK.ts": (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.d(__webpack_exports__, { default: () => TiK @@ -1781,6 +1867,7 @@ Pter: () => _Pter__WEBPACK_IMPORTED_MODULE_24__.default, SC: () => _SC__WEBPACK_IMPORTED_MODULE_1__.default, TL: () => _TL__WEBPACK_IMPORTED_MODULE_17__.default, + TSeeds: () => _TSeeds__WEBPACK_IMPORTED_MODULE_25__.default, TiK: () => _TiK__WEBPACK_IMPORTED_MODULE_23__.default, nCore: () => _nCore__WEBPACK_IMPORTED_MODULE_20__.default }); @@ -1809,6 +1896,7 @@ var _CHD__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__("./src/trackers/CHD.ts"); var _HDSky__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__("./src/trackers/HDSky.ts"); var _Pter__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__("./src/trackers/Pter.ts"); + var _TSeeds__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__("./src/trackers/TSeeds.ts"); var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([ _PTP__WEBPACK_IMPORTED_MODULE_0__ ]); _PTP__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; __webpack_async_result__(); @@ -2202,7 +2290,8 @@ }, "../common/dist/trackers/index.mjs": (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.d(__webpack_exports__, { - KG: () => KG + KG: () => KG, + TSeeds: () => TSeeds }); const KG = { TV: false, @@ -2213,6 +2302,15 @@ rateLimit: 125, both: true }; + const TSeeds = { + TV: false, + name: "TSeeds", + searchUrl: "https://www.torrentseeds.org/torrents?tmdbId=%tmdbid%", + loggedOutRegex: /Cloudflare|Forgot Your Password|Service Unavailable/, + matchRegex: /"Download">/, + positiveMatch: true, + both: true + }; }, "../node_modules/@trim21/gm-fetch/dist/index.mjs": (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.d(__webpack_exports__, { diff --git a/Find Unique Titles/package.json b/Find Unique Titles/package.json index 9063afc..058fd91 100644 --- a/Find Unique Titles/package.json +++ b/Find Unique Titles/package.json @@ -1,7 +1,7 @@ { "name": "find.unique.titles", "description": "Find unique titles to cross seed", - "version": "0.0.4", + "version": "0.0.5", "author": { "name": "Mea01" }, diff --git a/Find Unique Titles/readme.md b/Find Unique Titles/readme.md index ac2cdd2..207388b 100644 --- a/Find Unique Titles/readme.md +++ b/Find Unique Titles/readme.md @@ -5,6 +5,10 @@ You copy paste the content of the file `dist/find.unique.titles.user.js`. You can generate it by running run `npm run dev`. # Changelog +## 2023-11 +- Some work is done to use IMDB Scout code for searching +- Add support for TSeeds + ## 2023-10 - Add support for TiK - Add support for Pter diff --git a/Find Unique Titles/src/trackers/TSeeds.ts b/Find Unique Titles/src/trackers/TSeeds.ts new file mode 100644 index 0000000..3446584 --- /dev/null +++ b/Find Unique Titles/src/trackers/TSeeds.ts @@ -0,0 +1,114 @@ +import { parseImdbIdFromLink, parseSize } from "../utils/utils"; +import { Category, MetaData, Request, tracker } from "./tracker"; +import { addChild } from "common/dom"; +import { fetchAndParseHtml } from "common/http"; +import { search, SearchResult } from "common/searcher"; +import { TSeeds as TSeedsTracker } from "common/trackers"; + +const parseCategory = (element: Element): Category | undefined => { + const icon = element.querySelector("i.torrent-icon"); + if (!icon) return undefined; + if (icon.classList.contains("fa-female")) return Category.XXX; + if (icon.classList.contains("fa-tv")) return Category.TV; + if (icon.classList.contains("fa-film")) return Category.MOVIE; + if (icon.classList.contains("fa-music")) return Category.MUSIC; + if (icon.classList.contains("fa-basketball-ball")) return Category.SPORT; + if (icon.classList.contains("fa-gamepad")) return Category.GAME; + return undefined; +}; + +export default class TSeeds implements tracker { + canBeUsedAsSource(): boolean { + return true; + } + + canBeUsedAsTarget(): boolean { + return true; + } + + canRun(url: string): boolean { + return url.includes("torrentseeds.org"); + } + + async *getSearchRequest(): AsyncGenerator { + let torrentsSelector = "#torrent-list-table tbody tr"; + if (isCategoryPage()) { + torrentsSelector = '.cat-torrents table tbody tr' + } + let nodes = document.querySelectorAll(torrentsSelector); + yield { + total: nodes.length, + }; + for (const element of nodes) { + const category = parseCategory(element); + let imdbId = null; + if (category == Category.MOVIE) { + const link: HTMLAnchorElement | null = element.querySelector( + 'a.view-torrent[href*="/torrents/"]' + ); + let response = await fetchAndParseHtml( + (link as HTMLAnchorElement).href + ); + imdbId = parseImdbIdFromLink(response as HTMLElement); + } + let sizeText = element.querySelector(".torrent-listings-size span") + ?.textContent as string; + if (isCategoryPage()) { + sizeText = element.children[7]?.textContent?.trim() as string + } + const size = parseSize( + sizeText + ); + + const request: Request = { + torrents: [ + { + size, + tags: [], + dom: element as HTMLElement, + }, + ], + dom: element as HTMLElement, + imdbId, + query: "", + category, + }; + yield request; + } + } + + name(): string { + return "TSeeds"; + } + + async canUpload(request: Request) { + if (!request.imdbId) return true; + const result = await search(TSeedsTracker, { + movie_title: "", + movie_imdb_id: request.imdbId, + }); + return result == SearchResult.NOT_FOUND; + } + + insertTrackersSelect(select: HTMLElement): void { + if (isCategoryPage()) { + addChild( + document.querySelector( + ".table-responsive.cat-torrents .text-center" + ) as HTMLElement, + select + ); + } else { + const wrapper = document.createElement("div"); + wrapper.classList.add("form-group", "col-xs-3"); + wrapper.appendChild(select); + addChild( + document.querySelector("#torrent-list-search div.row") as HTMLElement, + wrapper + ); + } + } +} +const isCategoryPage = () => { + return document.location.toString().includes("/categories/"); +}; diff --git a/Find Unique Titles/src/trackers/index.ts b/Find Unique Titles/src/trackers/index.ts index 332a17a..077c3e3 100644 --- a/Find Unique Titles/src/trackers/index.ts +++ b/Find Unique Titles/src/trackers/index.ts @@ -23,6 +23,7 @@ import nCore from "./nCore"; import CHD from "./CHD"; import HDSky from "./HDSky"; import Pter from "./Pter"; +import TSeeds from "./TSeeds"; export { PTP, @@ -50,4 +51,5 @@ export { HDSky, TiK, Pter, + TSeeds, };