Release v0.2.0 #74
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"Header": {
|
||||
"title": "Proxy Raye",
|
||||
"description": "A proxy for XVideos",
|
||||
"description": "A proxy for porn websites",
|
||||
"disclaimer_0": "Genital sexuality is only one of the many possible conceptions of sexuality",
|
||||
"disclaimer_1": "Platform capitalism makes money on desire flow. Proxies avoid this to happen.",
|
||||
"disclaimer_2": "Platform capitalism is narcissism-driven",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"Header": {
|
||||
"title": "Proxy Raye",
|
||||
"description": "Un proxy per XVideos",
|
||||
"description": "Un proxy per i siti porno",
|
||||
"disclaimer_0": "Quella genitale è solo una delle possibili concezioni della sessualità.",
|
||||
"disclaimer_1": "Le piattaforme monetizzano i flussi di desiderio. I proxy impediscono che questo accada.",
|
||||
"disclaimer_2": "Le piattaforme si alimentano del narcisisismo degli utenti.",
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
import Layout from "@/components/Layout";
|
||||
|
||||
import Home from "@/components/Pages/Home";
|
||||
import { VideoAgent } from "@/utils/agent";
|
||||
|
||||
import { fetchGalleryData } from '@/utils/scrape/xvideos/gallery';
|
||||
import { getPlatformCookie } from "@/utils/cookies/read";
|
||||
|
||||
export default async function HomePage() {
|
||||
|
||||
const data = await fetchGalleryData()
|
||||
const platform = await getPlatformCookie()
|
||||
|
||||
const data = await new VideoAgent(platform).getGallery()
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
|
|
|
@ -2,11 +2,14 @@ import Layout from "@/components/Layout";
|
|||
|
||||
import Search from "@/components/Pages/Search";
|
||||
|
||||
import { fetchGalleryData } from "@/utils/scrape/xvideos/gallery";
|
||||
import { VideoAgent } from "@/utils/agent";
|
||||
import { getPlatformCookie } from "@/utils/cookies/read";
|
||||
|
||||
export default async function SearchPage({ params }: { params: { query: string } }) {
|
||||
|
||||
const data = await fetchGalleryData({ query: params.query })
|
||||
const platform = await getPlatformCookie()
|
||||
|
||||
const data = await new VideoAgent(platform).getGallery({ query: params.query })
|
||||
|
||||
return <Layout>
|
||||
<Search data={data} query={decodeURIComponent(params.query)} />
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
import { redirect } from 'next/navigation';
|
||||
|
||||
import Layout from "@/components/Layout";
|
||||
|
||||
import Video from "@/components/Pages/Video";
|
||||
|
||||
import { decodeVideoUrlPath } from '@/utils/string';
|
||||
|
||||
import { fetchVideoData } from '@/utils/scrape/xvideos/video';
|
||||
|
||||
import { useLocale } from 'next-intl';
|
||||
|
||||
export default async function VideoPage({ params }: { params: { id: string } }) {
|
||||
|
||||
const locale = useLocale()
|
||||
|
||||
const decodedId = decodeVideoUrlPath(params.id)
|
||||
|
||||
const [data, related] = await fetchVideoData(decodedId)
|
||||
|
||||
if (!data.lowResUrl) {
|
||||
redirect(`/${locale}/404`)
|
||||
}
|
||||
|
||||
return <Layout>
|
||||
<Video id={params.id} data={data} related={related}/>
|
||||
</Layout>
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
import { redirect } from 'next/navigation';
|
||||
|
||||
import Layout from "@/components/Layout";
|
||||
|
||||
import Video from "@/components/Pages/Video";
|
||||
|
||||
import { decodeVideoUrlPath } from '@/utils/string';
|
||||
|
||||
import { useLocale } from 'next-intl';
|
||||
import { Platforms } from '@/meta/settings';
|
||||
import { VideoAgent } from '@/utils/agent';
|
||||
|
||||
export default async function VideoPage({ params }: { params: { platform: Platforms, id: string } }) {
|
||||
|
||||
const { platform, id } = params
|
||||
|
||||
const locale = useLocale()
|
||||
|
||||
if (!platform || !Object.keys(Platforms).includes(platform)) {
|
||||
redirect(`/${locale}/404`)
|
||||
}
|
||||
|
||||
const decodedId = decodeVideoUrlPath(id)
|
||||
|
||||
const [data, related] = await new VideoAgent(platform).getVideo(decodedId)
|
||||
|
||||
//const [data, related] = await fetchVideoData(decodedId)
|
||||
|
||||
if (!data.lowResUrl) {
|
||||
redirect(`/${locale}/404`)
|
||||
}
|
||||
|
||||
return <Layout>
|
||||
<Video id={id} data={data} related={related}/>
|
||||
</Layout>
|
||||
}
|
|
@ -10,6 +10,7 @@ import { setCookie } from '@/utils/cookies/write';
|
|||
import { useCookies } from 'react-cookie';
|
||||
|
||||
interface Props {
|
||||
handleClose(): void
|
||||
labels: {
|
||||
title: string,
|
||||
}
|
||||
|
@ -17,7 +18,7 @@ interface Props {
|
|||
|
||||
const Orientation: React.FC<Props> = (props) => {
|
||||
|
||||
const { labels } = props
|
||||
const { labels, handleClose } = props
|
||||
|
||||
const [cookies] = useCookies([Cookies.orientation]);
|
||||
|
||||
|
@ -25,6 +26,8 @@ const Orientation: React.FC<Props> = (props) => {
|
|||
const value = event.target.value;
|
||||
|
||||
await setCookie(Cookies.orientation, value)
|
||||
|
||||
handleClose()
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -10,6 +10,7 @@ import { setCookie } from '@/utils/cookies/write';
|
|||
import { useCookies } from 'react-cookie';
|
||||
|
||||
interface Props {
|
||||
handleClose(): void
|
||||
labels: {
|
||||
title: string,
|
||||
}
|
||||
|
@ -17,7 +18,7 @@ interface Props {
|
|||
|
||||
const Platform: React.FC<Props> = (props) => {
|
||||
|
||||
const { labels } = props
|
||||
const { labels, handleClose } = props
|
||||
|
||||
const [cookies] = useCookies([Cookies.platform]);
|
||||
|
||||
|
@ -25,6 +26,8 @@ const Platform: React.FC<Props> = (props) => {
|
|||
const value = event.target.value;
|
||||
|
||||
await setCookie(Cookies.platform, value)
|
||||
|
||||
handleClose()
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -29,8 +29,8 @@ const LangSwitcher: React.FC<Props> = (props) => {
|
|||
<div className={style.close} onClick={() => { handleClose() }}><IoCloseCircleOutline size={24} /></div>
|
||||
</header>
|
||||
<div className={style.content}>
|
||||
<Platform labels={{ title: labels.platform.title }} />
|
||||
<Orientation labels={{ title: labels.orientation.title }} />
|
||||
<Platform handleClose={handleClose} labels={{ title: labels.platform.title }} />
|
||||
<Orientation handleClose={handleClose} labels={{ title: labels.orientation.title }} />
|
||||
</div>
|
||||
</article>
|
||||
</dialog >
|
||||
|
|
|
@ -9,25 +9,28 @@ import classNames from 'classnames';
|
|||
import Link from 'next/link'
|
||||
|
||||
import style from './Thumbnail.module.scss'
|
||||
|
||||
import { encodeVideoUrlPath } from '@/utils/string';
|
||||
import { Platforms } from '@/meta/settings';
|
||||
|
||||
interface Props {
|
||||
locale: string
|
||||
videoUrl: string
|
||||
imgUrl: string
|
||||
platform: Platforms
|
||||
text: string
|
||||
show: boolean
|
||||
}
|
||||
|
||||
const Thumbnail: React.FC<Props> = (props) => {
|
||||
|
||||
const { locale, videoUrl, imgUrl, text, show } = props
|
||||
const { locale, platform, videoUrl, imgUrl, text, show } = props
|
||||
|
||||
const encodedUri = encodeVideoUrlPath(videoUrl)
|
||||
|
||||
return (
|
||||
<div className={classNames(style.thumbnailContainer, { [style.show]: show } )}>
|
||||
<Link href={`/${locale}/video/${encodedUri}`}>
|
||||
<Link href={`/${locale}/video/${platform}/${encodedUri}`}>
|
||||
<Img className={style.image} src={imgUrl} unloader={<div className={style.imgPlaceholder}></div>} />
|
||||
<div className={style.text}>{text}</div>
|
||||
</Link>
|
||||
|
|
|
@ -27,6 +27,7 @@ const Gallery: React.FC<Props> = (props) => {
|
|||
key={key}
|
||||
imgUrl={elem.imgUrl}
|
||||
videoUrl={elem.videoUrl}
|
||||
platform={elem.platform}
|
||||
text={elem.text}
|
||||
locale={locale} />
|
||||
})}
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
export const XVIDEOS_BASE_URL: string = "https://www.xvideos.com"
|
||||
export const XVIDEOS_BASE_URL_GAY: string = "https://www.xvideos.com/gay"
|
||||
export const XVIDEOS_BASE_URL_TRANS: string = "https://www.xvideos.com/shemale"
|
||||
|
||||
export const XNXX_BASE_URL: string = 'https://www.xnxx.com'
|
||||
|
||||
export const XNXX_BASE_URL_ETERO: string = 'https://www.xnxx.com/best'
|
||||
export const XNXX_BASE_URL_GAY: string = 'https://www.xnxx.com/best-of-gay'
|
||||
export const XNXX_BASE_URL_TRANS: string = 'https://www.xnxx.com/best-of-shemale'
|
||||
|
||||
export const XNXX_BASE_SEARCH: string = 'https://www.xnxx.com/search'
|
|
@ -1,7 +1,15 @@
|
|||
import { Platforms } from "./settings"
|
||||
|
||||
export interface FetchParams {
|
||||
baseUrl?: string
|
||||
query?: string
|
||||
}
|
||||
|
||||
export interface GalleryData {
|
||||
videoUrl: string
|
||||
imgUrl: string
|
||||
text: string
|
||||
platform: Platforms
|
||||
}
|
||||
|
||||
export interface VideoData {
|
||||
|
@ -9,3 +17,8 @@ export interface VideoData {
|
|||
hiResUrl?: string,
|
||||
hlsUrl?: string
|
||||
}
|
||||
|
||||
export interface VideoAgent {
|
||||
getGallery(params?: FetchParams): Promise<GalleryData[]>
|
||||
getVideo(id: string, params?: FetchParams): Promise<[VideoData, GalleryData[]]>
|
||||
}
|
|
@ -27,6 +27,7 @@ export enum Themes {
|
|||
}
|
||||
|
||||
export const DEFAULT_THEME = Themes.light
|
||||
export const DEFAULT_PLATFORM = Platforms.xvideos
|
||||
|
||||
export interface LangOption {
|
||||
label: string;
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
import { FetchParams, GalleryData, VideoData } from "@/meta/data";
|
||||
|
||||
import { Platforms } from "@/meta/settings";
|
||||
|
||||
import { XVideosAgent } from "./scrape/xvideos/agent";
|
||||
import { XNXXAgent } from "./scrape/xnxx/agent";
|
||||
|
||||
const AgentMapper = {
|
||||
[Platforms.xvideos]: XVideosAgent,
|
||||
[Platforms.xnxx]: XNXXAgent
|
||||
}
|
||||
|
||||
export class VideoAgent {
|
||||
platform: Platforms;
|
||||
|
||||
constructor(platform: Platforms) {
|
||||
this.platform = platform
|
||||
}
|
||||
|
||||
public getGallery = async (params?: FetchParams): Promise<GalleryData[]> => {
|
||||
return await new AgentMapper[this.platform]().getGallery(params)
|
||||
}
|
||||
|
||||
public getVideo = async (id: string, params?: FetchParams): Promise<[VideoData, GalleryData[]]> => {
|
||||
return await new AgentMapper[this.platform]().getVideo(id, params)
|
||||
}
|
||||
}
|
|
@ -1,11 +1,17 @@
|
|||
'use server'
|
||||
|
||||
import { Cookies as AppCookies, DEFAULT_PLATFORM, Platforms } from '@/meta/settings';
|
||||
import { cookies } from 'next/headers'
|
||||
|
||||
export async function getCookie(name: string) {
|
||||
export async function getCookie(name: AppCookies) {
|
||||
return cookies().get(name);
|
||||
}
|
||||
|
||||
export async function hasCookie(name: string):Promise<boolean> {
|
||||
export async function hasCookie(name: AppCookies):Promise<boolean> {
|
||||
return cookies().has(name)
|
||||
}
|
||||
|
||||
export async function getPlatformCookie(): Promise<Platforms> {
|
||||
const platformCookie = await getCookie(AppCookies.platform)
|
||||
return platformCookie && platformCookie.value ? platformCookie.value as Platforms : DEFAULT_PLATFORM
|
||||
}
|
|
@ -1,12 +1,13 @@
|
|||
'use server'
|
||||
|
||||
import { Cookies as AppCookies } from '@/meta/settings';
|
||||
import { cookies } from 'next/headers'
|
||||
|
||||
export async function deleteCookie(name: string) {
|
||||
export async function deleteCookie(name: AppCookies) {
|
||||
cookies().delete(name)
|
||||
}
|
||||
|
||||
export async function setCookie(name: string, value: string) {
|
||||
export async function setCookie(name: AppCookies, value: string) {
|
||||
cookies().set(name, value, {
|
||||
sameSite: 'lax',
|
||||
secure: false
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { XVIDEOS_BASE_URL } from "@/constants/urls";
|
||||
import { removeHttpS } from "../string";
|
||||
import { removeHttpS } from "@/utils/string";
|
||||
|
||||
const getRandomUserAgent = (): string => {
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
import { GalleryData } from "@/meta/data";
|
||||
import { Platforms } from "@/meta/settings";
|
||||
|
||||
export const findVideoUrlInsideTagStringByFunctionNameAndExtension = (
|
||||
tagBlock: string, functionName: string, extension: string): string | null => {
|
||||
const start = tagBlock.indexOf(`html5player.${functionName}('`) + `html5player.${functionName}('`.length;
|
||||
const end = tagBlock.toString().indexOf("'", start);
|
||||
|
||||
const substr = tagBlock.substring(start, end);
|
||||
|
||||
if (substr.includes(extension)) {
|
||||
return substr
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
export const findRelatedVideos = (tagBlock: string, platform: Platforms): GalleryData[] | null => {
|
||||
if (!(tagBlock.includes('video_related=['))) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Trova l'inizio e la fine dell'array di oggetti nell'input
|
||||
const start = tagBlock.indexOf('[{');
|
||||
const end = tagBlock.lastIndexOf('}]') + 2;
|
||||
|
||||
// Estrai la sottostringa contenente l'array di oggetti
|
||||
const jsonString = tagBlock.substring(start, end);
|
||||
|
||||
// Parsea la stringa JSON in un array di oggetti
|
||||
const videoRelatedArray = JSON.parse(jsonString);
|
||||
|
||||
// Mappa ogni oggetto nell'array per rinominare le chiavi
|
||||
//@ts-ignore
|
||||
const parsedArray = videoRelatedArray.map(obj => ({
|
||||
//@ts-ignore
|
||||
videoUrl: obj.u,
|
||||
imgUrl: obj.i,
|
||||
text: obj.tf,
|
||||
platform
|
||||
}));
|
||||
|
||||
return parsedArray;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import { FetchParams, GalleryData, VideoAgent, VideoData } from "@/meta/data";
|
||||
import { fetchXNXXGalleryData, } from "./gallery";
|
||||
import { fetchXNXXVideoData } from "./video";
|
||||
|
||||
export class XNXXAgent implements VideoAgent {
|
||||
|
||||
public getGallery = async (params?: FetchParams): Promise<GalleryData[]> => {
|
||||
return await fetchXNXXGalleryData(params)
|
||||
}
|
||||
|
||||
public getVideo = async (id: string, params?: FetchParams): Promise<[VideoData, GalleryData[]]> => {
|
||||
return await fetchXNXXVideoData(id, params)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
import { FetchParams, GalleryData } from '@/meta/data';
|
||||
import axios, { AxiosError } from 'axios';
|
||||
|
||||
import * as cheerio from "cheerio";
|
||||
|
||||
import { getHeaders } from '@/utils/scrape/common/headers';
|
||||
import { getXNXXQueryUrl } from './url';
|
||||
|
||||
import { Platforms } from '@/meta/settings';
|
||||
import { XNXX_BASE_URL } from '@/constants/urls';
|
||||
|
||||
export const fetchXNXXGalleryData = async (params?: FetchParams): Promise<GalleryData[]> => {
|
||||
|
||||
let data: GalleryData[] = [];
|
||||
|
||||
const reqHeaders = getHeaders(XNXX_BASE_URL)
|
||||
|
||||
const queryUrl = await getXNXXQueryUrl(params?.query)
|
||||
|
||||
await axios.get(queryUrl, reqHeaders)
|
||||
|
||||
.then(response => {
|
||||
|
||||
const html = response.data;
|
||||
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
const thumbs = $(".thumb-block");
|
||||
|
||||
thumbs.map((key, thumb) => {
|
||||
|
||||
const videoUrl = $(thumb).find(".thumb a").attr("href")
|
||||
const imgUrl = $(thumb).find(".thumb img").attr("data-src")
|
||||
const text = $(thumb).find(".thumb-under a").attr("title")
|
||||
|
||||
videoUrl && imgUrl && text && data.push({
|
||||
videoUrl,
|
||||
imgUrl,
|
||||
text,
|
||||
platform: Platforms.xnxx
|
||||
})
|
||||
})
|
||||
|
||||
}).catch((error: AxiosError) => {
|
||||
// handle errors
|
||||
});
|
||||
|
||||
|
||||
return data
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
import { XNXX_BASE_SEARCH, XNXX_BASE_URL_ETERO, XNXX_BASE_URL_GAY, XNXX_BASE_URL_TRANS } from '@/constants/urls';
|
||||
import { Cookies, XVideosCatQueryMap, XVideosOrientations } from '@/meta/settings';
|
||||
import { getCookie } from '@/utils/cookies/read';
|
||||
|
||||
export const getXNXXQueryUrl = async (query?: string) => {
|
||||
|
||||
const category = await getCookie(Cookies.orientation)
|
||||
|
||||
if (!category && !query) {
|
||||
return XNXX_BASE_URL_ETERO
|
||||
}
|
||||
|
||||
if (!category && query) {
|
||||
return `${XNXX_BASE_SEARCH}/${query}`
|
||||
}
|
||||
|
||||
if (category && !Object.values(XVideosOrientations).includes(category.value as XVideosOrientations)) {
|
||||
return XNXX_BASE_URL_ETERO
|
||||
}
|
||||
|
||||
if (category && !query) {
|
||||
switch (category.value) {
|
||||
case XVideosOrientations.etero:
|
||||
return XNXX_BASE_URL_ETERO
|
||||
case XVideosOrientations.gay:
|
||||
return XNXX_BASE_URL_GAY
|
||||
case XVideosOrientations.trans:
|
||||
return XNXX_BASE_URL_TRANS
|
||||
default:
|
||||
return XNXX_BASE_URL_ETERO;
|
||||
}
|
||||
}
|
||||
|
||||
if (category && query) {
|
||||
return `${XNXX_BASE_SEARCH}/${XVideosCatQueryMap[category.value as XVideosOrientations]}/${query}`
|
||||
}
|
||||
|
||||
return XNXX_BASE_URL_ETERO
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
import { XNXX_BASE_URL } from '@/constants/urls';
|
||||
import { FetchParams, GalleryData, VideoData } from '@/meta/data';
|
||||
|
||||
import axios, { AxiosError } from 'axios';
|
||||
|
||||
import * as cheerio from "cheerio";
|
||||
|
||||
import { Platforms } from '@/meta/settings';
|
||||
import { findRelatedVideos, findVideoUrlInsideTagStringByFunctionNameAndExtension } from '@/utils/scrape/common/wgcz';
|
||||
import { getHeaders } from '@/utils/scrape/common/headers';
|
||||
|
||||
export const fetchXNXXVideoData = async (videoId: string, params?: FetchParams): Promise<[VideoData, GalleryData[]]> => {
|
||||
|
||||
let data: VideoData = {
|
||||
lowResUrl: ''
|
||||
}
|
||||
|
||||
let related: GalleryData[] = [];
|
||||
|
||||
const host = XNXX_BASE_URL
|
||||
|
||||
const reqHeaders = getHeaders(host)
|
||||
|
||||
const queryUrl = `${host}${videoId}`
|
||||
|
||||
await axios.get(queryUrl, reqHeaders)
|
||||
|
||||
.then(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
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
// populate related gallery
|
||||
scriptTags.map((idx, elem) => {
|
||||
const relatedVideos = findRelatedVideos($(elem).toString(), Platforms.xnxx)
|
||||
|
||||
if (relatedVideos) {
|
||||
related = relatedVideos
|
||||
}
|
||||
})
|
||||
|
||||
}).catch((error: AxiosError) => {
|
||||
// handle errors
|
||||
});
|
||||
|
||||
return [data, related];
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import { FetchParams, GalleryData, VideoAgent, VideoData } from "@/meta/data";
|
||||
import { fetchXVideosGalleryData } from "./gallery";
|
||||
import { fetchXvideosVideoData } from "./video";
|
||||
|
||||
export class XVideosAgent implements VideoAgent {
|
||||
|
||||
public getGallery = async (params?: FetchParams): Promise<GalleryData[]> => {
|
||||
return await fetchXVideosGalleryData(params)
|
||||
}
|
||||
|
||||
public getVideo = async (id: string, params?: FetchParams): Promise<[VideoData, GalleryData[]]> => {
|
||||
return await fetchXvideosVideoData(id, params)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,16 +1,12 @@
|
|||
import { GalleryData } from '@/meta/data';
|
||||
import { FetchParams, GalleryData } from '@/meta/data';
|
||||
import axios, { AxiosError } from 'axios';
|
||||
|
||||
import * as cheerio from "cheerio";
|
||||
import { getHeaders } from '../headers';
|
||||
import { getHeaders } from '@/utils/scrape/common/headers';
|
||||
import { getXVideosQueryUrl } from './url';
|
||||
import { Platforms } from '@/meta/settings';
|
||||
|
||||
interface FetchParams {
|
||||
baseUrl?: string
|
||||
query?: string
|
||||
}
|
||||
|
||||
export const fetchGalleryData = async (params?: FetchParams): Promise<GalleryData[]> => {
|
||||
export const fetchXVideosGalleryData = async (params?: FetchParams): Promise<GalleryData[]> => {
|
||||
|
||||
let data: GalleryData[] = [];
|
||||
|
||||
|
@ -37,7 +33,8 @@ export const fetchGalleryData = async (params?: FetchParams): Promise<GalleryDat
|
|||
videoUrl && imgUrl && text && data.push({
|
||||
videoUrl,
|
||||
imgUrl,
|
||||
text
|
||||
text,
|
||||
platform: Platforms.xvideos
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -1,18 +1,15 @@
|
|||
import { XVIDEOS_BASE_URL } from '@/constants/urls';
|
||||
import { GalleryData, VideoData } from '@/meta/data';
|
||||
import { FetchParams, GalleryData, VideoData } from '@/meta/data';
|
||||
|
||||
import axios, { AxiosError } from 'axios';
|
||||
|
||||
import * as cheerio from "cheerio";
|
||||
import { findRelatedVideos, findVideoUrlInsideTagStringByFunctionNameAndExtension } from '../../string';
|
||||
import { getHeaders } from '../headers';
|
||||
import { getHeaders } from '@/utils/scrape/common/headers';
|
||||
import { Platforms } from '@/meta/settings';
|
||||
|
||||
interface FetchParams {
|
||||
baseUrl?: string
|
||||
query?: string
|
||||
}
|
||||
import { findRelatedVideos, findVideoUrlInsideTagStringByFunctionNameAndExtension } from '@/utils/scrape/common/wgcz';
|
||||
|
||||
export const fetchVideoData = async (videoId: string, params?: FetchParams): Promise<[VideoData, GalleryData[]]> => {
|
||||
export const fetchXvideosVideoData = async (videoId: string, params?: FetchParams): Promise<[VideoData, GalleryData[]]> => {
|
||||
|
||||
let data: VideoData = {
|
||||
lowResUrl: ''
|
||||
|
@ -20,9 +17,11 @@ export const fetchVideoData = async (videoId: string, params?: FetchParams): Pro
|
|||
|
||||
let related: GalleryData[] = [];
|
||||
|
||||
const reqHeaders = getHeaders()
|
||||
const host = XVIDEOS_BASE_URL
|
||||
|
||||
const queryUrl = `${(params && params.baseUrl) ?? XVIDEOS_BASE_URL}${videoId}`
|
||||
const reqHeaders = getHeaders(host)
|
||||
|
||||
const queryUrl = `${host}${videoId}`
|
||||
|
||||
await axios.get(queryUrl, reqHeaders)
|
||||
|
||||
|
@ -30,7 +29,6 @@ export const fetchVideoData = async (videoId: string, params?: FetchParams): Pro
|
|||
|
||||
const html = response.data;
|
||||
|
||||
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
const scriptTags = $("script");
|
||||
|
@ -58,7 +56,7 @@ export const fetchVideoData = async (videoId: string, params?: FetchParams): Pro
|
|||
|
||||
// populate related gallery
|
||||
scriptTags.map((idx, elem) => {
|
||||
const relatedVideos = findRelatedVideos($(elem).toString())
|
||||
const relatedVideos = findRelatedVideos($(elem).toString(), Platforms.xvideos)
|
||||
|
||||
if (relatedVideos) {
|
||||
related = relatedVideos
|
||||
|
|
|
@ -1,46 +1,3 @@
|
|||
import { GalleryData } from "@/meta/data";
|
||||
|
||||
export const findVideoUrlInsideTagStringByFunctionNameAndExtension = (
|
||||
tagBlock: string, functionName: string, extension: string): string | null => {
|
||||
const start = tagBlock.indexOf(`html5player.${functionName}('`) + `html5player.${functionName}('`.length;
|
||||
const end = tagBlock.toString().indexOf("'", start);
|
||||
|
||||
const substr = tagBlock.substring(start, end);
|
||||
|
||||
if (substr.includes(extension)) {
|
||||
return substr
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
export const findRelatedVideos = (tagBlock: string): GalleryData[] | null => {
|
||||
if (!(tagBlock.includes('video_related=['))) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Trova l'inizio e la fine dell'array di oggetti nell'input
|
||||
const start = tagBlock.indexOf('[{');
|
||||
const end = tagBlock.lastIndexOf('}]') + 2;
|
||||
|
||||
// Estrai la sottostringa contenente l'array di oggetti
|
||||
const jsonString = tagBlock.substring(start, end);
|
||||
|
||||
// Parsea la stringa JSON in un array di oggetti
|
||||
const videoRelatedArray = JSON.parse(jsonString);
|
||||
|
||||
// Mappa ogni oggetto nell'array per rinominare le chiavi
|
||||
//@ts-ignore
|
||||
const parsedArray = videoRelatedArray.map(obj => ({
|
||||
//@ts-ignore
|
||||
videoUrl: obj.u,
|
||||
imgUrl: obj.i,
|
||||
text: obj.tf
|
||||
}));
|
||||
|
||||
return parsedArray;
|
||||
}
|
||||
|
||||
export const removeHttpS = (url: string): string => {
|
||||
if (url.startsWith("http://")) {
|
||||
return url.slice(7);
|
||||
|
|
Loading…
Reference in New Issue