hottub skill
This commit is contained in:
323
SKILL.md
Normal file
323
SKILL.md
Normal file
@@ -0,0 +1,323 @@
|
||||
---
|
||||
name: hottub
|
||||
description: Work on the Hottub Rust server. Use this skill when you need the real build/run commands, compile-time single-provider builds, runtime env vars, API and proxy endpoint trigger examples, or yt-dlp verification steps for returned media URLs.
|
||||
---
|
||||
|
||||
# Hottub
|
||||
|
||||
Hottub is a Rust `ntex` server. The main entrypoints are:
|
||||
|
||||
- `src/main.rs`: server startup, env loading, root redirect, `/api`, `/proxy`, static files
|
||||
- `src/api.rs`: `/api/status`, `/api/videos`, `/api/test`, `/api/proxies`
|
||||
- `src/proxy.rs`: `/proxy/...` redirect and media/image proxy routes
|
||||
- `src/providers/mod.rs`: provider registry, compile-time provider selection, channel metadata
|
||||
- `src/util/requester.rs`: outbound HTTP, Burp proxy support, FlareSolverr fallback
|
||||
|
||||
## Build and run
|
||||
|
||||
Default local run:
|
||||
|
||||
```bash
|
||||
cargo run
|
||||
```
|
||||
|
||||
Run with compiled-in debug logs:
|
||||
|
||||
```bash
|
||||
cargo run --features debug
|
||||
```
|
||||
|
||||
Compile a single-provider binary:
|
||||
|
||||
```bash
|
||||
HOT_TUB_PROVIDER=hsex cargo build
|
||||
```
|
||||
|
||||
Single-provider binary with debug logs:
|
||||
|
||||
```bash
|
||||
HOT_TUB_PROVIDER=hsex cargo run --features debug
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- `HOT_TUB_PROVIDER` is the preferred compile-time selector.
|
||||
- `HOTTUB_PROVIDER` is also supported as a fallback alias.
|
||||
- Single-provider builds register only that provider at compile time, so other providers are not constructed and their init paths do not run.
|
||||
- In a single-provider build, `/api/videos` requests with `"channel": "all"` are remapped to the compiled provider.
|
||||
- The server binds to `0.0.0.0:18080`.
|
||||
|
||||
Useful checks:
|
||||
|
||||
```bash
|
||||
cargo check -q
|
||||
HOT_TUB_PROVIDER=hsex cargo check -q
|
||||
HOT_TUB_PROVIDER=hsex cargo check -q --features debug
|
||||
```
|
||||
|
||||
## Environment
|
||||
|
||||
Runtime env vars:
|
||||
|
||||
- `DATABASE_URL` required. SQLite path, for example `hottub.db`.
|
||||
- `RUST_LOG` optional. Defaults to `warn` if unset.
|
||||
- `PROXY` optional. Any value other than `"0"` enables proxy mode in the shared requester.
|
||||
- `BURP_URL` optional. Outbound HTTP proxy used when `PROXY` is enabled.
|
||||
- `FLARE_URL` optional but strongly recommended for provider work. Used for FlareSolverr fallback and some providers that call it directly.
|
||||
- `DOMAIN` optional. Used for the `/` redirect target.
|
||||
- `DISCORD_WEBHOOK` optional. Enables `/api/test` and provider error reporting to Discord.
|
||||
|
||||
Build-time env vars:
|
||||
|
||||
- `HOT_TUB_PROVIDER` optional. Compile only one provider into the binary.
|
||||
- `HOTTUB_PROVIDER` optional fallback alias for the same purpose.
|
||||
|
||||
Practical `.env` baseline:
|
||||
|
||||
```dotenv
|
||||
DATABASE_URL=hottub.db
|
||||
RUST_LOG=info
|
||||
PROXY=0
|
||||
BURP_URL=http://127.0.0.1:8081
|
||||
FLARE_URL=http://127.0.0.1:8191/v1
|
||||
DOMAIN=127.0.0.1:18080
|
||||
DISCORD_WEBHOOK=
|
||||
```
|
||||
|
||||
## Endpoint surface
|
||||
|
||||
Root:
|
||||
|
||||
- `GET /`
|
||||
- Returns `302 Found`
|
||||
- Redirects to `hottub://source?url=<DOMAIN-or-request-host>`
|
||||
|
||||
Status API:
|
||||
|
||||
- `GET /api/status`
|
||||
- `POST /api/status`
|
||||
- Returns the server status and channel list
|
||||
- The `User-Agent` matters because channel visibility can depend on parsed client version
|
||||
|
||||
Videos API:
|
||||
|
||||
- `POST /api/videos`
|
||||
- Main provider execution endpoint
|
||||
- Body is JSON matching `VideosRequest` in `src/videos.rs`
|
||||
|
||||
Diagnostics:
|
||||
|
||||
- `GET /api/test`
|
||||
- Sends a Discord test error if `DISCORD_WEBHOOK` is configured
|
||||
- `GET /api/proxies`
|
||||
- Returns the current outbound proxy snapshot
|
||||
|
||||
Proxy endpoints:
|
||||
|
||||
- Redirect proxies:
|
||||
- `GET|POST /proxy/sxyprn/{endpoint}*`
|
||||
- `GET|POST /proxy/javtiful/{endpoint}*`
|
||||
- `GET|POST /proxy/spankbang/{endpoint}*`
|
||||
- `GET|POST /proxy/porndish/{endpoint}*`
|
||||
- `GET|POST /proxy/pimpbunny/{endpoint}*`
|
||||
- Media/image proxies:
|
||||
- `GET|POST /proxy/noodlemagazine/{endpoint}*`
|
||||
- `GET|POST /proxy/noodlemagazine-thumb/{endpoint}*`
|
||||
- `GET|POST /proxy/hanime-cdn/{endpoint}*`
|
||||
- `GET|POST /proxy/hqporner-thumb/{endpoint}*`
|
||||
- `GET|POST /proxy/porndish-thumb/{endpoint}*`
|
||||
- `GET|POST /proxy/pimpbunny-thumb/{endpoint}*`
|
||||
|
||||
Everything else under `/` is served from `static/`.
|
||||
|
||||
## How to trigger endpoints
|
||||
|
||||
Verify the root redirect:
|
||||
|
||||
```bash
|
||||
curl -i http://127.0.0.1:18080/
|
||||
```
|
||||
|
||||
Fetch status with a Hot Tub-like user agent:
|
||||
|
||||
```bash
|
||||
curl -s \
|
||||
-H 'User-Agent: Hot%20Tub/22c CFNetwork/1494.0.7 Darwin/23.4.0' \
|
||||
http://127.0.0.1:18080/api/status | jq
|
||||
```
|
||||
|
||||
Equivalent `POST /api/status`:
|
||||
|
||||
```bash
|
||||
curl -s -X POST http://127.0.0.1:18080/api/status | jq
|
||||
```
|
||||
|
||||
Minimal videos request:
|
||||
|
||||
```bash
|
||||
curl -s http://127.0.0.1:18080/api/videos \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'User-Agent: Hot%20Tub/22c CFNetwork/1494.0.7 Darwin/23.4.0' \
|
||||
-d '{"channel":"hsex","sort":"date","page":1,"perPage":10}' | jq
|
||||
```
|
||||
|
||||
Use `"all"` against a normal multi-provider build:
|
||||
|
||||
```bash
|
||||
curl -s http://127.0.0.1:18080/api/videos \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"channel":"all","sort":"date","page":1,"perPage":10}' | jq
|
||||
```
|
||||
|
||||
Use `"all"` against a single-provider build:
|
||||
|
||||
```bash
|
||||
HOT_TUB_PROVIDER=hsex cargo run --features debug
|
||||
curl -s http://127.0.0.1:18080/api/videos \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"channel":"all","sort":"date","page":1,"perPage":10}' | jq
|
||||
```
|
||||
|
||||
Literal query behavior:
|
||||
|
||||
- Quoted queries are treated as literal substring filters after provider fetch.
|
||||
- Leading `#` is stripped before matching.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
curl -s http://127.0.0.1:18080/api/videos \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"channel":"hsex","query":"\"teacher\"","page":1,"perPage":10}' | jq
|
||||
```
|
||||
|
||||
Trigger the Discord test route:
|
||||
|
||||
```bash
|
||||
curl -i http://127.0.0.1:18080/api/test
|
||||
```
|
||||
|
||||
Inspect proxy state:
|
||||
|
||||
```bash
|
||||
curl -s http://127.0.0.1:18080/api/proxies | jq
|
||||
```
|
||||
|
||||
Trigger a redirect proxy and inspect the `Location` header:
|
||||
|
||||
```bash
|
||||
curl -I 'http://127.0.0.1:18080/proxy/spankbang/some/provider/path'
|
||||
```
|
||||
|
||||
Trigger a media proxy directly:
|
||||
|
||||
```bash
|
||||
curl -I 'http://127.0.0.1:18080/proxy/noodlemagazine/some/media/path'
|
||||
```
|
||||
|
||||
## Videos request fields
|
||||
|
||||
Commonly useful request keys:
|
||||
|
||||
- `channel`
|
||||
- `sort`
|
||||
- `query`
|
||||
- `page`
|
||||
- `perPage`
|
||||
- `featured`
|
||||
- `category`
|
||||
- `sites`
|
||||
- `all_provider_sites`
|
||||
- `filter`
|
||||
- `language`
|
||||
- `networks`
|
||||
- `stars`
|
||||
- `categories`
|
||||
- `duration`
|
||||
- `sexuality`
|
||||
|
||||
Most provider debugging only needs:
|
||||
|
||||
```json
|
||||
{
|
||||
"channel": "hsex",
|
||||
"sort": "date",
|
||||
"query": null,
|
||||
"page": 1,
|
||||
"perPage": 10
|
||||
}
|
||||
```
|
||||
|
||||
## Recommended provider-debug workflow
|
||||
|
||||
1. Build only the provider you care about.
|
||||
2. Run with `--features debug`.
|
||||
3. Hit `/api/status` to confirm only the expected channel is present.
|
||||
4. Hit `/api/videos` with either the provider id or `"all"`.
|
||||
5. Inspect `.items[0].url`, `.items[0].formats`, `.items[0].thumb`, and any local `/proxy/...` URLs.
|
||||
6. Verify the media URL with `yt-dlp`.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
HOT_TUB_PROVIDER=hsex cargo run --features debug
|
||||
curl -s http://127.0.0.1:18080/api/status | jq '.channels[].id'
|
||||
curl -s http://127.0.0.1:18080/api/videos \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"channel":"all","page":1,"perPage":1}' | tee /tmp/hottub-video.json | jq
|
||||
```
|
||||
|
||||
## yt-dlp verification
|
||||
|
||||
Use `yt-dlp` to prove that a returned video URL or format is actually consumable.
|
||||
|
||||
Check the primary item URL:
|
||||
|
||||
```bash
|
||||
URL="$(jq -r '.items[0].url' /tmp/hottub-video.json)"
|
||||
yt-dlp -v --simulate "$URL"
|
||||
```
|
||||
|
||||
Prefer the first explicit format when present:
|
||||
|
||||
```bash
|
||||
FORMAT_URL="$(jq -r '.items[0].formats[0].url' /tmp/hottub-video.json)"
|
||||
yt-dlp -v -F "$FORMAT_URL"
|
||||
yt-dlp -v --simulate "$FORMAT_URL"
|
||||
```
|
||||
|
||||
If the format contains required HTTP headers, pass them through:
|
||||
|
||||
```bash
|
||||
yt-dlp -v --simulate \
|
||||
--add-header 'Referer: https://example.com/' \
|
||||
--add-header 'User-Agent: Mozilla/5.0 ...' \
|
||||
"$FORMAT_URL"
|
||||
```
|
||||
|
||||
If you want to build the command from JSON:
|
||||
|
||||
```bash
|
||||
FORMAT_URL="$(jq -r '.items[0].formats[0].url' /tmp/hottub-video.json)"
|
||||
mapfile -t HDRS < <(
|
||||
jq -r '.items[0].formats[0].http_headers // {} | to_entries[] | "--add-header=\(.key): \(.value)"' \
|
||||
/tmp/hottub-video.json
|
||||
)
|
||||
yt-dlp -v --simulate "${HDRS[@]}" "$FORMAT_URL"
|
||||
```
|
||||
|
||||
For local proxy URLs returned by Hottub, verify the server endpoint directly:
|
||||
|
||||
```bash
|
||||
LOCAL_URL="$(jq -r '.items[0].formats[0].url // .items[0].url' /tmp/hottub-video.json)"
|
||||
yt-dlp -v --simulate "$LOCAL_URL"
|
||||
```
|
||||
|
||||
## Interaction rules
|
||||
|
||||
- Prefer compile-time single-provider builds for provider work.
|
||||
- Prefer `/api/status` before `/api/videos` so you know what channels the current binary exposes.
|
||||
- When reproducing client-specific issues, send a realistic `User-Agent`.
|
||||
- When debugging fetch failures, enable `debug` and set `FLARE_URL`.
|
||||
- When debugging outbound request behavior, set `PROXY=1` and `BURP_URL=...`.
|
||||
- Use `/api/test` only when you intentionally want a Discord notification.
|
||||
Reference in New Issue
Block a user