From b88eba017d59bc14dc6d3e326d008a23698bbdb2 Mon Sep 17 00:00:00 2001 From: WebStreamr <210764791+webstreamr@users.noreply.github.com> Date: Mon, 30 Jun 2025 18:51:21 +0000 Subject: [PATCH] chore(extractor): simplify type and passing of height --- src/extractor/DoodStream.ts | 5 ++--- src/extractor/Dropload.ts | 2 +- src/extractor/ExternalUrl.ts | 2 +- src/extractor/KinoGer.ts | 6 ++---- src/extractor/Mixdrop.ts | 3 ++- src/extractor/Soaper.ts | 5 ++--- src/extractor/SuperVideo.ts | 2 +- src/extractor/Uqload.ts | 2 +- src/extractor/VidSrc.ts | 5 ++--- src/extractor/__snapshots__/DoodStream.test.ts.snap | 2 ++ src/extractor/__snapshots__/ExternalUrl.test.ts.snap | 1 + src/extractor/__snapshots__/ExtractorRegistry.test.ts.snap | 1 + src/extractor/__snapshots__/KinoGer.test.ts.snap | 1 + src/extractor/__snapshots__/Mixdrop.test.ts.snap | 1 + src/extractor/__snapshots__/Soaper.test.ts.snap | 1 + src/types.ts | 4 ++-- src/utils/height.ts | 4 ++-- 17 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/extractor/DoodStream.ts b/src/extractor/DoodStream.ts index 1724148..797785e 100644 --- a/src/extractor/DoodStream.ts +++ b/src/extractor/DoodStream.ts @@ -1,7 +1,7 @@ import randomstring from 'randomstring'; import * as cheerio from 'cheerio'; import { Extractor } from './Extractor'; -import { Fetcher, guessFromTitle } from '../utils'; +import { Fetcher, guessHeightFromTitle } from '../utils'; import { Context, CountryCode, Format, UrlResult } from '../types'; import { NotFoundError } from '../error'; @@ -43,7 +43,6 @@ export class DoodStream extends Extractor { const $ = cheerio.load(html); const title = $('title').text().trim().replace(/ - DoodStream$/, '').trim(); - const height = guessFromTitle(title); const mp4Url = new URL(`${baseUrl}${randomstring.generate(10)}?token=${token}&expiry=${Date.now()}`); @@ -58,9 +57,9 @@ export class DoodStream extends Extractor { ttl: this.ttl, meta: { countryCodes: [countryCode], + height: guessHeightFromTitle(title), title, ...(mp4Head['content-length'] && { bytes: parseInt(mp4Head['content-length'] as string) }), - ...(height && { height }), }, requestHeaders: { Referer: url.origin, diff --git a/src/extractor/Dropload.ts b/src/extractor/Dropload.ts index 10d5ae7..c199e72 100644 --- a/src/extractor/Dropload.ts +++ b/src/extractor/Dropload.ts @@ -48,7 +48,7 @@ export class Dropload extends Extractor { meta: { bytes: bytes.parse(sizeMatch[1] as string) as number, countryCodes: [countryCode], - height: parseInt(heightMatch[1] as string) as number, + height: parseInt(heightMatch[1] as string), title, }, }, diff --git a/src/extractor/ExternalUrl.ts b/src/extractor/ExternalUrl.ts index 5550629..86b28ba 100644 --- a/src/extractor/ExternalUrl.ts +++ b/src/extractor/ExternalUrl.ts @@ -39,7 +39,7 @@ export class ExternalUrl extends Extractor { ttl: this.ttl, meta: { countryCodes: [countryCode], - ...(title && { title }), + title, }, }, ]; diff --git a/src/extractor/KinoGer.ts b/src/extractor/KinoGer.ts index 6369ffa..e7236e0 100644 --- a/src/extractor/KinoGer.ts +++ b/src/extractor/KinoGer.ts @@ -1,6 +1,6 @@ import crypto from 'crypto'; import { Extractor } from './Extractor'; -import { Fetcher, guessFromTitle } from '../utils'; +import { Fetcher, guessHeightFromTitle } from '../utils'; import { Context, CountryCode, Format, UrlResult } from '../types'; /** @see https://github.com/Gujal00/ResolveURL/blob/master/script.module.resolveurl/lib/resolveurl/plugins/kinoger.py */ @@ -36,8 +36,6 @@ export class KinoGer extends Extractor { const { cf, title } = JSON.parse(decrypted) as { cf: string; title: string }; - const height = guessFromTitle(title); - return [ { url: new URL(cf), @@ -47,8 +45,8 @@ export class KinoGer extends Extractor { ttl: this.ttl, meta: { countryCodes: [countryCode], + height: guessHeightFromTitle(title), title, - ...(height && { height }), }, requestHeaders: { Referer: url.origin, diff --git a/src/extractor/Mixdrop.ts b/src/extractor/Mixdrop.ts index 6179a97..2c417ce 100644 --- a/src/extractor/Mixdrop.ts +++ b/src/extractor/Mixdrop.ts @@ -1,7 +1,7 @@ import bytes from 'bytes'; import * as cheerio from 'cheerio'; import { Extractor } from './Extractor'; -import { buildMediaFlowProxyExtractorRedirectUrl, Fetcher, supportsMediaFlowProxy } from '../utils'; +import { buildMediaFlowProxyExtractorRedirectUrl, Fetcher, guessHeightFromTitle, supportsMediaFlowProxy } from '../utils'; import { Context, CountryCode, Format, UrlResult } from '../types'; import { NotFoundError } from '../error'; @@ -48,6 +48,7 @@ export class Mixdrop extends Extractor { ttl: this.ttl, meta: { countryCodes: [countryCode], + height: guessHeightFromTitle(title), title, ...(sizeMatch && { bytes: bytes.parse((sizeMatch[1] as string).replace(',', '')) as number, diff --git a/src/extractor/Soaper.ts b/src/extractor/Soaper.ts index acd558e..88f76a3 100644 --- a/src/extractor/Soaper.ts +++ b/src/extractor/Soaper.ts @@ -1,5 +1,5 @@ import { Extractor } from './Extractor'; -import { Fetcher, guessFromPlaylist } from '../utils'; +import { Fetcher, guessHeightFromPlaylist } from '../utils'; import { Context, CountryCode, Format, UrlResult } from '../types'; interface SoaperInfoResponsePartial { @@ -48,7 +48,6 @@ export class Soaper extends Extractor { const jsonResponse = JSON.parse(response) as SoaperInfoResponsePartial; const m3u8Url = new URL(jsonResponse['val'], url.origin); - const height = await guessFromPlaylist(ctx, this.fetcher, m3u8Url); return [ { @@ -59,8 +58,8 @@ export class Soaper extends Extractor { ttl: this.ttl, meta: { countryCodes: [countryCode], + height: await guessHeightFromPlaylist(ctx, this.fetcher, m3u8Url), title: `${title}`, - ...(height && { height }), }, }, ]; diff --git a/src/extractor/SuperVideo.ts b/src/extractor/SuperVideo.ts index b70d4a6..0f71698 100644 --- a/src/extractor/SuperVideo.ts +++ b/src/extractor/SuperVideo.ts @@ -54,7 +54,7 @@ export class SuperVideo extends Extractor { title, ...(heightAndSizeMatch && { bytes: bytes.parse(heightAndSizeMatch[2] as string) as number, - height: parseInt(heightAndSizeMatch[1] as string) as number, + height: parseInt(heightAndSizeMatch[1] as string), }), }, }, diff --git a/src/extractor/Uqload.ts b/src/extractor/Uqload.ts index f93a18f..5af6a30 100644 --- a/src/extractor/Uqload.ts +++ b/src/extractor/Uqload.ts @@ -47,7 +47,7 @@ export class Uqload extends Extractor { countryCodes: [countryCode], title, ...(heightMatch && { - height: parseInt(heightMatch[1] as string) as number, + height: parseInt(heightMatch[1] as string), }), }, }, diff --git a/src/extractor/VidSrc.ts b/src/extractor/VidSrc.ts index 6f2f79a..fb6952f 100644 --- a/src/extractor/VidSrc.ts +++ b/src/extractor/VidSrc.ts @@ -1,7 +1,7 @@ import * as cheerio from 'cheerio'; import slugify from 'slugify'; import { Extractor } from './Extractor'; -import { Fetcher, guessFromPlaylist } from '../utils'; +import { Fetcher, guessHeightFromPlaylist } from '../utils'; import { Context, CountryCode, Format, UrlResult } from '../types'; import { NotFoundError } from '../error'; @@ -46,7 +46,6 @@ export class VidSrc extends Extractor { } const m3u8Url = new URL(fileMatch[1] as string); - const height = await guessFromPlaylist(ctx, this.fetcher, m3u8Url); return { url: m3u8Url, @@ -56,8 +55,8 @@ export class VidSrc extends Extractor { ttl: this.ttl, meta: { countryCodes: [countryCode], + height: await guessHeightFromPlaylist(ctx, this.fetcher, m3u8Url), title, - ...(height && { height }), }, }; }), diff --git a/src/extractor/__snapshots__/DoodStream.test.ts.snap b/src/extractor/__snapshots__/DoodStream.test.ts.snap index 056b69b..60d8ad7 100644 --- a/src/extractor/__snapshots__/DoodStream.test.ts.snap +++ b/src/extractor/__snapshots__/DoodStream.test.ts.snap @@ -32,6 +32,7 @@ exports[`DoodStream dood.to 1`] = ` "countryCodes": [ "de", ], + "height": undefined, "title": "des-teufels-bad-2024", }, "requestHeaders": { @@ -53,6 +54,7 @@ exports[`DoodStream doodster 1`] = ` "countryCodes": [ "de", ], + "height": undefined, "title": "Brokeback Mountain 2005", }, "requestHeaders": { diff --git a/src/extractor/__snapshots__/ExternalUrl.test.ts.snap b/src/extractor/__snapshots__/ExternalUrl.test.ts.snap index 6e351a6..5c841d7 100644 --- a/src/extractor/__snapshots__/ExternalUrl.test.ts.snap +++ b/src/extractor/__snapshots__/ExternalUrl.test.ts.snap @@ -31,6 +31,7 @@ exports[`ExternalUrl netu.fanstream.us 1`] = ` "countryCodes": [ "fr", ], + "title": undefined, }, "sourceId": "external_fr", "ttl": 3600000, diff --git a/src/extractor/__snapshots__/ExtractorRegistry.test.ts.snap b/src/extractor/__snapshots__/ExtractorRegistry.test.ts.snap index 5f2fbd9..de7fc9a 100644 --- a/src/extractor/__snapshots__/ExtractorRegistry.test.ts.snap +++ b/src/extractor/__snapshots__/ExtractorRegistry.test.ts.snap @@ -12,6 +12,7 @@ exports[`ExtractorRegistry returns external URLs if enabled by config 1`] = ` "countryCodes": [ "de", ], + "title": undefined, }, "sourceId": "external_de", "ttl": 3600000, diff --git a/src/extractor/__snapshots__/KinoGer.test.ts.snap b/src/extractor/__snapshots__/KinoGer.test.ts.snap index 23064be..b8a1e49 100644 --- a/src/extractor/__snapshots__/KinoGer.test.ts.snap +++ b/src/extractor/__snapshots__/KinoGer.test.ts.snap @@ -9,6 +9,7 @@ exports[`KinoGer Blood & Sinners 1`] = ` "countryCodes": [ "de", ], + "height": undefined, "title": "Blood.and.Sinners.2025.mkv", }, "requestHeaders": { diff --git a/src/extractor/__snapshots__/Mixdrop.test.ts.snap b/src/extractor/__snapshots__/Mixdrop.test.ts.snap index 9b56c9d..18b2bcb 100644 --- a/src/extractor/__snapshots__/Mixdrop.test.ts.snap +++ b/src/extractor/__snapshots__/Mixdrop.test.ts.snap @@ -12,6 +12,7 @@ exports[`Mixdrop mixdrop.my /e/ 1`] = ` "countryCodes": [ "de", ], + "height": undefined, "title": "28_giorni_dopo_2002_HD_-_Altadefinizione01.mp4", }, "sourceId": "mixdrop_de", diff --git a/src/extractor/__snapshots__/Soaper.test.ts.snap b/src/extractor/__snapshots__/Soaper.test.ts.snap index ee85732..b068c3f 100644 --- a/src/extractor/__snapshots__/Soaper.test.ts.snap +++ b/src/extractor/__snapshots__/Soaper.test.ts.snap @@ -47,6 +47,7 @@ exports[`Soaper last of us s2e3 1`] = ` "countryCodes": [ "de", ], + "height": undefined, "title": "The Last of Us 2x3", }, "sourceId": "soaper_de", diff --git a/src/types.ts b/src/types.ts index 90bf019..cafa811 100644 --- a/src/types.ts +++ b/src/types.ts @@ -31,8 +31,8 @@ export enum BlockedReason { export interface Meta { bytes?: number; countryCodes: CountryCode[]; - height?: number; - title?: string; + height?: number | undefined; + title?: string | undefined; } export enum Format { diff --git a/src/utils/height.ts b/src/utils/height.ts index 3210666..21165d7 100644 --- a/src/utils/height.ts +++ b/src/utils/height.ts @@ -1,7 +1,7 @@ import { CustomRequestInit, Fetcher } from './Fetcher'; import { Context } from '../types'; -export const guessFromTitle = (title: string): number | undefined => { +export const guessHeightFromTitle = (title: string): number | undefined => { const heightMatch = title.match(/([0-9]+)p/); if (heightMatch && heightMatch[1]) { return parseInt(heightMatch[1]); @@ -10,7 +10,7 @@ export const guessFromTitle = (title: string): number | undefined => { return undefined; }; -export const guessFromPlaylist = async (ctx: Context, fetcher: Fetcher, url: URL, init?: CustomRequestInit): Promise => { +export const guessHeightFromPlaylist = async (ctx: Context, fetcher: Fetcher, url: URL, init?: CustomRequestInit): Promise => { const m3u8Data = await fetcher.text(ctx, url, init); const heights = Array.from(m3u8Data.matchAll(/\d+x(\d+)|(\d+)p/g))