feat: use Playwright challenge and reuse cookies scraper (#17)
* adjust eslint * playground depreciation warning * adjust some tests * playwright simulate run instead just raw phin * adjusted ci * vibe debugging * update all deps, small ci changes, and strict dockerized build
This commit is contained in:
@@ -4,9 +4,6 @@ import c from "../../utils/options";
|
||||
import { logger } from "../../utils/logger";
|
||||
import { maybeError } from "../../utils/modifier";
|
||||
import { Request, Response } from "express";
|
||||
import LustPress from "../../LustPress";
|
||||
|
||||
const lust = new LustPress();
|
||||
|
||||
export async function randomEporner(req: Request, res: Response) {
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { scrapeContent } from "../../scraper/eporner/epornerSearchController";
|
||||
import c from "../../utils/options";
|
||||
import { logger } from "../../utils/logger";
|
||||
import { maybeError, spacer } from "../../utils/modifier";
|
||||
import { maybeError } from "../../utils/modifier";
|
||||
import { Request, Response } from "express";
|
||||
|
||||
export async function searchEporner(req: Request, res: Response) {
|
||||
@@ -45,28 +45,28 @@ export async function searchEporner(req: Request, res: Response) {
|
||||
if (isNaN(page)) throw Error("Parameter page must be a number");
|
||||
|
||||
const slug = key
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.replace(/\s+/g, "-");
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.replace(/\s+/g, "-");
|
||||
|
||||
const url =
|
||||
page === 1
|
||||
? `${c.EPORNER}/tag/${slug}/`
|
||||
: `${c.EPORNER}/tag/${slug}/${page}/`;
|
||||
? `${c.EPORNER}/tag/${slug}/`
|
||||
: `${c.EPORNER}/tag/${slug}/${page}/`;
|
||||
|
||||
const data = await scrapeContent(url);
|
||||
|
||||
logger.info({
|
||||
path: req.path,
|
||||
query: req.query,
|
||||
method: req.method,
|
||||
ip: req.ip,
|
||||
useragent: req.get("User-Agent")
|
||||
path: req.path,
|
||||
query: req.query,
|
||||
method: req.method,
|
||||
ip: req.ip,
|
||||
useragent: req.get("User-Agent")
|
||||
});
|
||||
|
||||
return res.json(data);
|
||||
} catch (err) {
|
||||
} catch (err) {
|
||||
const e = err as Error;
|
||||
res.status(400).json(maybeError(false, e.message));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ function getRelatedApiUrl(videoId: string, page = 1, count = 50): string {
|
||||
const thousand = Math.floor(id / 1_000) * 1_000;
|
||||
|
||||
return (
|
||||
`https://txxx.com/api/json/videos_related2/` +
|
||||
"https://txxx.com/api/json/videos_related2/" +
|
||||
`432000/${count}/${million}/${thousand}/${id}.all.${page}.json`
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,53 +6,53 @@ import { logger } from "../../utils/logger";
|
||||
const lust = new LustPress();
|
||||
|
||||
export async function randomTxxx(req: Request, res: Response) {
|
||||
try {
|
||||
const apiUrl =
|
||||
try {
|
||||
const apiUrl =
|
||||
"https://txxx.com/api/json/videos2/14400/str/most-popular/60/..1.all..day.json";
|
||||
|
||||
const buffer = await lust.fetchBody(apiUrl);
|
||||
const rawData = JSON.parse(buffer.toString("utf-8"));
|
||||
const buffer = await lust.fetchBody(apiUrl);
|
||||
const rawData = JSON.parse(buffer.toString("utf-8"));
|
||||
|
||||
const videos = Array.isArray(rawData.videos)
|
||||
? rawData.videos
|
||||
: [];
|
||||
const videos = Array.isArray(rawData.videos)
|
||||
? rawData.videos
|
||||
: [];
|
||||
|
||||
if (videos.length === 0) {
|
||||
throw new Error("No videos returned from upstream");
|
||||
}
|
||||
|
||||
// Pick one random video
|
||||
const v = videos[Math.floor(Math.random() * videos.length)];
|
||||
|
||||
const data = {
|
||||
video_id: v.video_id,
|
||||
title: v.title,
|
||||
dir: v.dir,
|
||||
duration: v.duration,
|
||||
views: v.video_viewed,
|
||||
rating: v.rating,
|
||||
uploaded: v.post_date,
|
||||
likes: v.likes,
|
||||
dislikes: v.dislikes,
|
||||
image: v.scr,
|
||||
categories: v.categories ? v.categories.split(",") : [],
|
||||
embed: `https://txxx.com/embed/${v.video_id}/`,
|
||||
};
|
||||
|
||||
logger.info({
|
||||
path: req.path,
|
||||
method: req.method,
|
||||
ip: req.ip,
|
||||
useragent: req.get("User-Agent"),
|
||||
});
|
||||
|
||||
return res.json({
|
||||
success: true,
|
||||
data,
|
||||
source: apiUrl,
|
||||
});
|
||||
} catch (err) {
|
||||
const e = err as Error;
|
||||
return res.status(400).json(maybeError(false, e.message));
|
||||
if (videos.length === 0) {
|
||||
throw new Error("No videos returned from upstream");
|
||||
}
|
||||
|
||||
// Pick one random video
|
||||
const v = videos[Math.floor(Math.random() * videos.length)];
|
||||
|
||||
const data = {
|
||||
video_id: v.video_id,
|
||||
title: v.title,
|
||||
dir: v.dir,
|
||||
duration: v.duration,
|
||||
views: v.video_viewed,
|
||||
rating: v.rating,
|
||||
uploaded: v.post_date,
|
||||
likes: v.likes,
|
||||
dislikes: v.dislikes,
|
||||
image: v.scr,
|
||||
categories: v.categories ? v.categories.split(",") : [],
|
||||
embed: `https://txxx.com/embed/${v.video_id}/`,
|
||||
};
|
||||
|
||||
logger.info({
|
||||
path: req.path,
|
||||
method: req.method,
|
||||
ip: req.ip,
|
||||
useragent: req.get("User-Agent"),
|
||||
});
|
||||
|
||||
return res.json({
|
||||
success: true,
|
||||
data,
|
||||
source: apiUrl,
|
||||
});
|
||||
} catch (err) {
|
||||
const e = err as Error;
|
||||
return res.status(400).json(maybeError(false, e.message));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,59 +5,59 @@ import { maybeError } from "../../utils/modifier";
|
||||
const lust = new LustPress();
|
||||
|
||||
export async function searchTxxx(req: Request, res: Response) {
|
||||
try {
|
||||
const key = String(req.query.key || "").trim();
|
||||
const page = Number(req.query.page || 1);
|
||||
try {
|
||||
const key = String(req.query.key || "").trim();
|
||||
const page = Number(req.query.page || 1);
|
||||
|
||||
if (!key) {
|
||||
return res.json({
|
||||
success: false,
|
||||
error: "Parameter key is required",
|
||||
});
|
||||
}
|
||||
if (!key) {
|
||||
return res.json({
|
||||
success: false,
|
||||
error: "Parameter key is required",
|
||||
});
|
||||
}
|
||||
|
||||
if (Number.isNaN(page)) {
|
||||
return res.json({
|
||||
success: false,
|
||||
error: "Parameter page must be a number",
|
||||
});
|
||||
}
|
||||
if (Number.isNaN(page)) {
|
||||
return res.json({
|
||||
success: false,
|
||||
error: "Parameter page must be a number",
|
||||
});
|
||||
}
|
||||
|
||||
const apiUrl =
|
||||
`https://txxx.com/api/videos2.php` +
|
||||
const apiUrl =
|
||||
"https://txxx.com/api/videos2.php" +
|
||||
`?params=259200/str/relevance/60/search..${page}.all..` +
|
||||
`&s=${encodeURIComponent(key)}`;
|
||||
|
||||
// Fetch from API directly
|
||||
const buffer = await lust.fetchBody(apiUrl);
|
||||
const rawData = JSON.parse(buffer.toString("utf-8"));
|
||||
// Fetch from API directly
|
||||
const buffer = await lust.fetchBody(apiUrl);
|
||||
const rawData = JSON.parse(buffer.toString("utf-8"));
|
||||
|
||||
const videos = Array.isArray(rawData.videos) ? rawData.videos : [];
|
||||
const videos = Array.isArray(rawData.videos) ? rawData.videos : [];
|
||||
|
||||
const data = videos.map((v: any) => ({
|
||||
video_id: v.video_id,
|
||||
title: v.title,
|
||||
dir: v.dir,
|
||||
duration: v.duration,
|
||||
views: v.video_viewed,
|
||||
rating: v.rating,
|
||||
uploaded: v.post_date,
|
||||
likes: v.likes,
|
||||
dislikes: v.dislikes,
|
||||
image: v.scr,
|
||||
categories: v.categories ? v.categories.split(",") : [],
|
||||
embed: `https://txxx.com/embed/${v.video_id}/`,
|
||||
}));
|
||||
const data = videos.map((v: any) => ({
|
||||
video_id: v.video_id,
|
||||
title: v.title,
|
||||
dir: v.dir,
|
||||
duration: v.duration,
|
||||
views: v.video_viewed,
|
||||
rating: v.rating,
|
||||
uploaded: v.post_date,
|
||||
likes: v.likes,
|
||||
dislikes: v.dislikes,
|
||||
image: v.scr,
|
||||
categories: v.categories ? v.categories.split(",") : [],
|
||||
embed: `https://txxx.com/embed/${v.video_id}/`,
|
||||
}));
|
||||
|
||||
return res.json({
|
||||
success: true,
|
||||
total_count: String(rawData.total_count ?? videos.length),
|
||||
pages: Number(rawData.pages ?? 1),
|
||||
page,
|
||||
data,
|
||||
});
|
||||
} catch (err) {
|
||||
const e = err as Error;
|
||||
return res.json(maybeError(false, e.message));
|
||||
}
|
||||
return res.json({
|
||||
success: true,
|
||||
total_count: String(rawData.total_count ?? videos.length),
|
||||
pages: Number(rawData.pages ?? 1),
|
||||
page,
|
||||
data,
|
||||
});
|
||||
} catch (err) {
|
||||
const e = err as Error;
|
||||
return res.json(maybeError(false, e.message));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user