Commit graph

88 commits

Author SHA1 Message Date
LimeDrive
cdc3d0834b refactor(debrid): switch to DLToken/EDToken/OCCredentials/PPCredentials 2026-04-04 12:14:45 +02:00
LimeDrive
e8b0976332 refactor(logging): switch info/debug logs to trace across modules
convert info/debug logs to trace across modules for deeper diagnostics
without changing behavior
2026-04-03 12:09:26 +02:00
LimeDrive
31cd83e9cb refactor(debrid): adjust not_cached ttl and remove series file_index path
extend not_cached ttl from 20m to 3h to reduce re-checks
of not cached items

remove the file_index shortcut for series in Torbox
and rely on season/episode parsing
2026-04-01 22:34:48 +02:00
LimeDrive
76afe6ed15 feat: enhance json_response method to support json data and add new torrent management features in Torbox 2026-03-31 03:06:07 +02:00
LimeDrive
099132d9c4 feat: add background caching for magnets/torrents in AllDebrid 2026-03-30 23:52:50 +02:00
LimeDrive
fb019a85bf feat(search): add configurable indexer search phases and RealDebrid optimization
Introduce a 4-phase search system where private indexers are grouped by priority:
- Phase 1 (priority_private): always queried first
- Phase 2 (intermediary_private): queried only if private results < minCachedResults
- Phase 3 (fallback_private): queried only if still insufficient
- Phase 4 (public): Yggflix relay position controlled by yggflixPriority toggle

Add rdMinCachedBeforeCheck setting to skip RealDebrid if prior services already found enough cached results, since RD API is slow (~3s) and rate-limited. Default to 3.

Non-blocking magnet cleanup in AllDebrid availability checks via background task. G3MINI now computes info_hash from .torrent files when API omits it. Public indexer results are excluded from final matches unless already cached by a debrid service.
2026-03-30 17:49:18 +02:00
LimeDrive
b64c14200d docs(debrid): document optional enrichment hook in caching strategy 2026-03-28 05:15:57 +01:00
LimeDrive
0aba81abb2 feat(peer): add authenticated peer-to-peer cache sharing
Introduces a secure peer-to-peer cache sharing system using HMAC-SHA256 request signatures and Fernet (AES-128-CBC) response encryption.

