Skip to content

Releases

v0.3.16

Choose a tag to compare

@izzoa izzoa released this 05 Jul 17:56

Two complementary fixes for the freemagazines.top → LimeWire download path: the site now rotates share links after takedowns, and LimeWire changed its share-page serialization. Either one alone left downloads failing with an identical "share link is unavailable" error; both are needed to download reliably.

Fixed

  • Downloads 404'd on live, browser-downloadable shares. LimeWire's share page moved its server-rendered data to a React Router turbo-stream — a flat array where fields are index references rather than inline values — but establish_session still extracted bucket_id and content_item_id by text position. It picked up the neighboring UUIDs (the file-encryption-key id as the bucket, the free-user-id as the content item), so POST /sharing/download/{bucket} returned 404, surfacing as the same "share link is unavailable" message a genuinely removed share produces. magsync now decodes the turbo-stream and reads metadata structurally (sharingBucket.id, contentItemList[0].id, the fileEncryptionKeys entry bound to the content item's baseFileEncryptionKeyId, ephemeralPublicKey, name, totalFileSize), verified end-to-end against a live share (valid PDF, correct byte count).
  • file_size read 0 for every share (the progress bar/estimate source) — totalFileSize is now taken from the decoded stream.
  • Rotated LimeWire links were never picked up, and issues parked unavailable never recovered. freemagazines.top swaps the LimeWire share link on an existing post when the old share is taken down (without bumping the post's modified time), but the index treated limewire_url as write-once — so every cycle re-scraped the fresh link, discarded it, and re-downloaded with the frozen dead one until the issue was parked unavailable with no path back (retry reused the stale URL, backfill-urls only fixed NULL URLs). Now:
    • Refresh on re-scrape: add_issues() replaces a stored limewire_url when a re-scrape yields a validated, different link, and resets that issue's failed/unavailable download back to pending so the fresh link is retried (the sha256, and any complete/in-flight download, are left untouched). The incoming URL is checked with a strict host/path/fragment guard before it can overwrite a known-good value.
    • Re-scrape on permanent failure: when a download fails with a permanent "share link is unavailable" error, the batch downloader re-scrapes the page once; if it now carries a different validated link, that link is persisted and the download is retried immediately (once). Only if the page still shows the same dead link — or the re-scrape yields nothing — is the issue parked unavailable.

Changed

  • The legacy regex extraction is retained only as a fallback for when the SSR format changes wholesale (no decodable stream); it never overrides ids resolved from a present stream, so a partial format drift fails loudly instead of silently shipping the wrong (decoy) ids.
  • Removed-share detection gained a structural backstop: a decoded container reporting ok:false is classified permanent even when the SanitizedError marker falls outside the raw-HTML detector's window; a container merely missing ok is treated as undecodable, never as removed.
  • .part resume files are now keyed to the share link that produced them (a hash of the full URL, including the decryption-key fragment). A refreshed or rotated link starts a clean download instead of resuming bytes from a different encrypted blob (which would decrypt to garbage and misfire self-healing). Legacy un-keyed .part files are discarded once on upgrade and re-downloaded.
  • download_batch() de-duplicates its input by issue ID, so overlapping subscriptions that enqueue the same issue no longer download it twice (and a dead link is re-scraped at most once per batch).

Docker image: ghcr.io/izzoa/magsync:0.3.16 (also :0.3, :latest)

Full changelog: https://github.com/izzoa/magsync/blob/v0.3.16/CHANGELOG.md

v0.3.14

Choose a tag to compare

@izzoa izzoa released this 17 Jun 10:56

Fixed

  • Removed LimeWire shares were retried forever. After LimeWire changed its share-page SSR serialization (JSON objects → React-Router streaming arrays), the dead-share detector stopped matching, so removed shares (SanitizedError) were misclassified as a transient "Unexpected Server Error" and retried every cycle — and, since 0.3.13, tripped the shared throttle pause, stalling the batch. Detection is now format-agnostic and anchored to the share's error tuple, so removed shares are correctly marked unavailable and skipped. Run magsync retry to re-attempt if a link returns.
  • SSR error classification now runs before JWT/CSRF extraction, so a removed page that omits the auth cookie is still classified correctly.
  • A download-API 404 (bucket removed) is now treated as permanent (unavailable) instead of retried.

Full changelog: https://github.com/izzoa/magsync/blob/v0.3.14/CHANGELOG.md

v0.3.11

Choose a tag to compare

@izzoa izzoa released this 07 Apr 17:24

Fixed

  • MAGSYNC_DOWNLOAD__RETRY_ATTEMPTS env var now actually takes effect in batch/daemon downloads.

Changed

  • retry_attempts semantics: 0 = no retry, N = N retries after initial attempt. Default is 2 (3 total attempts, same as before).

v0.3.10

Choose a tag to compare

@izzoa izzoa released this 07 Apr 17:07

Changed

  • retry_attempts now means number of retries after the initial attempt:
    • 0 = try once, no retry
    • 2 = 3 total attempts (1 initial + 2 retries)
  • Default changed from 3 to 2 to preserve the same 3-total-attempts behavior.
  • Session establishment retry also respects this setting (previously hardcoded).

v0.3.9

Choose a tag to compare

@izzoa izzoa released this 07 Apr 17:02

Changed

  • Session retry count now respects download.retry_attempts config setting (previously hardcoded to 3). Configurable via config.toml, MAGSYNC_DOWNLOAD__RETRY_ATTEMPTS env var, or magsync config download.retry_attempts <N>.
  • Updated README directory tree and organization docs to reflect flat file layout (Komga/Kavita compatible).
  • Added MAGSYNC_DOWNLOAD__RETRY_ATTEMPTS to README environment variables table.

v0.3.7

Choose a tag to compare

@izzoa izzoa released this 07 Apr 14:47

Fixed

  • LimeWire "Unexpected Server Error" SSR responses (common from cloud/datacenter IPs) are now treated as transient and retried with backoff, instead of being permanently marked as dead links. Only SanitizedError (genuinely removed shares) is permanent.
  • Session establishment now retries up to 3 times with 5s/10s delays for transient SSR errors before falling back to the outer download retry loop.

Changed

  • Improved diagnostic logging for LimeWire error detection: logs now include the sharing ID, response size, and which specific error pattern triggered.

v0.3.6

Choose a tag to compare

@izzoa izzoa released this 07 Apr 11:04

Fixed

  • Stop marking transient decryption and constant-refresh failures as permanent unavailable errors.
  • Limit permanent failure classification to genuinely dead LimeWire share links so recoverable issues can be retried normally.