Commit Graph

299 Commits

Author SHA1 Message Date
Sucukdeluxe
24e457d84d Revalidate completed items on startup, fix stale session data
Items incorrectly marked as "completed" by the old 50% recovery threshold
persist in the session file across updates. On startup, check all completed
items: if the file on disk is smaller than expected totalBytes, reset to
"queued" so it gets re-downloaded. Also reset items whose files are missing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 20:14:11 +01:00
Sucukdeluxe
e80948df54 Fix disk-fallback in hybrid extract allowing partial files
Two bugs in findReadyArchiveSets disk-fallback:

1. Failed items were explicitly excluded from the blocking check
   (status !== "failed"), so partial downloads with "failed" status
   would not block extraction. Now ANY non-completed item blocks.

2. The disk size check was only > 10 KB, allowing 627 MB partial
   files of 1001 MB archives to pass. Now requires the file to be
   within one allocation unit of the item's expected totalBytes.

Added findItemByDiskPath helper to look up the owning item for a
file on disk and get its expected size.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 20:10:04 +01:00
Sucukdeluxe
0f2823bdc2 Fix premature hybrid extraction of incomplete archive parts
Item-Recovery incorrectly marked partially downloaded files as "completed"
when the file size was >= 50% of expected size. A 627 MB partial download
of a 1001 MB file (62.7%) would pass the check and trigger hybrid
extraction on incomplete RAR archives.

Fix: require file to be within one allocation unit (4 KB) of the expected
size instead of 50%. Also add a pre-allocation guard: if the file appears
to be at the expected size but downloadedBytes is significantly behind
(< 95%), skip recovery (likely a pre-allocated sparse file from a crash).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 19:48:22 +01:00
Sucukdeluxe
927ff5c21a Auto-fix legacy (N) suffix filenames on startup
Detect items whose targetPath has a " (N)" suffix from the previous
duplicate filename bug and rename them back to the original filename.
This fixes extraction failures for RAR split archives that were
downloaded with (1) suffix before v1.7.19.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 19:36:30 +01:00
Sucukdeluxe
afbd425227 Fix Debrid-Link key selection: always use first available key
Replace shared currentKeyIndex round-robin with sequential scan from
first key. All parallel items now consistently use the same key (e.g.
Key 3) until it hits a quota/error, then all move to Key 4, etc.

Previously, currentKeyIndex was shared across parallel unrestrict calls,
causing items to scatter across keys (3, 5, 7) even when Key 3 still
had capacity.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 19:33:40 +01:00
Sucukdeluxe
0e0c211d35 Restore target path reservations on startup to prevent (1) duplicates
After restart, reservedTargetPaths (in-memory) was empty so claimTargetPath
could not distinguish between "file belongs to this item" and "file belongs
to another item". The naive fix (allow overwrite if unclaimed) would have
risked overwriting completed files from other items.

Proper fix: restore reservedTargetPaths from persisted session data on init.
This way each item's targetPath is correctly claimed, and claimTargetPath
can safely reuse the item's own file while protecting other items' files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 19:26:29 +01:00
Sucukdeluxe
cb02dd3aac Fix duplicate (1) filenames after app restart with partial downloads
When the app restarts (or updates) while downloads are in progress,
partial files remain on disk but reservedTargetPaths (in-memory) is empty.
claimTargetPath treated the unclaimed-but-existing file as a conflict and
appended (1) to the filename, breaking RAR split archive extraction.

Fix: if a file exists on disk but no other item has reserved the path,
allow overwriting instead of creating a duplicate.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 19:20:26 +01:00
Sucukdeluxe
a0800045ec Fix Debrid-Link key rotation: skip broken keys immediately, add cooldown cache
- Add "notDebrid", "disabledServerHost", "notFree" as immediate-skip errors
  (no 3x retry per key, break to next key instantly like quota errors)
- Add per-key cooldown cache (2 min) so parallel items skip recently-failed keys
  instead of all starting at the same broken key
