diff --git a/.env-sample b/.env-sample index 92f4a80..f32643c 100644 --- a/.env-sample +++ b/.env-sample @@ -155,6 +155,8 @@ JACKETTIO_URL=https://jackettio.example.com # Full manifest URL without /manifes SCRAPE_DEBRIDIO=False DEBRIDIO_API_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +DEBRIDIO_PROVIDER=realdebrid # alldebrid, debrider, debridlink, easydebrid, premiumize, realdebrid, torbox +DEBRIDIO_PROVIDER_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX SCRAPE_TORBOX=False TORBOX_API_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX diff --git a/comet/main.py b/comet/main.py index 61c6ec2..9eef237 100644 --- a/comet/main.py +++ b/comet/main.py @@ -288,14 +288,14 @@ def start_log(): f"Jackettio Scraper: {settings.format_scraper_mode(settings.SCRAPE_JACKETTIO)}{jackettio_url}", ) - debridio_api_key = ( - f" - {settings.DEBRIDIO_API_KEY}" + debridio_info = ( + f" - {settings.DEBRIDIO_API_KEY} - {settings.DEBRIDIO_PROVIDER}|{settings.DEBRIDIO_PROVIDER_KEY}" if settings.is_any_context_enabled(settings.SCRAPE_DEBRIDIO) else "" ) logger.log( "COMET", - f"Debridio Scraper: {settings.format_scraper_mode(settings.SCRAPE_DEBRIDIO)}{debridio_api_key}", + f"Debridio Scraper: {settings.format_scraper_mode(settings.SCRAPE_DEBRIDIO)}{debridio_info}", ) torbox_api_key = ( diff --git a/comet/scrapers/debridio.py b/comet/scrapers/debridio.py index edc17d0..f8f5b01 100644 --- a/comet/scrapers/debridio.py +++ b/comet/scrapers/debridio.py @@ -1,46 +1,92 @@ import aiohttp +import base64 +import orjson +import re +from functools import lru_cache from comet.utils.general import log_scraper_error, size_to_bytes -from comet.utils.torrent import extract_trackers_from_magnet from comet.utils.models import settings +DATA_PATTERN = re.compile( + r"💾\s+([\d.,]+\s+[KMGT]B|Unknown|\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2})(?:\s+👤\s+(\d+|Unknown|undefined))?(?:\s+⚙️\s+(.+?))?(?:\n|$)", + re.IGNORECASE, +) + + +@lru_cache(maxsize=1) +def get_debridio_config(): + config = { + "api_key": settings.DEBRIDIO_API_KEY, + "provider": settings.DEBRIDIO_PROVIDER, + "providerKey": settings.DEBRIDIO_PROVIDER_KEY, + "disableUncached": False, + "maxSize": "", + "maxReturnPerQuality": "", + "resolutions": ["4k", "1440p", "1080p", "720p", "480p", "360p", "unknown"], + "excludedQualities": [], + } + return base64.b64encode(orjson.dumps(config)).decode("utf-8") + async def get_debridio(manager, session: aiohttp.ClientSession): + if ( + not settings.DEBRIDIO_API_KEY + or not settings.DEBRIDIO_PROVIDER + or not settings.DEBRIDIO_PROVIDER_KEY + ): + return + torrents = [] + b64_config = get_debridio_config() try: - data = await session.get( - f"https://debapi.debridio.com/{settings.DEBRIDIO_API_KEY}/search/{manager.media_only_id}" + results = await session.get( + f"https://addon.debridio.com/{b64_config}/stream/{manager.media_type}/{manager.media_id}.json" ) - data = await data.json() + results = await results.json() - for torrent in data: - size = torrent["size"] - if isinstance(size, str) and size != "Unknown": - size = size_to_bytes(size.replace(",", "")) - elif isinstance(size, int): - pass - else: - size = 0 + for torrent in results["streams"]: + title_full = torrent["title"] + torrent_name = title_full.split("\n")[0] - seeders = torrent["seeders"] - if seeders == "Unknown": - seeders = None + match = DATA_PATTERN.search(title_full) + + size_str = match.group(1) + size = ( + 0 + if not size_str or "Unknown" in size_str or "-" in size_str + else size_to_bytes(size_str.replace(",", "")) + ) + + seeders_str = match.group(2) + seeders = ( + None + if not seeders_str or seeders_str in ["undefined", "Unknown"] + else int(seeders_str) + ) + + tracker = f"Debridio|{match.group(3)}" + + info_hash = torrent["url"].split("/")[-2] torrents.append( { - "title": torrent["name"], - "infoHash": torrent["hash"], + "title": torrent_name, + "infoHash": info_hash, "fileIndex": None, "seeders": seeders, "size": size, - "tracker": f"Debridio|{torrent['indexer']}", - "sources": extract_trackers_from_magnet(torrent["magnet"]), + "tracker": tracker, + "sources": [], } ) + except Exception as e: log_scraper_error( - "Debridio", settings.DEBRIDIO_API_KEY, manager.media_only_id, e + "Debridio", + f"{settings.DEBRIDIO_PROVIDER}|{settings.DEBRIDIO_PROVIDER_KEY}", + manager.media_id, + e, ) await manager.filter_manager("Debridio", torrents) diff --git a/comet/scrapers/torrentio.py b/comet/scrapers/torrentio.py index 4b92738..8650de8 100644 --- a/comet/scrapers/torrentio.py +++ b/comet/scrapers/torrentio.py @@ -8,7 +8,7 @@ from comet.utils.general import ( ) -data_pattern = re.compile( +DATA_PATTERN = re.compile( r"(?:👤 (\d+) )?💾 ([\d.]+ [KMGT]B)(?: ⚙️ (\w+))?", re.IGNORECASE ) @@ -28,7 +28,7 @@ async def get_torrentio(manager, url: str): else: title = title_full.split("\n")[0] - match = data_pattern.search(title_full) + match = DATA_PATTERN.search(title_full) seeders = int(match.group(1)) if match.group(1) else None size = size_to_bytes(match.group(2)) diff --git a/comet/utils/models.py b/comet/utils/models.py index 9e68720..c831aa7 100644 --- a/comet/utils/models.py +++ b/comet/utils/models.py @@ -84,6 +84,8 @@ class AppSettings(BaseSettings): JACKETTIO_URL: Optional[Union[str, List[str]]] = None SCRAPE_DEBRIDIO: Union[bool, str] = False DEBRIDIO_API_KEY: Optional[str] = None + DEBRIDIO_PROVIDER: Optional[str] = None + DEBRIDIO_PROVIDER_KEY: Optional[str] = None SCRAPE_TORBOX: Union[bool, str] = False TORBOX_API_KEY: Optional[str] = None CUSTOM_HEADER_HTML: Optional[str] = None diff --git a/comet/utils/torrent.py b/comet/utils/torrent.py index c28da50..c58804e 100644 --- a/comet/utils/torrent.py +++ b/comet/utils/torrent.py @@ -18,7 +18,7 @@ from comet.utils.logger import logger from comet.utils.models import settings, database from comet.utils.general import is_video, default_dump -info_hash_pattern = re.compile(r"btih:([a-fA-F0-9]{40}|[a-zA-Z0-9]{32})") +INFO_HASH_PATTERN = re.compile(r"btih:([a-fA-F0-9]{40}|[a-zA-Z0-9]{32})") def extract_trackers_from_magnet(magnet_uri: str): @@ -41,7 +41,7 @@ async def download_torrent(session: aiohttp.ClientSession, url: str): location = response.headers.get("Location", "") if location: - match = info_hash_pattern.search(location) + match = INFO_HASH_PATTERN.search(location) if match: info_hash = match.group(1) if len(info_hash) == 32: