feat(downloads): support general direct URLs (keep FF/DataNodes resolver) - #19
Closed
arousi wants to merge 6 commits into
Closed
feat(downloads): support general direct URLs (keep FF/DataNodes resolver)#19arousi wants to merge 6 commits into
arousi wants to merge 6 commits into
Conversation
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.
This was referenced Aug 22, 2026
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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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) holdsRESOLVER_HOSTS+needs_resolution(), unit-tested intest_providers.py(resolver hosts incl. subdomains, general hosts, look-alike hosts, malformed input).download_workerroutes non-resolver hosts (and updates) to a host-agnostic_download_direct_file().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.