Skip to content

feat(downloads): support general direct URLs (keep FF/DataNodes resolver) - #19

Closed
arousi wants to merge 6 commits into
billysams21:devfrom
arousi:fix/general-downloads
Closed

feat(downloads): support general direct URLs (keep FF/DataNodes resolver)#19
arousi wants to merge 6 commits into
billysams21:devfrom
arousi:fix/general-downloads

Conversation

@arousi

@arousi arousi commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Normalizes the download path so any plain direct URL works, not just FuckingFast/DataNodes.

Any link whose host isn't a Turnstile provider now downloads straight over HTTP (urllib) with resume/pause/progress. FuckingFast and DataNodes links still go through get_direct_link (the nodriver Turnstile solver) + curl transport, exactly as before.

  • providers.py (new, Qt-free) holds RESOLVER_HOSTS + needs_resolution(), unit-tested in test_providers.py (resolver hosts incl. subdomains, general hosts, look-alike hosts, malformed input).
  • download_worker routes non-resolver hosts (and updates) to a host-agnostic _download_direct_file().
  • Paste box hint broadened to mention direct URLs.

Stacked

Built on top of #18 (updater-via-queue). Please merge #18 first; afterwards this PR's diff collapses to just the general-downloads change. Both touch the top of download_worker.

Verified

python test_providers.py (3) + offscreen routing smoke: a general URL downloads with 0 solver calls; a fuckingfast link invokes the solver exactly once.

arousi added 6 commits August 22, 2026 06:16
The old modal UpdateDownloaderDialog streamed the whole release zip while
flooding the GUI thread with per-chunk cross-thread progress calls; on a
large (205MB) release, concurrent with the live-graph update_ui, it could
crash the app mid-download.

Route updates through the existing, proven download engine instead:
- an available update is added to the normal queue as a DownloadTask
  (is_update); the user starts it and can pause/resume (Range-resume) it
  like any other download
- update tasks bypass the Cloudflare/CAPTCHA direct-link step and are never
  auto-extracted
- on completion the app offers Install now (restart) or Install on next
  open; a deferred update is applied via _check_pending_update on launch
- execute_update -> _apply_downloaded_update(zip_path): the robust
  extract -> robocopy swap -> marker-verify -> rollback flow is unchanged,
  it just consumes the already-downloaded zip

Removes the crash-prone modal download path entirely.
Root cause of the 'added but never progresses / connection timed out':
the queued update task ran through download_worker on a manager-spawned
thread and reused the shared curl_cffi self.dl_session. That session
(built on the main thread) hangs with curl (28) for a plain request that
never went through the nodriver/get_direct_link path first — normal
downloads work only because get_direct_link runs before the transfer.

Route update tasks through a dedicated _download_update_file() using urllib
(stdlib): supports Range-resume, pause/cancel, progress, and a 416
already-complete short-circuit. Confirmed progressing via the real manager
path where curl deterministically hung. Also stop a previously failed
update task from blocking a fresh re-offer.
Update downloads were written to a hidden ~/.silverspoon_updates folder, so
users couldn't find the completed file. Download to the same Save-To
directory as every other download (…/SilverSpoon Update <version>/), so it's
visible, consistent, and persists for an install-on-next-open.
Guard the completion prompt and the re-offer dedup on os.path.exists(filepath)
so a stale Completed update task (file deleted/moved) neither fires a phantom
install prompt nor blocks re-downloading.
…aNodes

Normalize the download path: any link whose host isn't a Turnstile/CAPTCHA
host now downloads straight over HTTP via urllib (the same robust path used
for app updates), with resume/pause/progress. FuckingFast and DataNodes
links still go through get_direct_link (the nodriver Turnstile solver) + the
curl transport exactly as before.

- add needs_resolution(link) + RESOLVER_HOSTS = (fuckingfast.co, datanodes.to)
- download_worker routes non-resolver hosts (and updates) to the renamed,
  now host-agnostic _download_direct_file()
- broaden the paste-box hint to mention direct URLs

Verified: general URL downloads without invoking the solver; a fuckingfast
link still invokes get_direct_link exactly once.
@arousi

arousi commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #27, which carries this change together with the other four fixes on top of v1.5.1 as a single PR from my fork's main.

@arousi arousi closed this Sep 8, 2026
@arousi
arousi deleted the fix/general-downloads branch September 8, 2026 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant