From a30b271a578ff85cf31b3911bfc6aea2da0773a0 Mon Sep 17 00:00:00 2001 From: WebStreamr <210764791+webstreamr@users.noreply.github.com> Date: Thu, 18 Sep 2025 08:42:10 +0000 Subject: [PATCH] fix(source): improve 4KHDHub year and title matching --- package-lock.json | 37 +- package.json | 2 + src/source/FourKHDHub.ts | 20 +- .../https:4khdhub.fanscrank-movie-1745.html | 94 +- ...tion-mask-vs-leotard-devil-movie-2971.html | 496 +++++- ...-pigs-hoofs-secret-mission-movie-3116.html | 1433 ----------------- .../https:4khdhub.fansdark-series-889.html | 96 +- ...ub.fansdexter-original-sin-series-336.html | 90 +- ...b.fansdexter-resurrection-series-2297.html | 341 +++- ...4khdhub.fanslovely-runner-series-3379.html | 66 +- .../https:4khdhub.fanssCrankpercent202006 | 136 +- ...ercent20Leotardpercent20Devilpercent201993 | 4 +- ...nt20Hizumepercent20Daisakusenpercent201998 | 4 +- .../https:4khdhub.fanssDarkpercent202017 | 4 +- ...percent20Originalpercent20Sinpercent202024 | 124 +- ...ercent3Apercent20Resurrectionpercent202025 | 6 +- ...ub.fanssLovelypercent20Runnerpercent202024 | 148 +- .../https:4khdhub.fanssSupermanpercent202025 | 4 +- ...0Devilpercent27spercent20Bathpercent202024 | 72 +- ...:4khdhub.fanssuperman-imax-movie-2998.html | 658 +++++++- .../https:api.themoviedb.org3movie1061474 | 2 +- .../https:api.themoviedb.org3movie128868 | 2 +- .../https:api.themoviedb.org3movie128875 | 2 +- .../https:api.themoviedb.org3movie1948 | 2 +- .../https:api.themoviedb.org3movie931944 | 2 +- .../https:api.themoviedb.org3tv219937 | 2 +- .../https:api.themoviedb.org3tv230923 | 2 +- .../https:api.themoviedb.org3tv259909 | 2 +- .../https:api.themoviedb.org3tv70523 | 2 +- .../https:hubdrive.spacefile14019654338 | 32 +- .../https:hubdrive.spacefile2344141892 | 32 +- .../https:hubdrive.spacefile3499951460 | 32 +- ...lc5alo2bXoxVVNyNk45a2FIZkhpT1BvWTd1Y0E9PQ} | 2 +- ...0FpK0ZOMlZmdVVKZjZIOGkzS3RpUUNsQVZSNWc9PQ} | 2 +- ...Wh5M1NMeXVpOGw2QmtENDRPM3RoMmRtUXIvVnc9PQ} | 2 +- .../__snapshots__/FourKHDHub.test.ts.snap | 77 +- 36 files changed, 1892 insertions(+), 2140 deletions(-) delete mode 100644 src/source/__fixtures__/FourKHDHub/https:4khdhub.fanscrayon-shinchan-blitzkrieg-pigs-hoofs-secret-mission-movie-3116.html rename src/source/__fixtures__/FourKHDHub/{https:taazabull24.comidQ1dxTzFnbjhrQm5kMG5lL01tQzcvaHhpOFBFcWlwQUQ0VnRSUlFZaDIyUXdPUUtwRXlBUVZhY3h3RityMHlIT0ZTL0w0Q0xzOFY3N2ZhcEk4MFQ1WWc9PQ => https:taazabull24.comidQ1dxTzFnbjhrQm5kMG5lL01tQzcvaHhpOFBFcWlwQUQ0VnRSUlFZaDIyU3ZCbUl4V3Z0STBYY05iVlc5alo2bXoxVVNyNk45a2FIZkhpT1BvWTd1Y0E9PQ} (91%) rename src/source/__fixtures__/FourKHDHub/{https:taazabull24.comidQ1dxTzFnbjhrQm5kMG5lL01tQzcvaHhpOFBFcWlwQUQ0VnRSUlFZaDIyUlJmc1JoSTlOOVZrcTJFb0ZwdFZSSVpQc1NnTXBBYjJycVVRR0RCbU9pUGc9PQ => https:taazabull24.comidQ1dxTzFnbjhrQm5kMG5lL01tQzcvaHhpOFBFcWlwQUQ0VnRSUlFZaDIyVEJhcnhSOVdtUjErT2dac0FpK0ZOMlZmdVVKZjZIOGkzS3RpUUNsQVZSNWc9PQ} (91%) rename src/source/__fixtures__/FourKHDHub/{https:taazabull24.comidQ1dxTzFnbjhrQm5kMG5lL01tQzcvaHhpOFBFcWlwQUQ0VnRSUlFZaDIyVEFDYkFSSWt4aFZOVlNGZUpTWnVyOEh2ak5nWnYrcGRzYVo2bWlDSnpHZkE9PQ => https:taazabull24.comidQ1dxTzFnbjhrQm5kMG5lL01tQzcvaHhpOFBFcWlwQUQ0VnRSUlFZaDIyVHJsZjhRWnVDaVlzSXpzOWh5M1NMeXVpOGw2QmtENDRPM3RoMmRtUXIvVnc9PQ} (91%) diff --git a/package-lock.json b/package-lock.json index 926ae7a..9abb124 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "cacheable": "^2.0.0", "cheerio": "^1.0.0", "express": "^5.1.0", + "fast-levenshtein": "^3.0.0", "fetch-socks": "^1.3.2", "http-cache-semantics": "^4.2.0", "minimatch": "^10.0.3", @@ -32,6 +33,7 @@ "@tsconfig/node22": "^22.0.2", "@types/bytes": "^3.1.5", "@types/express": "^5.0.1", + "@types/fast-levenshtein": "^0.0.4", "@types/http-cache-semantics": "^4.0.4", "@types/jest": "^30.0.0", "@types/make-fetch-happen": "^10.0.4", @@ -1721,6 +1723,13 @@ "@types/send": "*" } }, + "node_modules/@types/fast-levenshtein": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@types/fast-levenshtein/-/fast-levenshtein-0.0.4.tgz", + "integrity": "sha512-tkDveuitddQCxut1Db8eEFfMahTjOumTJGPHmT9E7KUH+DkVq9WTpVvlfenf3S+uCBeu8j5FP2xik/KfxOEjeA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/http-cache-semantics": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", @@ -4929,11 +4938,22 @@ "license": "MIT" }, "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", + "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==", + "license": "MIT", + "dependencies": { + "fastest-levenshtein": "^1.0.7" + } + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } }, "node_modules/fastq": { "version": "1.19.1", @@ -8268,6 +8288,13 @@ "node": ">= 0.8.0" } }, + "node_modules/optionator/node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, "node_modules/own-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", diff --git a/package.json b/package.json index 62cf66f..bde1f78 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "cacheable": "^2.0.0", "cheerio": "^1.0.0", "express": "^5.1.0", + "fast-levenshtein": "^3.0.0", "fetch-socks": "^1.3.2", "http-cache-semantics": "^4.2.0", "minimatch": "^10.0.3", @@ -54,6 +55,7 @@ "@tsconfig/node22": "^22.0.2", "@types/bytes": "^3.1.5", "@types/express": "^5.0.1", + "@types/fast-levenshtein": "^0.0.4", "@types/http-cache-semantics": "^4.0.4", "@types/jest": "^30.0.0", "@types/make-fetch-happen": "^10.0.4", diff --git a/src/source/FourKHDHub.ts b/src/source/FourKHDHub.ts index 7265e95..0200621 100644 --- a/src/source/FourKHDHub.ts +++ b/src/source/FourKHDHub.ts @@ -2,6 +2,7 @@ import bytes from 'bytes'; import * as cheerio from 'cheerio'; import { BasicAcceptedElems, CheerioAPI } from 'cheerio'; import { AnyNode } from 'domhandler'; +import levenshtein from 'fast-levenshtein'; import rot13Cipher from 'rot13-cipher'; import { ContentType } from 'stremio-addon-sdk'; import { Context, CountryCode, Meta } from '../types'; @@ -68,13 +69,20 @@ export class FourKHDHub extends Source { const $ = cheerio.load(html); - const yearMatches = $(`.movie-card`) - .slice(0, 2) - .filter((_i, el) => parseInt($('.movie-card-meta', el).text()) === year); - const exactTitleMatches = yearMatches - .filter((_i, el) => $('.movie-card-title', el).text().includes(name)); + return $(`.movie-card:has(.movie-card-format:contains("${tmdbId.season ? 'Series' : 'Movies'}"))`) + .filter((_i, el) => { + const movieCardYear = parseInt($('.movie-card-meta', el).text()); - return (exactTitleMatches.length ? exactTitleMatches : yearMatches) + return Math.abs(movieCardYear - year) <= 1; + }) + .filter((_i, el) => { + const movieCardTitle = $('.movie-card-title', el) + .text() + .replace(/\[.*?]/, '') + .trim(); + + return levenshtein.get(movieCardTitle, name, { useCollator: true }) < 5; + }) .map((_i, el) => new URL($(el).attr('href') as string, this.baseUrl)) .get(0); }; diff --git a/src/source/__fixtures__/FourKHDHub/https:4khdhub.fanscrank-movie-1745.html b/src/source/__fixtures__/FourKHDHub/https:4khdhub.fanscrank-movie-1745.html index 13ecf98..21a8951 100644 --- a/src/source/__fixtures__/FourKHDHub/https:4khdhub.fanscrank-movie-1745.html +++ b/src/source/__fixtures__/FourKHDHub/https:4khdhub.fanscrank-movie-1745.html @@ -43,7 +43,7 @@ - + @@ -1420,29 +1420,63 @@ p, .metadata-value, .episode-description, .movie-tagline {
+
+
+
+
+
+
+
+
-
-
-
-
-
- @@ -1264,9 +1424,9 @@ p, .metadata-value, .episode-description, .movie-tagline {
+
-
-
-
-
-
-
+
+
+
+
+
+
+