Compare commits
5 Commits
v8.2.1-alp
...
v8.3.4-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe225e1090 | ||
|
|
6ed1567f0e | ||
|
|
67445ed648 | ||
|
|
e2c59b032b | ||
|
|
de73724e17 |
66
.github/workflows/playground.yml
vendored
Normal file
66
.github/workflows/playground.yml
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
name: Playground
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@4bc047ad259df6fc24a6c9b0f9a0cb08cf17fbe5 # v2.0.1
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
- name: Install dependencies
|
||||
run: bun install
|
||||
|
||||
- name: Generate Swagger JSON and HTML
|
||||
run: |
|
||||
mkdir public
|
||||
bun run start:dev &
|
||||
sleep 3
|
||||
curl -s http://localhost:3000/docs/json > public/swagger.json
|
||||
cat << 'EOF' > public/index.html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>LustPress API Playground</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui.css" />
|
||||
<style>body { margin: 0; padding: 0; } .swagger-ui .topbar { display: none; }</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
<script src="https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui-bundle.js"></script>
|
||||
<script src="https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui-standalone-preset.js"></script>
|
||||
<script>
|
||||
window.onload = () => {
|
||||
window.ui = SwaggerUIBundle({
|
||||
url: "./swagger.json",
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset],
|
||||
plugins: [SwaggerUIBundle.plugins.DownloadUrl],
|
||||
});
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
uses: peaceiris/actions-gh-pages@v4
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: ./public
|
||||
publish_branch: gh-pages
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -10,4 +10,5 @@ p.ts
|
||||
.idea
|
||||
CHANGELOG.md
|
||||
theme.zip
|
||||
AGENTS.md
|
||||
AGENTS.md
|
||||
lustpress-express
|
||||
14
README.md
14
README.md
@@ -7,8 +7,8 @@
|
||||
<a href="https://codeclimate.com/github/sinkaroid/lustpress/maintainability"><img src="https://api.codeclimate.com/v1/badges/29a2be78f853f9e3a4a3/maintainability" /></a>
|
||||
</p>
|
||||
|
||||
Lustpress was originally named Lust and Express (legacy name) and now runs on **Bun** + **Elysia** a high-performance remake from the ground up using Bun.
|
||||
The motivation of this project is to bring you an actionable data related to pornhub and other r18 sites with gather, similar design pattern, endpoint bindings, and consistent structure in mind.
|
||||
Lustpress was originally named Lust and Express (legacy name) and now runs on **Bun** + **Elysia**.
|
||||
The motivation of this project is carry an actionable data related to pornhub and other r18 sites with gather, similar design pattern, endpoint bindings, and consistent structure in mind.
|
||||
|
||||
<a href="https://sinkaroid.github.io/lustpress">Playground</a> •
|
||||
<a href="https://github.com/sinkaroid/lustpress/blob/master/CONTRIBUTING.md">Contributing</a> •
|
||||
@@ -28,11 +28,11 @@ The motivation of this project is to bring you an actionable data related to por
|
||||
- [Installation](#installation)
|
||||
- [Docker](#docker)
|
||||
- [Manual](#manual)
|
||||
- [Tests case](#tests)
|
||||
- [Tests](#tests)
|
||||
- [Playground](https://sinkaroid.github.io/lustpress)
|
||||
- [Routing](#playground)
|
||||
- [Status response](#status-response)
|
||||
- [Pornhub JS Challenge Solver](#pornhub-js-challenge-solver)
|
||||
- [Ph Challenge Solver](#pornhub-js-challenge-solver)
|
||||
- [CLosing remarks](https://github.com/sinkaroid/lustpress/blob/master/CLOSING_REMARKS.md)
|
||||
- [Alternative links](https://github.com/sinkaroid/lustpress/blob/master/CLOSING_REMARKS.md#alternative-links)
|
||||
- [Pronunciation](#Pronunciation)
|
||||
@@ -99,7 +99,7 @@ REDIS_URL = redis://default:somenicepassword@redis-666.c10.us-east-6-6.ec666.clo
|
||||
EXPIRE_CACHE = 1
|
||||
|
||||
# you must identify your origin, if not set it will use default
|
||||
USER_AGENT = "lustpress/8.2.0-alpha Bun/1.3.13"
|
||||
USER_AGENT = "lustpress/8.2.3-alpha Bun/1.3.13"
|
||||
```
|
||||
|
||||
### Docker
|
||||
@@ -114,7 +114,7 @@ docker run -d \
|
||||
-p 3028:3000 \
|
||||
-e REDIS_URL='redis://default:somenicepassword@redis-666.c10.us-east-6-6.ec666.cloud.redislabs.com:1337' \
|
||||
-e EXPIRE_CACHE='1' \
|
||||
-e USER_AGENT='lustpress/8.2.0-alpha Bun/1.3.13' \
|
||||
-e USER_AGENT='lustpress/8.2.3-alpha Bun/1.3.13' \
|
||||
ghcr.io/sinkaroid/lustpress:latest
|
||||
```
|
||||
|
||||
@@ -129,7 +129,7 @@ docker run -d \
|
||||
- Lustpress testing and hot reload
|
||||
- `bun run start:dev`
|
||||
|
||||
## Running tests
|
||||
## Tests
|
||||
Run the following commands to execute tests for each supported source:
|
||||
|
||||
```bash
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "lustpress",
|
||||
"version": "8.2.1-alpha",
|
||||
"version": "8.3.4-alpha",
|
||||
"description": "RESTful and experimental API for PH and other R18 websites",
|
||||
"main": "src/index.ts",
|
||||
"scripts": {
|
||||
|
||||
@@ -25,12 +25,14 @@ function cachedLocationOrUnknown(): string {
|
||||
class LustPress {
|
||||
url: 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 } = {};
|
||||
|
||||
constructor() {
|
||||
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> {
|
||||
@@ -77,7 +79,10 @@ class LustPress {
|
||||
|
||||
async fetchBody(url: string): Promise<Buffer> {
|
||||
const cached = await keyv.get(url);
|
||||
if (cached) return cached;
|
||||
if (cached) {
|
||||
console.log(`[CACHE HIT] ${url}`);
|
||||
return cached;
|
||||
}
|
||||
|
||||
const isPornhub = /pornhub\.com/i.test(url);
|
||||
const domain = new URL(url).hostname;
|
||||
@@ -96,21 +101,25 @@ class LustPress {
|
||||
headers["Accept-Language"] = "en-US,en;q=0.9";
|
||||
}
|
||||
|
||||
console.log(`[FETCH] ${url}`);
|
||||
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...");
|
||||
this.cookieCache[domain] = await this.getPornhubCookies();
|
||||
res = await fetch(url, {
|
||||
headers: { ...headers, Cookie: this.cookieCache[domain] },
|
||||
redirect: "follow"
|
||||
});
|
||||
text = await res.text();
|
||||
arrayBuf = await res.arrayBuffer();
|
||||
body = Buffer.from(arrayBuf);
|
||||
}
|
||||
|
||||
const body = Buffer.from(text);
|
||||
if (!url.includes("/random")) await keyv.set(url, body, ttl);
|
||||
if (res.ok && !url.includes("/random")) {
|
||||
await keyv.set(url, body, ttl);
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
|
||||
15
src/index.ts
15
src/index.ts
@@ -32,7 +32,6 @@ const app = new Elysia()
|
||||
}))
|
||||
.use(scrapeRoutes)
|
||||
.onError(({ code, error, set }) => {
|
||||
console.log("Error occurred:", error);
|
||||
if (code === "NOT_FOUND") {
|
||||
set.status = 404;
|
||||
return {
|
||||
@@ -40,6 +39,20 @@ const app = new Elysia()
|
||||
message: (error as Error).message || "Not Found",
|
||||
};
|
||||
}
|
||||
if (code === "VALIDATION") {
|
||||
set.status = 400;
|
||||
return {
|
||||
success: false,
|
||||
message: JSON.parse((error as Error).message)[0]?.message || "Validation Error",
|
||||
};
|
||||
}
|
||||
if (code === "UNKNOWN") {
|
||||
set.status = 400;
|
||||
return {
|
||||
success: false,
|
||||
message: (error as Error).message,
|
||||
};
|
||||
}
|
||||
set.status = 500;
|
||||
return {
|
||||
success: false,
|
||||
|
||||
Reference in New Issue
Block a user