- Set cooldown on quota errors too, preventing repeated checks on exhausted keys

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 18:02:34 +01:00
Sucukdeluxe
e00c5b5344 Fix shelve mechanism: reset provider + circuit breaker, reduce pause to 90s
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>
2026-03-07 17:55:56 +01:00
Sucukdeluxe
ccf4dc2e08 Fix hosterNotAvailable skipping provider cooldown in inner catch
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>
2026-03-07 17:14:38 +01:00
Sucukdeluxe
35975d7333 Fix hosterNotAvailable retry stalling due to provider cooldown
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>
2026-03-07 17:09:29 +01:00
Sucukdeluxe
67fc3a8e1c Treat hosterNotAvailable as temporary error with retry
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>
2026-03-07 17:01:58 +01:00
Sucukdeluxe
8e4b29a155 Encrypted backup system + hide extracted items in package list
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>
2026-03-07 16:44:21 +01:00
Sucukdeluxe
0edd8f6be5 Redesign backup system: AES-256-GCM encrypted .mdd format
- 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>
2026-03-07 16:39:19 +01:00
Sucukdeluxe
5fbcdc1722 Cache flat-mode flag per package to skip redundant password cycles
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>
2026-03-07 15:11:37 +01:00
Sucukdeluxe
f5fe3efb73 Fix episode regex for rrp suffixes, skip 0-byte MKVs, prevent duplicate (2) copies
- 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>
2026-03-07 14:39:17 +01:00
Sucukdeluxe
8f6b87ae8c Fix parallel extraction wrong_password false positives, preserve session download counter across stop/resume
- 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>
2026-03-07 14:18:09 +01:00
Sucukdeluxe
7737a4b0da Release v1.7.1 2026-03-07 03:52:41 +01:00
Sucukdeluxe
dd4264a936 Fix remaining broken umlauts in main.ts and debrid.ts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 02:30:26 +01:00
Sucukdeluxe
e212ccc86f Add daily traffic limits, auto-sort packages, Debrid-Link multi-key improvements
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>
2026-03-07 02:29:48 +01:00
Sucukdeluxe
1cbda1350e Fix absolute archive paths, show provider account number in UI
- 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>
2026-03-07 00:38:34 +01:00
Sucukdeluxe
3287504618 Fix invalid path when package name contains forward slash
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>
2026-03-07 00:21:14 +01:00
Sucukdeluxe
dfc5d73105 Fix disk-fallback extraction triggering with incomplete archive parts
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>
2026-03-07 00:03:31 +01:00
Sucukdeluxe
9d374b97cf Fix provider order/routing respecting on restart, schedule timer on manual start
- 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>
2026-03-06 23:52:09 +01:00
Sucukdeluxe
905b55e7d8 fix: provider fallback on cooldown, hoster routing dirty flag, provider order in DM 2026-03-06 23:06:05 +01:00
Sucukdeluxe
2e6074337a feat: re-download from history, reset-all-failed, scheduled start, fix provider order dirty flag 2026-03-06 22:53:20 +01:00
Sucukdeluxe
716b516900 feat: dynamic provider order, hoster routing, MKV sample fix
- Replace fixed primary/secondary/tertiary slots with unlimited ordered
  providerOrder: DebridProvider[] list; supports as many accounts as needed
