diff --git a/src/providers/sources/warezcdn/common.ts b/src/providers/sources/warezcdn/common.ts index 83e94bc..56d23e8 100644 --- a/src/providers/sources/warezcdn/common.ts +++ b/src/providers/sources/warezcdn/common.ts @@ -1,4 +1,26 @@ +import { ScrapeContext } from '@/utils/context'; + export const warezcdnBase = 'https://embed.warezcdn.com'; export const warezcdnApiBase = 'https://warezcdn.com/embed'; export const warezcdnPlayerBase = 'https://warezcdn.com/player'; export const warezcdnWorkerProxy = 'https://workerproxy.warezcdn.workers.dev'; + +export async function getExternalPlayerUrl(ctx: ScrapeContext, embedId: string, embedUrl: string) { + const params = { + id: embedUrl, + sv: embedId, + }; + const realUrl = await ctx.proxiedFetcher(`/getPlay.php`, { + baseUrl: warezcdnApiBase, + headers: { + Referer: `${warezcdnApiBase}/getEmbed.php?${new URLSearchParams(params)}`, + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36', + }, + query: params, + }); + + const realEmbedUrl = realUrl.match(/window\.location\.href="([^"]*)";/); + if (!realEmbedUrl) throw new Error('Could not find embed url'); + return realEmbedUrl[1]; +} diff --git a/src/providers/sources/warezcdn/index.ts b/src/providers/sources/warezcdn/index.ts index 1c9ad00..f27b052 100644 --- a/src/providers/sources/warezcdn/index.ts +++ b/src/providers/sources/warezcdn/index.ts @@ -5,74 +5,110 @@ import { SourcererEmbed, makeSourcerer } from '@/providers/base'; import { mixdropScraper } from '@/providers/embeds/mixdrop'; import { warezcdnembedHlsScraper } from '@/providers/embeds/warezcdn/hls'; import { warezcdnembedMp4Scraper } from '@/providers/embeds/warezcdn/mp4'; -import { MovieScrapeContext, ShowScrapeContext } from '@/utils/context'; import { NotFoundError } from '@/utils/errors'; -import { warezcdnApiBase, warezcdnBase } from './common'; - -const universalScraper = async (ctx: MovieScrapeContext | ShowScrapeContext) => { - if (!ctx.media.imdbId) throw new NotFoundError('This source requires IMDB id.'); - - let id = `filme/${ctx.media.imdbId}`; - if (ctx.media.type === 'show') - id = `serie/${ctx.media.imdbId}/${ctx.media.season.number}/${ctx.media.episode.number}`; - - const serversPage = await ctx.proxiedFetcher(`/${id}`, { - baseUrl: warezcdnBase, - }); - const $ = load(serversPage); - - const embedsHost = $('.hostList.active [data-load-embed]').get(); - - const embeds: SourcererEmbed[] = []; - - embedsHost.forEach(async (element) => { - const embedHost = $(element).attr('data-load-embed-host')!; - const embedUrl = $(element).attr('data-load-embed')!; - - if (embedHost === 'mixdrop') { - const params = { - id: embedUrl, - sv: 'mixdrop', - }; - const realUrl = await ctx.proxiedFetcher(`/getPlay.php`, { - baseUrl: warezcdnApiBase, - headers: { - Referer: `${warezcdnApiBase}/getEmbed.php?${new URLSearchParams(params)}`, - }, - query: params, - }); - - const realEmbedUrl = realUrl.match(/window\.location\.href="([^"]*)";/); - if (!realEmbedUrl) throw new Error('Could not find embed url'); - embeds.push({ - embedId: mixdropScraper.id, - url: realEmbedUrl[1], - }); - } else if (embedHost === 'warezcdn') { - embeds.push( - { - embedId: warezcdnembedHlsScraper.id, - url: embedUrl, - }, - { - embedId: warezcdnembedMp4Scraper.id, - url: embedUrl, - }, - ); - } - }); - - return { - embeds, - }; -}; +import { getExternalPlayerUrl, warezcdnBase } from './common'; +import { SerieAjaxResponse } from './types'; export const warezcdnScraper = makeSourcerer({ id: 'warezcdn', name: 'WarezCDN', rank: 81, flags: [flags.CORS_ALLOWED], - scrapeMovie: universalScraper, - scrapeShow: universalScraper, + scrapeMovie: async (ctx) => { + if (!ctx.media.imdbId) throw new NotFoundError('This source requires IMDB id.'); + + const serversPage = await ctx.proxiedFetcher(`/filme/${ctx.media.imdbId}`, { + baseUrl: warezcdnBase, + }); + const $ = load(serversPage); + + const embedsHost = $('.hostList.active [data-load-embed]').get(); + + const embeds: SourcererEmbed[] = []; + + embedsHost.forEach(async (element) => { + const embedHost = $(element).attr('data-load-embed-host')!; + const embedUrl = $(element).attr('data-load-embed')!; + + if (embedHost === 'mixdrop') { + const realEmbedUrl = await getExternalPlayerUrl(ctx, 'mixdrop', embedUrl); + if (!realEmbedUrl) throw new Error('Could not find embed url'); + embeds.push({ + embedId: mixdropScraper.id, + url: realEmbedUrl, + }); + } else if (embedHost === 'warezcdn') { + embeds.push( + { + embedId: warezcdnembedHlsScraper.id, + url: embedUrl, + }, + { + embedId: warezcdnembedMp4Scraper.id, + url: embedUrl, + }, + ); + } + }); + + return { + embeds, + }; + }, + scrapeShow: async (ctx) => { + if (!ctx.media.imdbId) throw new NotFoundError('This source requires IMDB id.'); + + const url = `${warezcdnBase}/serie/${ctx.media.imdbId}/${ctx.media.season.number}/${ctx.media.episode.number}`; + + const serversPage = await ctx.proxiedFetcher(url); + + const episodeId = serversPage.match(/\$\('\[data-load-episode-content="(\d+)"\]'\)/)?.[1]; + + if (!episodeId) throw new NotFoundError('Failed to find episode id'); + + const streamsData = await ctx.proxiedFetcher(`/serieAjax.php`, { + method: 'POST', + baseUrl: warezcdnBase, + body: new URLSearchParams({ + getAudios: episodeId, + }), + headers: { + Origin: warezcdnBase, + Referer: url, + 'X-Requested-With': 'XMLHttpRequest', + }, + }); + + const streams: SerieAjaxResponse = JSON.parse(streamsData); + const list = streams.list['0']; + const embeds: SourcererEmbed[] = []; + + // 3 means ok + if (list.mixdropStatus === '3') { + const realEmbedUrl = await getExternalPlayerUrl(ctx, 'mixdrop', list.id); + if (!realEmbedUrl) throw new Error('Could not find embed url'); + embeds.push({ + embedId: mixdropScraper.id, + url: realEmbedUrl, + }); + } + + if (list.warezcdnStatus === '3') { + embeds.push( + { + embedId: warezcdnembedHlsScraper.id, + url: list.id, + }, + { + embedId: warezcdnembedMp4Scraper.id, + url: list.id, + }, + ); + } + + return { + embeds, + }; + }, }); diff --git a/src/providers/sources/warezcdn/types.ts b/src/providers/sources/warezcdn/types.ts new file mode 100644 index 0000000..38711ff --- /dev/null +++ b/src/providers/sources/warezcdn/types.ts @@ -0,0 +1,16 @@ +interface Data { + id: string; + audio: string; + mixdropStatus: string; + fembedStatus: string; + streamtapeStatus: string; + warezcdnStatus: string; +} + +type List = { + [key: string]: Data; +}; + +export interface SerieAjaxResponse { + list: List; +}