Skip to content

V2 — datanodes rebuilt, fuckingfast rebuilt, new GUI

Choose a tag to compare

@LeyckerS LeyckerS released this 30 Jul 18:10
f2b4604

V2 — datanodes rebuilt, fuckingfast rebuilt, new GUI

Everything since V1 (tag v14.1). Both providers changed how they hand out links, so both
extraction methods were rewritten from scratch, the interface left tkinter, and the
settings panel was split per method — because the two methods no longer share one.

195.7 MB/s · 124 fuckingfast links · 8 DL streams · 12.63 GB in 1m23s · 29 done, 0 failed —
and not one browser window, because no datanodes link was in the batch.


🔧 datanodes.to — rebuilt on real Chrome

The old flow stopped working end to end. It now runs on a real Chrome/Edge the app
spawns itself with --remote-debugging-port and attaches to over CDP, on a persistent
profile
.

  • Cloudflare Turnstile is handled — auto-solve, with a manual fallback and a
    configurable wait. The old blocklist contained challenges.cloudflare, so the widget
    could never even load, and it blocked stylesheets, which collapses every
    getBoundingClientRect() to 0×0 and left the button finder blind.
  • Not Playwright's Chromium any more. Turnstile rejects it — automation switches, not
    a Google-branded build, empty profile → Verification failed / Error 600010. It also
    issues no token to a headless browser at all (the challenge platform answers 401 on
    its /pat/ endpoint), so datanodes runs visible on purpose.
  • The profile is the point: the cf_clearance cookie survives between links, so
    later files get challenged less. Solve one, the session coasts.
  • One shared window, Pages tabs on it (1–8). Separate contexts per worker were
    tried and measured worse: multiple identities from one IP read as a bot farm and
    Turnstile hard-failed.
  • Exactly one POST /download per link — a second one re-runs SecSave server-side
    and invalidates the token the countdown step is holding. The old extractor tripped this
    by submitting the form and then click-hunting for "free download".
  • The form is armed at ~6 s by the site's own Vue scan; submitting at t=0 got nowhere.
  • Crash recovery: the shared Chrome used to die after ~80 sequential extractions and
    take the whole rest of the session with it. It is now re-validated and respawned
    transparently.
  • Premium API key (optional): extraction becomes a single JSON GET — no browser, no
    captcha, no countdown.

