Shelve (15+ failures) now mimics manual stop/start behavior:
- Clears item.provider for fresh provider selection on retry
- Resets provider circuit breaker (providerFailures) for the old provider
- Reduces shelve duration from 5 min to 90s since the issue is stale
provider state, not a timing problem (manual restart works instantly)
Also adds comprehensive session-load logging:
- Logs package/item count on every session file read
- Logs errors when session file parsing fails (was silent before)
- Safety net: if primary session is empty but backup has packages,
automatically restores from backup
- Logs shutdown save with package/item counts
- Logs DownloadManager init state and cleanup policy
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The inner unrestrict error handler still called recordProviderFailure()
for hosterNotAvailable errors, causing provider-level cooldown escalation
(up to 180s) even though the issue is hoster-side, not provider-side.
This made auto-retry stall while manual reset worked instantly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
hosterNotAvailable was added to isTemporaryUnrestrictError which
triggered aggressive provider-level cooldowns (up to 180s) that
blocked ALL items for the affected provider. Since items kept
failing, the cooldown never expired (15-min reset threshold never
reached), causing retries to effectively stall.
Fix: remove hosterNotAvailable from isTemporaryUnrestrictError.
It still gets normal unrestrict retry with item-level backoff
(5s -> 120s) via isUnrestrictFailure, but without provider-wide
cooldown blocking other items.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move hosterNotAvailable from isPermanentLinkError to
isTemporaryUnrestrictError — hoster being unavailable is usually
transient (overload, maintenance) and should be retried with backoff
instead of immediately failing as "Link ungültig".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backup redesign (JDownloader 2 style):
- AES-256-GCM encrypted .mdd format with fixed app key
- All credentials exported (no more ***-masking), works on any PC
- Includes settings, session AND history in backup
- Backward-compatible: auto-detects legacy JSON backups
- Normalize history entries on import
- Added debridLinkApiKeys, linkSnappy credentials to sensitive keys
Hide extracted items:
- New setting: hide completed/extracted items from package item list
- Items still count in progress stats (done/total), only hidden in UI
- Default: enabled
- Toggle in settings: "Entpackte Items in Paketliste ausblenden"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace plaintext JSON export with encrypted binary format (JDownloader 2 style)
- Fixed app-internal key, works on any machine without password
- Export now includes ALL credentials (no more ***-masking), session AND history
- Add debridLinkApiKeys, linkSnappy credentials to sensitive keys list
- Backward-compatible import: auto-detects legacy JSON backups
- File extension changed from .json to .mdd
- MDD1 magic bytes + random IV + GCM auth tag for integrity
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Archives with absolute internal paths (e.g. scene groups storing full
Windows paths) fail all password attempts in normal mode at ~98%, then
succeed only after the flat-mode fallback kicks in. Previously every
archive in such a package wasted all password cycles before discovering
flat mode was needed again.
Now the first successful flat-mode extraction sets a package-level flag
so subsequent archives skip the normal loop entirely and go straight to
flat-mode extraction, saving ~4x password attempts per archive.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- SCENE_EPISODE_RE/JOINED_RE: use (?!\d) lookahead instead of requiring
separator after episode number, so filenames like s09e06rrp now match
- MKV-Sammelordner: skip 0-byte files from failed/partial extractions
- MKV-Sammelordner: detect same-name same-size duplicates in target dir
and skip instead of creating (2) copies; remove duplicate source file
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Retry failed wrong_password archives serially after parallel extraction
to recover from CRC mismatches caused by concurrent UnRAR I/O contention
- Stop resetting sessionDownloadedBytes on start/resume so the session
total accurately reflects all bytes downloaded since app launch
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Multiple accounts from the same provider are now merged:
"Debrid-Link (#3), Debrid-Link (#4)" becomes "Debrid-Link (#3 + #4)"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Daily traffic limits:
- Per-provider daily download limit (configurable in GB per provider)
- Per Debrid-Link API key daily limit (individual limits per key)
- Usage tracking with automatic daily reset at midnight
- Provider is skipped when daily limit reached, falls back to next provider
- Reset button per provider and per Debrid-Link key in account settings
- Hoster routing skips daily-limited providers gracefully
Debrid-Link multi-key improvements:
- Keys now display with labels (#1, #2...) and masked tokens in account list
- Option to show detailed per-key view with individual usage stats
- Keys that hit their daily limit are automatically skipped
- providerAccountId/providerAccountLabel stored per download item
Auto-sort packages by progress:
- Active packages automatically sorted to top during downloads
- Sorted by completion ratio, then downloaded bytes
- Toggle in settings (autoSortPackagesByProgress)
UI polish:
- Package column headers: flatter, more transparent design
- LinkSnappy mode label: "Login" renamed to "Web"
- Account list: new toggle for detailed Debrid-Link key display
- Account usage stats section with warning styling
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All ? placeholders in App.tsx replaced with correct UTF-8 umlauts
(ä, ö, ü, ß). File is now properly encoded as UTF-8.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- extractor: detect UnRAR "Cannot create...\..." error (archive with
leading-backslash internal paths) and retry in flat mode (-e) which
strips all paths and avoids the invalid double-separator on Windows
- types/download-manager: add providerLabel field to DownloadItem,
store full label (e.g. "Debrid-Link #1") set at unrestrict time
- App: display providerLabel in Service column (falls back to generic
provider name if label not yet set)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sanitizeFilename() is now applied before constructing outputDir and
extractDir, so names like "TMSF/4SF" no longer produce broken Windows paths.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When a pending item has neither targetPath nor fileName (e.g. after a
reset before re-unrestrict), it is invisible to pendingItemStatus and
the disk-fallback could incorrectly start extraction with a partial file.
Add a guard that skips disk-fallback for any archive set if the package
contains such an untracked pending item.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Clear item.provider on stop/restart so provider order/routing changes
are respected on next download attempt
- Reset item.provider for all non-completed items when providerOrder or
hosterRouting changes in settings
- Cancel scheduled-start timer when queue is started manually
- Track disk-fallback hybrid-extract archives per session to prevent
infinite post-processing loop
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>