5 Commits

Author SHA1 Message Date
Indrawan I.
67be3acc6e fix: proper error handler (#23)
* re use legacy errors

* 8.3.6-alpha
2026-05-14 09:56:52 +07:00
SNEK WAIFU
e92cb6ca8a ee 2026-05-14 08:09:23 +07:00
SNEK WAIFU
85a45cf575 eeee 2026-05-14 08:09:04 +07:00
SNEK WAIFU
fe225e1090 8.3.4-alpha 2026-05-14 07:25:26 +07:00
SNEK WAIFU
6ed1567f0e need testing 2026-05-14 07:24:58 +07:00
4 changed files with 85 additions and 66 deletions

3
.gitignore vendored
View File

@@ -10,4 +10,5 @@ p.ts
.idea .idea
CHANGELOG.md CHANGELOG.md
theme.zip theme.zip
AGENTS.md AGENTS.md
lustpress-express

View File

@@ -1,6 +1,6 @@
{ {
"name": "lustpress", "name": "lustpress",
"version": "8.2.4-alpha", "version": "8.3.6-alpha",
"description": "RESTful and experimental API for PH and other R18 websites", "description": "RESTful and experimental API for PH and other R18 websites",
"main": "src/index.ts", "main": "src/index.ts",
"scripts": { "scripts": {

View File

@@ -25,12 +25,14 @@ function cachedLocationOrUnknown(): string {
class LustPress { class LustPress {
url: string; url: string;
useragent: string; useragent: string;
private browserUA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"; private browserUA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36";
private cookieCache: { [domain: string]: string } = {}; private cookieCache: { [domain: string]: string } = {};
constructor() { constructor() {
this.url = ""; this.url = "";
this.useragent = `${pkg.name}/${pkg.version} Bun/${Bun.version}`; this.browserUA =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36";
this.useragent = process.env.USER_AGENT || `${pkg.name}/${pkg.version} Bun/${Bun.version}`;
} }
async getPornhubCookies(): Promise<string> { async getPornhubCookies(): Promise<string> {
@@ -86,7 +88,7 @@ class LustPress {
const domain = new URL(url).hostname; const domain = new URL(url).hostname;
const headers: Record<string, string> = { const headers: Record<string, string> = {
"User-Agent": isPornhub ? this.browserUA : this.useragent, "User-Agent": isPornhub ? this.browserUA : this.useragent
}; };
if (isPornhub) { if (isPornhub) {
@@ -101,20 +103,23 @@ class LustPress {
console.log(`[FETCH] ${url}`); console.log(`[FETCH] ${url}`);
let res = await fetch(url, { headers, redirect: "follow" }); let res = await fetch(url, { headers, redirect: "follow" });
let text = await res.text(); let arrayBuf = await res.arrayBuffer();
let body = Buffer.from(arrayBuf);
if (isPornhub && text.includes("leastFactor")) { if (isPornhub && body.toString("utf8").includes("leastFactor")) {
console.log("Challenge detected at target URL. Re-authenticating..."); console.log("Challenge detected at target URL. Re-authenticating...");
this.cookieCache[domain] = await this.getPornhubCookies(); this.cookieCache[domain] = await this.getPornhubCookies();
res = await fetch(url, { res = await fetch(url, {
headers: { ...headers, Cookie: this.cookieCache[domain] }, headers: { ...headers, Cookie: this.cookieCache[domain] },
redirect: "follow" redirect: "follow"
}); });
text = await res.text(); arrayBuf = await res.arrayBuffer();
body = Buffer.from(arrayBuf);
} }
const body = Buffer.from(text); if (res.ok && !url.includes("/random")) {
if (!url.includes("/random")) await keyv.set(url, body, ttl); await keyv.set(url, body, ttl);
}
return body; return body;
} }

View File

@@ -1,56 +1,69 @@
import { Elysia } from "elysia"; import { Elysia } from "elysia";
import { cors } from "@elysiajs/cors"; import { cors } from "@elysiajs/cors";
import { swagger } from "@elysiajs/swagger"; import { swagger } from "@elysiajs/swagger";
import { lust } from "./LustPress"; import { lust } from "./LustPress";
import { scrapeRoutes } from "./router/endpoint"; import { scrapeRoutes } from "./router/endpoint";
import pkg from "../package.json"; import pkg from "../package.json";
const app = new Elysia() const app = new Elysia()
.use(cors()) .use(cors())
.use( .use(
swagger({ swagger({
path: "/docs", path: "/docs",
documentation: { documentation: {
info: { info: {
title: "Lustpress API", title: "Lustpress API",
version: pkg.version, version: pkg.version,
description: pkg.description, description: pkg.description,
}, },
}, },
}) })
) )
.get("/", async () => ({ .get("/", async () => ({
success: true, success: true,
playground: "https://sinkaroid.github.io/lustpress", playground: "https://sinkaroid.github.io/lustpress",
endpoint: endpoint:
"https://github.com/sinkaroid/lustpress/blob/master/README.md#routing", "https://github.com/sinkaroid/lustpress/blob/master/README.md#routing",
date: new Date().toLocaleString(), date: new Date().toLocaleString(),
rss: lust.currentProccess().rss, rss: lust.currentProccess().rss,
heap: lust.currentProccess().heap, heap: lust.currentProccess().heap,
server: await lust.getServer(), server: await lust.getServer(),
version: pkg.version, version: pkg.version,
})) }))
.use(scrapeRoutes) .onError(({ code, error, set }) => {
.onError(({ code, error, set }) => { if (code === "NOT_FOUND") {
console.log("Error occurred:", error); set.status = 404;
if (code === "NOT_FOUND") { return {
set.status = 404; success: false,
return { message: (error as Error).message || "Not Found",
success: false, };
message: (error as Error).message || "Not Found", }
}; if (code === "VALIDATION") {
} set.status = 400;
set.status = 500; return {
return { success: false,
success: false, message: JSON.parse((error as Error).message)[0]?.message || "Validation Error",
message: (error as Error).message || "Internal Server Error", };
stack: (error as Error).stack, }
}; if (code === "UNKNOWN") {
}) set.status = 400;
.listen(process.env.PORT || 3000); return {
success: false,
console.log( message: (error as Error).message,
`Lustpress is running at ${app.server?.hostname}:${app.server?.port}` };
); }
set.status = 500;
export type App = typeof app; return {
success: false,
message: (error as Error).message || "Internal Server Error",
stack: (error as Error).stack,
};
})
.use(scrapeRoutes) // reuse legacy error handling
.listen(process.env.PORT || 3000);
console.log(
`Lustpress is running at ${app.server?.hostname}:${app.server?.port}`
);
export type App = typeof app;