import { HEADERS } from '~/globals/config'; import type { IFetcher } from '~/models/fetcher'; import { Logger } from '~/models/logger'; import type { RTMovie } from '~/models/rt-movie'; import type { RTSearchResults } from '~/models/rt-search-results'; import type { RTTVSeries } from '~/models/rt-tv-series'; import { extractBodyFromPage, extractMediaSetsFromFrontPageBody } from '~/modules/parser'; import { getLiteMovie, getLiteTvSeries } from '~/utilities/rt-to-lite'; import type { MediaSet, Movie, SearchResults, TVSeries } from '@rt_lite/common/models'; import { RT_SEARCH_URL, RT_URL } from '~/globals/rt-urls'; export class RTScraperGeneric { constructor ( private readonly fetcher: IFetcher, private readonly bodyProducer: (html: string) => HTMLBodyElement | null, private readonly shouldLog: boolean = true, private readonly logger: Logger = new Logger(console) ) {} async findMedia (terms?: string): Promise { if (typeof terms !== 'string') return { movies: [], tvSeries: [] }; const searchUrl = new URL('#', RT_SEARCH_URL); searchUrl.searchParams.append('query', terms); try { const response = await this.fetcher(searchUrl.href, { method: 'GET', headers: HEADERS }); const { movies, tvSeries } = await response.json(); return { movies: movies.map((movie: Readonly) => getLiteMovie(movie)), tvSeries: tvSeries.map((series: Readonly) => getLiteTvSeries(series)) }; } catch (err) { if (this.shouldLog) this.logger.error(err); return { movies: [], tvSeries: [] }; } } async findMovies (terms?: string): Promise { return (await this.findMedia(terms)).movies; } async findTVSeries (terms?: string): Promise { return (await this.findMedia(terms)).tvSeries; } async getFrontPageSets (): Promise { const frontPageMovieSets: MediaSet[] = []; const frontPage = await this.#getFrontPage(); if (frontPage.length < 1) return frontPageMovieSets; const frontPageBody = extractBodyFromPage(frontPage); const body = this.bodyProducer(frontPageBody); if (!body) return frontPageMovieSets; frontPageMovieSets.push(...extractMediaSetsFromFrontPageBody(body)); return frontPageMovieSets; } async #getFrontPage (): Promise { try { const response = await this.fetcher(RT_URL.href, { method: 'GET', headers: HEADERS }); const html = await response.text(); return html; } catch (err) { if (this.shouldLog) this.logger.error(err); return ''; } } }