From 6b82e3d8c3da51e26e3f9d5d26327a80ecfbdd09 Mon Sep 17 00:00:00 2001 From: WebStreamr <210764791+webstreamr@users.noreply.github.com> Date: Tue, 20 Jan 2026 15:47:58 +0000 Subject: [PATCH] cleanup/revert doodstream --- src/extractor/DoodStream.ts | 66 +++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 36 deletions(-) diff --git a/src/extractor/DoodStream.ts b/src/extractor/DoodStream.ts index 7717ae1..5e3ca99 100644 --- a/src/extractor/DoodStream.ts +++ b/src/extractor/DoodStream.ts @@ -1,63 +1,57 @@ +import bytes from 'bytes'; +import * as cheerio from 'cheerio'; import { NotFoundError } from '../error'; import { Context, Format, Meta, UrlResult } from '../types'; -import { - buildMediaFlowProxyExtractorStreamUrl, - supportsMediaFlowProxy, -} from '../utils'; +import { buildMediaFlowProxyExtractorStreamUrl, supportsMediaFlowProxy } from '../utils'; import { Extractor } from './Extractor'; export class DoodStream extends Extractor { public readonly id = 'doodstream'; - public readonly label = 'Dood(MFP)'; - public override readonly ttl = 6 * 60 * 60 * 1000; // 6h + + public readonly label = 'DoodStream'; + + public override readonly ttl: number = 21600000; // 6h public override viaMediaFlowProxy = true; + /** @see https://github.com/Gujal00/ResolveURL/blob/master/script.module.resolveurl/lib/resolveurl/plugins/doodstream.py */ public supports(ctx: Context, url: URL): boolean { - const supportedDomain - = /dood|do[0-9]go|doood|dooood|ds2play|ds2video|dsvplay|d0o0d|do0od|d0000d|d000d|myvidplay|vidply|all3do|doply|vide0|vvide0|d-s/.test( - url.host, - ); - - return supportedDomain && supportsMediaFlowProxy(ctx); - } + return null !== url.host.match(/dood|do[0-9]go|doood|dooood|ds2play|ds2video|dsvplay|d0o0d|do0od|d0000d|d000d|myvidplay|vidply|all3do|doply|vide0|vvide0|d-s/) && supportsMediaFlowProxy(ctx); + }; public override normalize(url: URL): URL { - const id = url.pathname.replace(/\/+$/, '').split('/').pop(); - if (!id) throw new NotFoundError('Dood: invalid URL'); + const videoId = url.pathname.replace(/\/+$/, '').split('/').at(-1) as string; - return new URL(`https://dood.to/e/${id}`); - } + return new URL(`http://dood.to/e/${videoId}`); + }; - protected async extractInternal( - ctx: Context, - url: URL, - meta: Meta, - ): Promise { - const headers = { - Referer: meta.referer ?? url.href, - }; + protected async extractInternal(ctx: Context, url: URL, meta: Meta): Promise { + const headers = { Referer: meta.referer ?? url.href }; - const streamUrl - = await buildMediaFlowProxyExtractorStreamUrl( - ctx, - this.fetcher, - 'Doodstream', - url, - headers, - ); + const html = await this.fetcher.text(ctx, url, { headers }); + + if (/Video not found/.test(html)) { + throw new NotFoundError(); + } + + const $ = cheerio.load(html); + const title = $('title').text().trim().replace(/ - DoodStream$/, '').trim(); + + const downloadHtml = await this.fetcher.text(ctx, new URL(url.href.replace('/e/', '/d/'))); + const sizeMatch = downloadHtml.match(/([\d.]+ ?[GM]B)/); return [ { - url: streamUrl, + url: await buildMediaFlowProxyExtractorStreamUrl(ctx, this.fetcher, 'Doodstream', url, headers), format: Format.mp4, label: this.label, ttl: this.ttl, meta: { ...meta, - sourceId: `${this.id}_${meta.countryCodes?.join('_')}`, + title, + ...(sizeMatch && { bytes: bytes.parse(sizeMatch[1] as string) as number }), }, }, ]; - } + }; }