- Provider list reorderable via up/down buttons in Accounts settings tab
- Migration: derives order from legacy primary/secondary/tertiary if empty
- Mega-Debrid split into megadebrid-api and megadebrid-web as separate providers
- Add per-hoster routing (hosterRouting) to assign specific debrid provider per hoster
- Fix duplicate MKV files in library: filter out sample files from Sample subfolders
- Remove legacy provider-selection dropdowns from hidden settings section
- Add CSS for provider-order-list/row/num/label/actions classes
- Update debrid tests: add providerOrder: [] to use legacy fallback path

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 22:17:44 +01:00
Sucukdeluxe
0003d786d8 Release v1.6.90 2026-03-06 20:43:15 +01:00
Sucukdeluxe
0eb3403e40 Release v1.6.89 2026-03-06 20:19:17 +01:00
Sucukdeluxe
272b43d59e Release v1.6.88 2026-03-06 20:05:53 +01:00
Sucukdeluxe
06e649ba5b fix: skip sample MKVs during library collection
MKV library collection now filters out sample files before moving.
Files in "sample"/"samples" directories and files with "sample" in
their name are excluded. This prevents duplicate "(2)" entries in
the library folder caused by samples having the same base name as
the real episodes (just different casing from the archive).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 19:33:15 +01:00
Sucukdeluxe
c811649b9d feat: add per-hoster provider routing (Hoster-Zuordnung)
- New settings field hosterRouting maps file hosters to specific debrid providers
- 27 known hosters predefined (Rapidgator, Uploaded, Turbobit, Nitroflare, etc.)
- Custom hoster support via prompt dialog
- Routing takes priority over default provider chain
- Falls back to normal chain on error when autoProviderFallback is enabled
- Logs routing decisions: "Hoster-Zuordnung: rapidgator → Debrid-Link"
- Full UI section in settings with add/remove/change provider per hoster
- Storage validation and normalization for hosterRouting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 19:14:16 +01:00
Sucukdeluxe
22ed37d67c feat: add LinkSnappy provider, account deactivation, UI polish
- Add LinkSnappy provider with cookie-based session auth and /api/linkgen
- Upgrade LinkSnappy download URLs from http to https (fix 425 errors)
- Add account deactivation toggle (disabledProviders in settings)
- Show account type (API/Web/Login) in provider dropdowns
- Show API key count for Debrid-Link in status label
- Fix all missing German umlauts throughout the UI
- Wider modal for textarea, compact action buttons in one row
- Debrid-Link: log which API key (#1/#2) is used for unrestrict

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 19:00:19 +01:00
Sucukdeluxe
af188d96c4 feat: add Debrid-Link provider with multi-account key rotation
- New DebridLinkClient with automatic API key rotation on quota errors
  (maxLink, maxLinkHost, maxData, maxDataHost, maxAttempts, maxTransfer)
- Multi-account support: comma or newline-separated API keys
- Full UI integration: account settings, provider dropdowns, summary display
- Safe fallback for undefined debridLinkApiKeys on settings upgrade

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 18:23:36 +01:00
Sucukdeluxe
e92cf59d86 Release v1.6.82 2026-03-06 16:43:49 +01:00
Sucukdeluxe
3cf1bc825e Release v1.6.81 2026-03-06 12:09:39 +01:00
Sucukdeluxe
359fb93be3 Release v1.6.80 2026-03-06 12:04:56 +01:00
Sucukdeluxe
153318274d ♻️ refactor(bestdebrid): switch from browser login to cookie file import
Replace BrowserWindow-based login flow with Netscape cookie file import
for BestDebrid authentication. Cloudflare Turnstile captcha cannot be
solved in Electron's embedded browser, so users export cookies from
their real browser and import them here.

- Rewrite bestdebrid-web.ts: remove BrowserWindow/CDP code, add
  parseNetscapeCookieFile() and importCookiesFromFile()
- Add file picker dialog for .txt cookie files in main IPC handler
- Update IPC channel from OPEN_BESTDEBRID_LOGIN to IMPORT_BESTDEBRID_COOKIES
- Update preload bridge and renderer UI with cookie import button
- Fix pLabel scope in downloadToFile (pass as parameter from processItem)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 11:44:23 +01:00
Sucukdeluxe
d6ba5aeae6 🐛 fix(bestdebrid): keep CDP debugger attached until window close
Detaching the debugger before loadURL removed the registered
anti-fingerprint scripts, causing blank pages. Now keep the
debugger attached through page load and detach on window close.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 11:35:45 +01:00
Sucukdeluxe
df02a04cfd 🐛 fix(bestdebrid): inject CDP anti-fingerprint patches for Cloudflare Turnstile
Use Chrome DevTools Protocol to inject scripts before page load that:
- Set navigator.webdriver to false
- Add fake navigator.plugins
- Set navigator.languages to realistic values
- Add window.chrome runtime stub

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 11:32:28 +01:00
Sucukdeluxe
90c73c4091 🐛 fix(bestdebrid): set user agent on session and webContents level
Cloudflare Turnstile blocks Electron's default user agent. Set a
Chrome user agent on both the session and webContents level so the
login captcha passes correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 11:29:15 +01:00
Sucukdeluxe
438a9f209e feat(bestdebrid): add BestDebrid web-login provider
- New BestDebrid web-login option (BrowserWindow + session.fetch)
- Uses bestdebrid.com/api/v1/generateLink with browser session cookies
- Login via BestDebrid website in embedded browser window
- Toggle "BestDebrid per Web-Login statt API-Token verwenden"
- Provider label shows "BestDebrid (Web)" or "BestDebrid (API)"
- Session persistence respects "Token merken" setting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 11:26:48 +01:00
Sucukdeluxe
5873ffa60d 🐛 fix(1fichier): disable CDN downloads to preserve CDN credits
Pass cdn: 0 to 1Fichier get_token API to force direct server
downloads instead of CDN, avoiding unnecessary CDN credit usage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 11:09:13 +01:00
Sucukdeluxe
3950207a0f 🐛 fix: show provider source label (API/Web) in download status text
The running download status (e.g. "Download läuft", "Warte auf
Festplatte") now shows the full provider label including the source
mode, e.g. "Mega-Debrid (API)" instead of just "Mega-Debrid".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 11:01:35 +01:00
Sucukdeluxe
aa4f69795f feat: show (API)/(Web) source labels for all providers
Real-Debrid, AllDebrid, and Mega-Debrid now show their active
mode in logs and UI (e.g. "Real-Debrid (API)" or "Real-Debrid (Web)").

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 10:58:09 +01:00
Sucukdeluxe
eb5d960e81 🐛 fix(megadebrid): deduplicate parallel connectUser API calls
Multiple parallel downloads calling connectUser simultaneously caused
token invalidation races. Only one connectUser request now runs at a
time; all parallel callers share the same result.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 10:57:10 +01:00
Sucukdeluxe
faece1cf26 feat(megadebrid): add API mode with toggle and provider labels
- Add Mega-Debrid API support (connectUser + getLink endpoints)
- API mode preferred by default, with automatic web fallback on failure
- User toggle "Mega-Debrid bevorzugt über API" in settings UI
- Provider labels now show source: "Mega-Debrid (API)" or "Mega-Debrid (Web)"
- sourceLabel propagated through all provider result paths
- API session token cached for 20 minutes with auto-invalidation
- Remove megaWebUnrestrict requirement for Mega-Debrid provider config

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 10:51:31 +01:00
Sucukdeluxe
2b322968d9 Add Real-Debrid web-login as alternative to manual API token
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 05:42:34 +01:00
Sucukdeluxe
e4a60a033b Release v1.6.69 2026-03-06 04:17:22 +01:00
Sucukdeluxe
c380abaee2 Fix deferred post-extraction cleanup skipped after hybrid extraction
When hybrid extraction handled all archives, extractedCount stayed 0
causing all cleanup steps (archive deletion, resume state, link/sample
removal, empty dir pruning, auto-rename, nested extraction) to be
bypassed. Extended conditions to also trigger on alreadyMarkedExtracted.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 17:32:11 +01:00