import { XVIDEOS_BASE_URL } from '@/constants/urls'; import { FetchParams, GalleryData, VideoData } from '@/meta/data'; import axios, { AxiosError } from 'axios'; import * as cheerio from "cheerio"; import { getHeaders } from '@/utils/scrape/common/headers'; import { Platforms } from '@/meta/settings'; import { findRelatedVideos, findVideoUrlInsideTagStringByFunctionNameAndExtension } from '@/utils/scrape/common/wgcz'; import { getDataFromRedis, storeDataIntoRedis } from '@/redis/client'; import { DEFAULT_RELATED_VIDEO_KEY_PATH, DEFAULT_XVIDEOS_CONTENT_EXPIRY } from '@/constants/redis'; export const fetchXvideosVideoData = async (videoId: string, params?: FetchParams): Promise<[VideoData, GalleryData[]]> => { let data: VideoData = { lowResUrl: '' } let related: GalleryData[] = []; const host = XVIDEOS_BASE_URL const reqHeaders = getHeaders(host) const queryUrl = `${host}${videoId}` const cachedVideoData = await getDataFromRedis(queryUrl) const cachedRelatedData = await getDataFromRedis(queryUrl + DEFAULT_RELATED_VIDEO_KEY_PATH) if (cachedVideoData) { return [cachedVideoData as VideoData, cachedRelatedData as GalleryData[] ?? []] } await axios.get(queryUrl, reqHeaders) .then(async response => { const html = response.data; const $ = cheerio.load(html); const scriptTags = $("script"); // populate video data object scriptTags.map((idx, elem) => { const lowResUrl = findVideoUrlInsideTagStringByFunctionNameAndExtension($(elem).toString(), 'setVideoUrlLow', '.mp4') const hiResUrl = findVideoUrlInsideTagStringByFunctionNameAndExtension($(elem).toString(), 'setVideoUrlHigh', '.mp4') const hlsUrl = findVideoUrlInsideTagStringByFunctionNameAndExtension($(elem).toString(), 'setVideoHLS', '.m3u8') if (lowResUrl) { data.lowResUrl = lowResUrl; } if (hiResUrl) { data.hiResUrl = hiResUrl } if (hlsUrl) { data.hlsUrl = hlsUrl } }) await storeDataIntoRedis(queryUrl, data, DEFAULT_XVIDEOS_CONTENT_EXPIRY); // populate related gallery scriptTags.map((idx, elem) => { const relatedVideos = findRelatedVideos($(elem).toString(), Platforms.xvideos) if (relatedVideos) { related = relatedVideos } }) await storeDataIntoRedis(queryUrl + DEFAULT_RELATED_VIDEO_KEY_PATH, related, DEFAULT_XVIDEOS_CONTENT_EXPIRY); }).catch((error: AxiosError) => { // handle errors }); return [data, related]; }