⚡ fuckingfast.co — rebuilt on plain HTTP, ~0.25 s per link

  • The /dl/ URL is not in the page any more. The landing page is Alpine + htmx and
    the direct URL exists only in the hx-redirect response header of
    POST /f/{id}/go. The old regex was searching for something the server stopped sending.
  • Cloudflare fingerprints TLS. aiohttp's ClientHello scores as a bot and gets
    cf-mitigated: challenge403 on every link, whatever headers you send.
    Extraction moved to curl_cffi, which impersonates Chrome's ClientHello and sails
    through. Downloads stay on aiohttp — dl.fuckingfast.co serves the file with full
    Range support.
  • No browser, no captcha, nothing to tune. ~0.25 s per link, measured against live
    FitGirl parts.
  • Fragment filenames fixed: links carry the name as a URL fragment
    (.../abc123#Game.part01.rar), which a naive split turned into a bogus file id.
  • curl_cffi>=0.7 is now required for this provider.

🖥️ New GUI — Edge WebView2, not tkinter

tkinter's canvas has no anti-aliasing and no alpha channel: arcs and rounded corners came
out as steps, glows as opaque bands. Its type was absolute, so on a 2560×1440 screen the
text measured ~8 px of ink and a third of the window sat empty.

  • Renders in Edge WebView2 — the same Chromium already on Windows 10/11. Real
    anti-aliasing, real alpha, gradients, blur, GPU transitions.
  • start.bat starts a loopback server and opens Edge or Chrome with --app: a window
    with no tabs and no address bar. No native GUI dependency, nothing to install.
  • Live transfer rows — one per file: progress ring, state, percentage, instantaneous
    speed. Active transfers sort above the finished tail.
  • Stats — 3 s rolling speed with sparkline, completed count, downloaded bytes,
    byte-based ETA. Extraction and download are tracked separately, because they run at the
    same time.
  • Link editor — per-host colouring while you paste, live count,
    datanodes / fuckingfast / others split.
  • English / Italian, switchable at runtime.
  • Type scales with the window (clamp()), so a big monitor gets a big interface.

⚙️ Settings — split per method, and out of the environment

One "Browsers" slider described an architecture that no longer exists. Three panels now:

Panel Settings
Common Extractors (2–32) · DL streams (2–48) · Retries (0–5)
datanodes Pages (1–8) · Captcha wait (30–600 s) · Chrome path · API key
fuckingfast nothing to tune — it declares it
  • The datanodes knobs used to be environment variables needing setx and a restart.
    They are in the GUI now and pushed into the extraction layer on every run.
  • Defaults retuned: captcha wait 240 s → 30 s, pages 3 → 8.
  • Settings and pasted links persist across restarts in settings.json (atomic write).
  • Every value the page sends is coerced and clamped before it reaches a semaphore.

🚫 Chrome no longer opens for links that don't need it

Every front-end used to open a browser per worker at the top of a run, before reading
a single URL. A batch of nothing but fuckingfast links — pure HTTP, no browser needed —
still put a Chrome window on screen and paid ~1.5 s of Playwright driver boot.

The launch now lives in one place and fires on the first datanodes link: no datanodes
link, no Chrome, no driver, not even the node process. One shared instance no matter how
many extractors race for it. Same behaviour in the GUI and the CLI, asserted by
python test_no_chrome.py on every push.

🐛 Also fixed

  • Transfer count showed the row cap (40) instead of transfers in flight — a 124-file
    session reported "40 active"
  • The Log tab rendered the transfer list on top of the log
  • Progress rings always rendered empty — a CSS declaration outranks an SVG presentation
    attribute, so setting stroke-dasharray in JS lost to the stylesheet
  • The loopback API replied 403 without draining the request body, so the next keep-alive
    request on that connection was parsed as garbage and answered 501
  • The whole repository is English — launcher output, engine warnings, Tk labels, OS dialog
    titles, module docstrings and test assertions. The GUI keeps its runtime EN/IT switch.
  • --browsers / Extractors is documented as what it is: parallel extraction workers,
    not one browser each

📦 What's in the box

start.bat          the GUI            moon_engine.py    the engine, no GUI attached
moon_bridge.py     window host + API  moon_extract.py   both extraction methods
web/               the interface      moon_cli.py       headless CLI

2 Python files in V1 → 8 modules and a web interface, ~4.1k lines of Python.

Renamed — every filename is English and says what it is: avvia.batstart.bat,
gen_cli.pymoon_cli.py, shots.pyrender_gui.py.

Removed:

  • The tkinter GUI and the generator that fed on it (gen_1.py/moon_tk.py,
    avvia_tk.bat, apply_web_v16.py). It was a second interface to maintain for the same
    engine — and it was the file moon_engine.py was generated from, which made the legacy
    GUI the source of truth for the modern engine. moon_engine.py now stands on its own;
    pillow leaves the requirements with it.
  • apply_patch.py, the v14.1 → v14.8 migration patcher: against the current tree it
    half-applies instead of failing.
  • prep_assets.py, a one-shot asset builder whose inputs were never committed.

📚 Documentation

Page Contents
Quick start install, first run, what each setting does
Configuration every setting, every environment variable, the Chrome profile
Providers how each host is extracted, and how to add another
Architecture how V2 is built, feature by feature
Engineering notes the measurements behind the design decisions
Troubleshooting 403s, Turnstile failures, CDP conflicts, stalls

📊 Benchmark

Metric Value
Peak ~250 MB/s
Measured run (screenshot) 195.7 MB/s · 124 fuckingfast links · 12.63 GB in 1m23s · 0 failed
Connection 2.5 Gbps fiber
Session 23.5 GB across 47 files in ~3 minutes
Settings 16 extractors / 8 DL streams / 3 retries
Providers datanodes.to · fuckingfast.co

🚀 Quick start

  1. Install Python 3.10+ — tick Add Python to PATH
  2. Download Source code (zip) below and extract it
  3. Double-click start.bat
  4. Done — the first run installs the dependencies and the Chromium build

Requirements: Windows 10/11 (the GUI needs Edge or Chrome, both ship with Chromium) ·
Python 3.10+ · aiohttp, playwright, curl_cffi · ~150 MB of disk for the Playwright
Chromium, which is only the datanodes fallback.