- New peer_keys table for per-peer credential management (key_id, secret)
- New /api/peer/check endpoint returns encrypted debrid availability data
- New /api/peer/items endpoint returns encrypted torrent metadata
- Rate limiting per peer key with configurable limits and windows
- Admin UI for creating, viewing, revoking, and deleting peer keys
- Peer cache enrichment integrated into BaseDebrid L2.5 lookup pipeline
- StremThruDebrid override with cross-service PG L2 check + peer cache
- Removed old /api/share/cache endpoint (replaced by /api/peer/*)
- Added cryptography package dependency

BREAKING CHANGE: The /api/share/cache endpoint has been removed and replaced with /api/peer/check. Clients must update to use HMAC authentication with X-Peer-Key-Id, X-Peer-Timestamp, and X-Peer-Signature headers.
2026-03-28 05:07:40 +01:00
LimeDrive
0c1d305784 feat(debrid): add PostgreSQL L2 cache for persistent debrid availability
Add a two-level caching architecture for debrid service availability lookups:
- L1: Redis (existing) with 10-day TTL for fast in-memory access
- L2: PostgreSQL with 30-day TTL for persistent caching across Redis restarts

Changes:
- Add `debrid_cache` table with unique constraint on (info_hash, service) and indexes for efficient queries
- Create `DebridCacheDAO` with batch get/upsert and invalidation methods
- Add pgCron job to periodically clean up expired cache entries
- Extend `get_availability_bulk_cached` to check PG on Redis miss, warm Redis from PG hits, and write confirmed-cached results to PG
- Add `invalidate_availability_cache` method to remove false positives from both caches when NO_CACHE_VIDEO_URL is returned during playback
- Integrate `db_session` dependency into playback and search views
- Add retry handling to Yggflix API (3 retries, ignore Retry-After headers) and rate-limiting delay (0.3s) between consecutive queries
2026-03-26 15:47:37 +01:00
LimeDrive
9203464680 refactor(logging): downgrade verbose log levels from info to debug/trace
Lower log verbosity across the codebase by converting info-level logs to debug
and debug-level logs to trace. This reduces noise in production while keeping
detailed information available for debugging when needed.

Affected modules: API key DAO, Real Debrid token manager, C411/Torr9/YGG
indexers, debrid services, torrent container, playback/stream handlers,
search views, and utility modules.
2026-03-26 13:49:57 +01:00
LimeDrive
8739513ced refactor(realdebrid): improve availability checking with direct RD API
Replaced StremThru-dependent availability check with a two-step approach:
- Step 1: Use StremThru community cache when available
- Step 2: Fall back to direct RD API checks via anonymous magnet adds

Added _check_availability_direct method to check RD cache by:
- Marking already-cached hashes from existing account torrents
- Adding anonymous magnets for remaining hashes (0.5s rate limit)
- Checking status of newly added torrents
- Performing background cleanup of temp torrents

Added _add_magnet_probe helper for low-level magnet addition with retry logic for rate limits, and _delete_torrents_background for non-blocking cleanup.

Changed return type from object wrapper to flat array, moved regex import to module level, and added deduplication of input hashes. Also fixed logging style by removing unnecessary f-string formatting.
2026-03-26 01:22:38 +01:00
LimeDrive
62fb267622 refactor(logging): optimize log levels and enhance secret redaction
Convert verbose debug messages to trace level for cleaner production logs, improve secret redaction patterns to handle JWT tokens and API key parameters while preserving parameter names, and standardize log messages to English for consistency across the codebase.
2026-03-25 16:56:32 +01:00
LimeDrive
7074387c3a feat: Implement StremThruDebrid integration with new SDK
- Added StremThruDebrid class for handling debrid operations using StremThru as backend.
- Introduced StremThruSDK for API interactions, including health checks and request handling.
- Created error handling with StremThruError for better error management.
- Updated torrent_smart_container to use the new StremThruDebrid class.
- Added necessary utility functions and data structures for managing magnet and torrent data.
- Implemented caching and session management for improved performance and reliability.
2026-03-25 02:23:56 +01:00
LimeDrive
5e183c48a0 refactor: async fixes, security hardening, and code deduplication
Async correctness:
- Wrap blocking time.sleep/requests.get calls with asyncio.to_thread()
  in torrent_service.py and torr9_service.py
- Run cache_container_items() as fire-and-forget background task via
  asyncio.create_task(asyncio.to_thread(...)) in search/views.py
- Make RDTokenManager.get_access_token() and new_access_token() async,
  replace requests.post with aiohttp (token_manager.py)
- Make RealDebrid.get_headers() async, await all callers (realdebrid.py)

Security:
- Remove API key, device code, and PIN values from log output
  (auth/views.py, admin/views.py)
- Add WARNING on startup when SESSION_KEY uses the insecure default
  value (settings.py)
- Make admin template dir configurable via settings.admin_template_dir

Performance:
- Parallelize TMDB metadata fetches with asyncio.gather() (catalog/views.py)
- Add tmdb_language setting instead of hardcoded "fr-FR"

Deduplication:
- Extract ensure_uuid() to stream_fusion/web/api/utils.py
- Extract get_client_ip() to stream_fusion/web/utils.py
- Replace 8-way if/elif debrid factory with _SERVICE_MAP dict +
  _build_service() helper (get_debrid_service.py)
- Extract _model_to_schema() in APIKeyDAO to remove 6 repeated blocks
- Simplify ProxyStreamer: remove manual BytesIO buffer, stream directly
  via iter_any() (stream/views.py)

Inspired by commits 823bc77 and e306eb5 from limedrive/develop.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 19:05:33 +01:00
LimeDrive
93ec64eb4a fix: update StremThru handling and improve torrent file processing in cache pre-fetch 2026-03-24 17:16:30 +01:00
LimeDrive
92db524f70 fix: update .gitignore and dev-compose.yml for environment configuration; add StremThru response handling methods 2026-03-24 15:54:46 +01:00
LimeDrive
dfc8182960 feat: shared Redis availability cache for all debrid providers (issue #77)
Implements a generic caching layer in BaseDebrid that wraps every provider's
get_availability_bulk() with a shared Redis cache, reducing API calls and
cross-user redundancy.

Key changes:
- base_debrid.py: add get_availability_bulk_cached(), _sanitize_for_cache(),
  _index_results_by_hash(), _reconstruct_response(), service_name property.
  Cache keys: debrid_avail:{service}:{hash}. TTL: 3d (cached), 10min (not cached).
  Security: _sanitize_for_cache() strips private links/tokens before shared storage.
- alldebrid.py: remove fragile cache helpers (_cache_get_json, _cache_set_json,
  _lookup_local_cache, _write_local_cache); add provider overrides for #77;
  fix rate limiter attribute names (global_limit/period, was silently ignored);
  remove statusCode==4 fallback (field absent from /magnet/upload response);
  re-comment in English; StremThru results no longer cached locally.
- realdebrid.py, torbox.py, premiumize.py, stremthru.py: add provider overrides.
- views.py: replace get_availability_bulk() → get_availability_bulk_cached()
  at both call sites (prefetch + stream_processing).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 23:03:47 +01:00
laster13
5b7def748c
Merge branch 'develop' into pr-limehubs-develop 2026-03-23 18:24:45 +01:00
laster13
7ed11a1fea fix: stabilize StremThru/AllDebrid cache checks, playback, and stream caching 2026-03-23 16:54:59 +00:00
LimeDrive
6f674a88db fix: cache MAGNET_INVALID_URI as confirmed not-cached (1h TTL)
MAGNET_INVALID_URI on a valid 40-char hash means AD doesn't have it
in cache — treat as a confirmed negative and store in Redis for 1h.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 03:06:20 +01:00
LimeDrive
cd3e2c4059 fix: handle error responses from AD upload (no hash field + no Redis cache)
Error responses (e.g. MAGNET_INVALID_URI) contain "magnet" not "hash".
Fall back to m.get("magnet") so the hash is not silently dropped.

MAGNET_INVALID_URI on a valid 40-char hash likely means AD cannot verify
an unknown hash without trackers — not a confirmed "not in cache" state.
These results are marked instant:False locally but NOT stored in Redis
to avoid caching a false negative caused by the trackless format.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 03:04:47 +01:00
LimeDrive
01ff4c2495 fix: remove statusCode check from upload response (field not present)
statusCode is only returned by /v4.1/magnet/status, not by /v4/magnet/upload.
The upload response only contains `ready: bool` to indicate cache status.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 02:56:48 +01:00
LimeDrive
3cdf5928cf fix: do not cache StremThru results in Redis
StremThru manages its own community cache and keeps it up to date.
Caching its responses locally would serve stale data and bypass
its real-time updates. Only direct AD API responses are cached.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 02:46:25 +01:00
LimeDrive
5a0dd36caa feat: shared Redis cache for AD availability check (7d/1h TTL)
Add a shared Redis availability cache keyed by hash (debrid:availability:ad:{hash})
so all users benefit from previous checks without hitting the AD API again.

TTLs:
- Confirmed cached (instant:True)  → 7 days
- Confirmed not cached (instant:False) → 1 hour

Anti-pollution safety rules:
- False is only cached when the AD API returned status:success AND the hash
  was present in the response (confirmed by AD itself)
- API errors, MAGNET_TOO_MANY_ACTIVE, exceptions and missing hashes
  never produce a cache entry → a misconfigured token cannot pollute
  the shared cache for other users
- StremThru confirmed results are also stored (always True, 7 days)
- Redis lookup uses mget (single round-trip for all hashes)
- Redis writes use pipeline (single round-trip per batch)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 02:41:50 +01:00
LimeDrive
99bf56f03b fix: send raw hashes to AD bulk upload + finally cleanup + statusCode 4
- Send raw hashes instead of stripped magnet URIs: the AD API accepts
  hashes natively, cleaner and unambiguous
- Wrap delete in finally block so temporary magnets are always cleaned up
  even when an exception occurs between upload and delete
- Add statusCode == 4 check as safety net for the ready field
  (statusCode 4 = "Ready" in AllDebrid's status codes)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 02:25:21 +01:00
LimeDrive
6a09005b14 fix: correct response formats for TorrentSmartContainer compatibility
AllDebrid: filter response to only instant:True magnets — _update_availability_alldebrid
marks every item in the magnets list as available without checking the instant field,
so non-cached hashes must be excluded to avoid false positives.

RealDebrid stub: return StremThru list format instead of dict — _update_availability_realdebrid
expects the old {hash: {"rd": [...]}} shape and would silently skip the new dict format,
leaving nothing marked as available despite the intended stub behaviour.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 01:34:34 +01:00
LimeDrive
4fb5cf1c83 feat: real cache check for AllDebrid via bulk upload/delete + RD stub
AllDebrid:
- Replace stub (instant:True) with hybrid strategy:
  1. StremThru community cache check (if configured)
  2. Bulk magnet upload (stripped, no trackers) + read `ready` field + delete
     in batches of 20 to stay under the 30-slot limit
- Rate limiter bumped from 250/60 to 600/60 (10 req/s, official limit is 12)
- import asyncio added

RealDebrid:
- Replace empty-return fallback with StremThru + stub (instant:True)
- Remove spurious _torrent_rate_limit() call at function entry

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 01:20:26 +01:00
LimeDrive
a44d513438 fix: use StremThru for cache check with fallback when not configured
AD/RD now delegate availability checks to StremThru if stremthru_url is
set. When StremThru is not configured, AllDebrid falls back to the stub
(instant: True for all) and RealDebrid returns empty (native endpoint
deprecated). TorrentSmartContainer detects the StremThru list-format
response and routes it to the existing _update_availability_stremthru handler.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 22:59:24 +01:00
LimeDrive
3dd8bb2904 Revert "fix: replace deprecated RD/AD cache checks with StremThru proxy"
This reverts commit 1a03842607.
2026-03-22 22:27:25 +01:00
laster13
18551fa8ff Improve search fallback/coverage for private indexers and fix AllDebrid cached check cleanup 2026-03-22 18:43:06 +00:00
laster13
db349c1bb9 Revert "Merge pull request #2 from elfhosted/fix/stremthru-cache-check"
This reverts commit 90cd64e83b, reversing
changes made to 0511e5f159.
2026-03-21 07:10:02 +00:00
Elfbot
1a03842607
fix: replace deprecated RD/AD cache checks with StremThru proxy
RealDebrid's /torrents/instantAvailability endpoint is deprecated and
returns 404, so cache checking was silently failing. AllDebrid's check
was a stub that optimistically marked everything as available, causing
unnecessary add-and-wait cycles for uncached content.

Both RealDebrid.get_availability_bulk() and AllDebrid.get_availability_bulk()
now delegate to StremThru's /v0/store/magnets/check, configured via the
existing STREMTHRU_URL env var (default: https://stremthru.13377001.xyz).

TorrentSmartContainer.update_availability() detects the list-format response
returned by StremThru and routes it to the existing _update_availability_stremthru
handler, which correctly processes file listings and availability codes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 10:51:33 +13:00
Telkaoss
4fc4a5cacc update 2026-03-02 11:32:28 +01:00
Telkaoss
465ea3ce22
Add flatten_files function for AllDebrid API response
Introduced a new function to flatten nested file structures from AllDebrid API responses. Updated the logic to handle flattened files for both movies and series.
2025-10-30 00:08:37 +01:00
Telkaoss
26c2cee770
Update magnet file retrieval and error handling
Refactor magnet handling to use v4 API and improve error handling.
2025-10-29 22:15:32 +01:00
Telkaoss
b562f09859
Update index 2025-10-16 09:24:40 +02:00
Telkaoss
ec6883be22
Delete stream_fusion/utils/debrid/premiusize.py.save 2025-10-11 14:44:16 +02:00
Telkaoss
4871acd4b6
Update alldebrid.py 2025-06-28 06:16:36 +02:00
Telkaoss
d47d4b5d83
Update alldebrid.py 2025-06-27 11:36:53 +02:00
Telkaoss
84b102c2f0
Update stremthru.py 2025-06-12 13:18:43 +02:00
Telkaoss
61e7298f26
Update stremthru.py 2025-06-12 11:16:06 +02:00
Telkaoss
ae296e4949
Update stremthru.py 2025-06-12 10:41:33 +02:00
Telkaoss
02df4f4f7f
Update stremthru.py 2025-06-12 10:10:23 +02:00
Telkaoss
7cbca804f9 update 2025-06-12 02:55:07 +02:00
Telkaoss
b0fe2f4c78
Update stremthru.py 2025-05-06 23:37:43 +02:00
Telkaoss
f03dbf473d update 2025-05-06 11:18:44 +02:00
Telkaoss
c76df27bca Stremthru 2025-05-05 05:45:09 +02:00
Telkaoss
35d35993a3 bug fix 2025-05-04 12:41:57 +02:00
Telkaoss
e3ed8b57f4 update 2025-05-04 09:31:01 +02:00
Telkaoss
1530d0557c Stremthru, async ++
Async Streaming: Converted key methods (fill_buffer, stream_content, close, get_stream_link, head_playback) to async for non-blocking streaming and improved scalability.

🔄 Unified Stremthru: Full refactor with dynamic STORE_CODE_TO_NAME / STORE_NAME_TO_TOKEN_KEY mappings and propagation of store_name in all requests (add_magnet, unrestrict_link, etc.). Updated RealDebrid to delegate via Stremthru.

💾 Cache Persistence: Store valid Stremthru links in Redis (stremthru:working:{store_code}:{info_hash}, TTL 7 days) and leverage this cache to mark links as "working" even on cached results.
2025-05-04 05:34:36 +02:00