From 3c3edbbacec223d7ebee3764e9f05f9f43b404c7 Mon Sep 17 00:00:00 2001 From: Ivan Evans <74743263+Pasithea0@users.noreply.github.com> Date: Fri, 3 Jan 2025 10:46:01 -0700 Subject: [PATCH] revert Catflix changes (keep rank) --- src/providers/sources/catflix.ts | 76 +++++++++++++++----------------- 1 file changed, 36 insertions(+), 40 deletions(-) diff --git a/src/providers/sources/catflix.ts b/src/providers/sources/catflix.ts index 8e825ad..11c98b4 100644 --- a/src/providers/sources/catflix.ts +++ b/src/providers/sources/catflix.ts @@ -1,59 +1,56 @@ import { load } from 'cheerio'; import { SourcererOutput, makeSourcerer } from '@/providers/base'; +import { compareMedia } from '@/utils/compare'; import { MovieScrapeContext, ShowScrapeContext } from '@/utils/context'; +import { NotFoundError } from '@/utils/errors'; const baseUrl = 'https://catflix.su'; async function comboScraper(ctx: ShowScrapeContext | MovieScrapeContext): Promise { - const movieId = ctx.media.tmdbId; - const mediaTitle = ctx.media.title.replace(/ /g, '-').replace(/[():]/g, '').toLowerCase(); - let watchPageUrl: string | undefined; + const searchPage = await ctx.proxiedFetcher('/', { + baseUrl, + query: { + s: ctx.media.title, + }, + }); - if (ctx.media.type === 'movie') { - watchPageUrl = `${baseUrl}/movie/${mediaTitle}-${movieId}`; - } else if (ctx.media.type === 'show') { - const seasonNumber = ctx.media.season.number; - const episodeNumber = ctx.media.episode.number; - const episodeId = ctx.media.episode.tmdbId; + ctx.progress(40); - if (!episodeId) { - throw new Error('Missing episode ID for show'); - } + const $search = load(searchPage); + const searchResults: { title: string; year?: number | undefined; url: string }[] = []; - watchPageUrl = `${baseUrl}/episode/${mediaTitle}-season-${seasonNumber}-episode-${episodeNumber}/eid-${episodeId}`; - } - if (!watchPageUrl) { - throw new Error('Failed to generate watch page URL'); - } + $search('li').each((_, element) => { + const title = $search(element).find('h2').first().text().trim(); + // the year is always present, but I sitll decided to make it nullable since the impl isn't as future-proof + const year = Number($search(element).find('.text-xs > span').eq(1).text().trim()) || undefined; + const url = $search(element).find('a').attr('href'); + + if (!title || !url) return; + + searchResults.push({ title, year, url }); + }); + + let watchPageUrl = searchResults.find((x) => x && compareMedia(ctx.media, x.title, x.year))?.url; + if (!watchPageUrl) throw new NotFoundError('No watchable item found'); ctx.progress(60); - const WatchPage = await ctx.proxiedFetcher(watchPageUrl); - const $WatchPage = load(WatchPage); - - const scriptContent = $WatchPage('script') - .toArray() - .find((script) => { - return ( - script.children[0] && script.children[0].type === 'text' && script.children[0].data.includes('main_origin =') - ); - }); - - if (!scriptContent) { - throw new Error('Script containing main_origin not found'); + if (ctx.media.type === 'show') { + const match = watchPageUrl.match(/\/series\/([^/]+)\/?/); + if (!match) throw new Error('Failed to parse watch page url'); + watchPageUrl = watchPageUrl.replace( + `/series/${match[1]}`, + `/episode/${match[1]}-${ctx.media.season.number}x${ctx.media.episode.number}`, + ); } - const mainOriginScript = scriptContent.children[0].type === 'text' ? scriptContent.children[0].data : ''; - const mainOriginMatch = mainOriginScript.match(/main_origin = "(.*?)";/); + const watchPage = load(await ctx.proxiedFetcher(watchPageUrl)); - if (!mainOriginMatch) { - throw new Error('Unable to extract main_origin value'); - } + ctx.progress(80); - const Catflix1 = mainOriginMatch[1]; - - const decodedUrl = atob(Catflix1); + const url = watchPage('iframe').first().attr('src'); // I couldn't think of a better way + if (!url) throw new Error('Failed to find embed url'); ctx.progress(90); @@ -61,7 +58,7 @@ async function comboScraper(ctx: ShowScrapeContext | MovieScrapeContext): Promis embeds: [ { embedId: 'turbovid', - url: decodedUrl, + url, }, ], }; @@ -72,7 +69,6 @@ export const catflixScraper = makeSourcerer({ name: 'Catflix', rank: 170, flags: [], - disabled: false, scrapeMovie: comboScraper, scrapeShow: comboScraper, });