Goon — self-hosted aggregator for adult-content scene metadata. Indexes scenes from TPDB, StashDB, and 30+ public adult tube sites. Cross-source deduplication via perceptual hash + Levenshtein distance. FastAPI backend + APScheduler worker + React Native (Expo) mobile client. FOSS, ad-free, donation-funded. See README for details.
304 lines
14 KiB
HTML
304 lines
14 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
|
<meta name="description" content="Goon — self-hosted adult content metadata aggregator. Mobile-first, FOSS, ad-free." />
|
|
<meta name="robots" content="noindex, nofollow" />
|
|
<title>goon · self-hosted adult content aggregator</title>
|
|
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<script>
|
|
tailwind.config = {
|
|
theme: {
|
|
extend: {
|
|
colors: {
|
|
bg: '#08090F',
|
|
bgElevated: '#11131C',
|
|
card: '#1A1D2A',
|
|
border: '#262A3D',
|
|
accent: '#8B5CF6',
|
|
accentGlow: '#A78BFA',
|
|
accentDeep: '#5B21B6',
|
|
good: '#10B981',
|
|
},
|
|
fontFamily: {
|
|
sans: ['-apple-system', 'BlinkMacSystemFont', 'Inter', 'system-ui', 'sans-serif'],
|
|
mono: ['ui-monospace', 'SFMono-Regular', 'Menlo', 'monospace'],
|
|
},
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style>
|
|
body { background-color: #08090F; color: #F4F4F8; }
|
|
.glow { box-shadow: 0 0 60px -10px rgba(139, 92, 246, 0.4); }
|
|
.grad { background: radial-gradient(60% 60% at 50% 0%, rgba(139,92,246,0.18) 0%, rgba(8,9,15,0) 70%); }
|
|
.card-hover { transition: transform 200ms ease, border-color 200ms ease; }
|
|
.card-hover:hover { transform: translateY(-2px); border-color: #8B5CF6; }
|
|
.pulse-dot { animation: pulse 2.5s ease-in-out infinite; }
|
|
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }
|
|
</style>
|
|
</head>
|
|
|
|
<body class="font-sans antialiased">
|
|
|
|
<!-- AGE GATE -->
|
|
<div id="agegate" class="fixed inset-0 z-50 bg-bg flex items-center justify-center px-6">
|
|
<div class="max-w-md text-center">
|
|
<div class="inline-block w-3 h-3 rounded-full bg-accent glow pulse-dot mb-6"></div>
|
|
<h1 class="text-3xl font-extrabold tracking-tight mb-3">18+ Adults Only</h1>
|
|
<p class="text-sm text-gray-400 mb-8 leading-relaxed">
|
|
This site discusses software for indexing adult content. You must be of legal
|
|
age in your jurisdiction to enter.
|
|
</p>
|
|
<div class="flex gap-3 justify-center">
|
|
<button onclick="document.getElementById('agegate').style.display='none'"
|
|
class="px-6 py-3 rounded-xl bg-accent text-white font-bold hover:bg-accentDeep transition">
|
|
I'm 18 or older
|
|
</button>
|
|
<a href="https://www.google.com"
|
|
class="px-6 py-3 rounded-xl bg-bgElevated border border-border text-gray-300 font-semibold">
|
|
Take me out
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- HERO -->
|
|
<header class="grad relative pt-20 pb-24 px-6 overflow-hidden">
|
|
<div class="max-w-5xl mx-auto">
|
|
<div class="flex items-center gap-2 mb-8">
|
|
<div class="w-3 h-3 rounded-full bg-accent glow"></div>
|
|
<span class="text-sm font-bold tracking-widest text-gray-300 uppercase">goon</span>
|
|
</div>
|
|
|
|
<h1 class="text-5xl md:text-7xl font-extrabold tracking-tight leading-[0.95] mb-6">
|
|
Self-hosted<br>
|
|
<span class="text-accent">scene catalog</span><br>
|
|
for grown-ups.
|
|
</h1>
|
|
|
|
<p class="text-lg md:text-xl text-gray-400 max-w-2xl leading-relaxed mb-10">
|
|
Goon indexes scene metadata from TPDB & StashDB, deduplicates across
|
|
30+ public tubes, and serves a fast mobile client. Zero ads. Zero tracking.
|
|
Your data stays on your VPS.
|
|
</p>
|
|
|
|
<div class="flex flex-wrap gap-3">
|
|
<a href="https://github.com/REPLACE_PERSONA/goon/releases/latest"
|
|
class="px-6 py-4 rounded-xl bg-accent text-white font-bold hover:bg-accentDeep transition glow">
|
|
Download APK
|
|
</a>
|
|
<a href="https://github.com/REPLACE_PERSONA/goon"
|
|
class="px-6 py-4 rounded-xl bg-bgElevated border border-border text-gray-200 font-semibold hover:border-accent transition">
|
|
View source on GitHub
|
|
</a>
|
|
<a href="#donate"
|
|
class="px-6 py-4 rounded-xl bg-transparent border border-border text-gray-400 font-semibold hover:text-accent hover:border-accent transition">
|
|
♥ Support project
|
|
</a>
|
|
</div>
|
|
|
|
<p class="text-xs text-gray-500 mt-6 font-mono">
|
|
Android only · self-hosted backend required · 18+
|
|
</p>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- FEATURES -->
|
|
<section class="px-6 py-20 bg-bgElevated/30 border-y border-border">
|
|
<div class="max-w-5xl mx-auto">
|
|
<h2 class="text-3xl font-extrabold mb-2 tracking-tight">What it does</h2>
|
|
<p class="text-gray-500 mb-12 max-w-xl">
|
|
Goon is not a tube. It does not host, transcode, or proxy content.
|
|
It is a metadata aggregator + mobile UI for finding scenes that are
|
|
already publicly available.
|
|
</p>
|
|
|
|
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
<div class="card-hover bg-card border border-border rounded-2xl p-6">
|
|
<div class="text-accent text-2xl mb-3">⌬</div>
|
|
<h3 class="text-lg font-bold mb-2">Multi-source ingest</h3>
|
|
<p class="text-sm text-gray-400 leading-relaxed">
|
|
TPDB & StashDB metadata + 30+ public tubes. Cross-source
|
|
deduplication via perceptual-hash thumbnails + title-Levenshtein matching.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="card-hover bg-card border border-border rounded-2xl p-6">
|
|
<div class="text-accent text-2xl mb-3">⌖</div>
|
|
<h3 class="text-lg font-bold mb-2">Per-performer backfill</h3>
|
|
<p class="text-sm text-gray-400 leading-relaxed">
|
|
A continuous worker walks performers by staleness and back-fills tube scenes
|
|
for the longest-stale first. Completeness over recency.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="card-hover bg-card border border-border rounded-2xl p-6">
|
|
<div class="text-accent text-2xl mb-3">⌥</div>
|
|
<h3 class="text-lg font-bold mb-2">Smart stream resolution</h3>
|
|
<p class="text-sm text-gray-400 leading-relaxed">
|
|
yt-dlp for mainstream tubes + P.A.C.K.E.R. unpacker for JWPlayer hosters
|
|
+ WebView fallback for IP-bound CDNs. Streams direct from source, no transcoding.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="card-hover bg-card border border-border rounded-2xl p-6">
|
|
<div class="text-accent text-2xl mb-3">⌗</div>
|
|
<h3 class="text-lg font-bold mb-2">Mobile-first UI</h3>
|
|
<p class="text-sm text-gray-400 leading-relaxed">
|
|
React Native + Expo. Scene grid, performer pages, watch history,
|
|
favorites, hold-to-preview thumbnails. Built for thumb scrolling.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="card-hover bg-card border border-border rounded-2xl p-6">
|
|
<div class="text-accent text-2xl mb-3">⌘</div>
|
|
<h3 class="text-lg font-bold mb-2">Privacy by default</h3>
|
|
<p class="text-sm text-gray-400 leading-relaxed">
|
|
App lock (PIN + biometrics), FLAG_SECURE screenshot block, age gate.
|
|
No analytics. No telemetry unless YOU configure Sentry with your own DSN.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="card-hover bg-card border border-border rounded-2xl p-6">
|
|
<div class="text-accent text-2xl mb-3">⌬</div>
|
|
<h3 class="text-lg font-bold mb-2">100% self-hosted</h3>
|
|
<p class="text-sm text-gray-400 leading-relaxed">
|
|
One <code class="text-accent font-mono text-xs">docker compose up -d</code>
|
|
and you own the API, the DB, the worker. No SaaS dependencies.
|
|
Your search history is yours.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- SCREENSHOTS -->
|
|
<section class="px-6 py-20">
|
|
<div class="max-w-5xl mx-auto">
|
|
<h2 class="text-3xl font-extrabold mb-2 tracking-tight">In the app</h2>
|
|
<p class="text-gray-500 mb-12">Screen-shots from a real install — censored where needed.</p>
|
|
|
|
<!-- Placeholder grid: replace with real screen-shots when ready -->
|
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-3">
|
|
<div class="aspect-[9/19.5] rounded-2xl bg-card border border-border flex items-center justify-center text-gray-600 text-xs font-mono">
|
|
Scenes grid
|
|
</div>
|
|
<div class="aspect-[9/19.5] rounded-2xl bg-card border border-border flex items-center justify-center text-gray-600 text-xs font-mono">
|
|
Scene detail
|
|
</div>
|
|
<div class="aspect-[9/19.5] rounded-2xl bg-card border border-border flex items-center justify-center text-gray-600 text-xs font-mono">
|
|
Performer page
|
|
</div>
|
|
<div class="aspect-[9/19.5] rounded-2xl bg-card border border-border flex items-center justify-center text-gray-600 text-xs font-mono">
|
|
Favorites
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- QUICK START -->
|
|
<section class="px-6 py-20 bg-bgElevated/30 border-y border-border">
|
|
<div class="max-w-3xl mx-auto">
|
|
<h2 class="text-3xl font-extrabold mb-3 tracking-tight">Quick start</h2>
|
|
<p class="text-gray-500 mb-8">5 commands. Backend runs in 30 seconds on any Docker host.</p>
|
|
|
|
<div class="bg-card border border-border rounded-2xl p-6 font-mono text-sm leading-relaxed">
|
|
<div class="text-gray-500">$ <span class="text-gray-300">git clone https://github.com/REPLACE_PERSONA/goon.git</span></div>
|
|
<div class="text-gray-500">$ <span class="text-gray-300">cd goon && cp .env.example .env</span></div>
|
|
<div class="text-gray-500">$ <span class="text-gray-300"># edit .env: set TPDB_API_TOKEN, STASHDB_API_KEY, API_KEYS</span></div>
|
|
<div class="text-gray-500">$ <span class="text-gray-300">docker compose up -d</span></div>
|
|
<div class="text-gray-500">$ <span class="text-gray-300">curl localhost:8000/health</span></div>
|
|
<div class="text-good text-xs mt-3">{"status":"ok"}</div>
|
|
</div>
|
|
|
|
<p class="text-sm text-gray-500 mt-6">
|
|
Then download the APK above, point it at your backend, paste an API key.
|
|
Full docs in the
|
|
<a href="https://github.com/REPLACE_PERSONA/goon#readme" class="text-accent hover:underline">README</a>.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- DONATE -->
|
|
<section id="donate" class="px-6 py-20">
|
|
<div class="max-w-3xl mx-auto">
|
|
<h2 class="text-3xl font-extrabold mb-3 tracking-tight">Support the project</h2>
|
|
<p class="text-gray-400 mb-8 leading-relaxed max-w-xl">
|
|
Goon stays free and ad-free because donations cover the VPS, the
|
|
TPDB/StashDB tokens, and the time. <strong class="text-gray-200">Crypto
|
|
only</strong> — mainstream processors won't touch adult-adjacent
|
|
FOSS projects.
|
|
</p>
|
|
|
|
<div class="grid sm:grid-cols-3 gap-3">
|
|
<div class="bg-card border border-border rounded-2xl p-5">
|
|
<div class="text-orange-500 text-xs font-mono font-bold mb-1">XMR</div>
|
|
<div class="text-sm font-bold mb-3">Monero</div>
|
|
<p class="text-xs text-gray-500 leading-relaxed">
|
|
Privacy by default. Recommended. Get the address from the app or the project README.
|
|
</p>
|
|
</div>
|
|
<div class="bg-card border border-border rounded-2xl p-5">
|
|
<div class="text-yellow-500 text-xs font-mono font-bold mb-1">BTC</div>
|
|
<div class="text-sm font-bold mb-3">Bitcoin</div>
|
|
<p class="text-xs text-gray-500 leading-relaxed">
|
|
Mainstream & easy to send. Use a fresh wallet if you care about on-chain anonymity.
|
|
</p>
|
|
</div>
|
|
<div class="bg-card border border-border rounded-2xl p-5">
|
|
<div class="text-blue-400 text-xs font-mono font-bold mb-1">LTC</div>
|
|
<div class="text-sm font-bold mb-3">Litecoin</div>
|
|
<p class="text-xs text-gray-500 leading-relaxed">
|
|
Fast and cheap (~$0.01 fee). Lower adoption than BTC but friendlier for small donations.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<p class="text-xs text-gray-500 mt-6">
|
|
Addresses are hard-coded in
|
|
<code class="font-mono text-accent">mobile/src/lib/donate.ts</code>
|
|
and shown in the app under Scenes » ♥. Always verify on-screen
|
|
against the repo before sending.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- FOOTER -->
|
|
<footer class="px-6 py-12 border-t border-border">
|
|
<div class="max-w-5xl mx-auto flex flex-col sm:flex-row gap-6 justify-between text-xs text-gray-500">
|
|
<div>
|
|
<div class="flex items-center gap-2 mb-2">
|
|
<div class="w-2 h-2 rounded-full bg-accent"></div>
|
|
<span class="font-bold tracking-widest uppercase">goon</span>
|
|
</div>
|
|
<p>Self-hosted adult content metadata aggregator.</p>
|
|
<p>MIT license. No warranty. 18+ jurisdictions only.</p>
|
|
</div>
|
|
<div class="flex flex-col gap-1 text-right">
|
|
<a href="https://github.com/REPLACE_PERSONA/goon" class="hover:text-accent transition">GitHub</a>
|
|
<a href="https://github.com/REPLACE_PERSONA/goon/releases" class="hover:text-accent transition">Releases</a>
|
|
<a href="https://github.com/REPLACE_PERSONA/goon#readme" class="hover:text-accent transition">Docs</a>
|
|
</div>
|
|
</div>
|
|
<p class="max-w-5xl mx-auto mt-6 text-[10px] text-gray-600 leading-relaxed">
|
|
Goon does not host, transcode, store, or distribute any media. It scrapes
|
|
publicly-available metadata and links out to the source. Operators are
|
|
responsible for complying with local law. See README » Disclaimer.
|
|
</p>
|
|
</footer>
|
|
|
|
<script>
|
|
// Persist age-gate acknowledgement so it doesn't reappear every visit.
|
|
if (localStorage.getItem('agegate_v1') === 'ok') {
|
|
document.getElementById('agegate').style.display = 'none';
|
|
}
|
|
document.querySelector('#agegate button').addEventListener('click', function () {
|
|
localStorage.setItem('agegate_v1', 'ok');
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|