From dadca784b1ddddbbde1d7db59e2d12039a99f60a Mon Sep 17 00:00:00 2001 From: Goldy <153996346+g0ldyy@users.noreply.github.com> Date: Fri, 12 Jul 2024 18:34:20 +0200 Subject: [PATCH] feat: Debrid-Link support --- comet/debrid/debridlink.py | 124 +++++++++++++++++++++++++++++++++++++ comet/debrid/manager.py | 3 + comet/templates/index.html | 3 + comet/utils/general.py | 2 + comet/utils/models.py | 2 +- 5 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 comet/debrid/debridlink.py diff --git a/comet/debrid/debridlink.py b/comet/debrid/debridlink.py new file mode 100644 index 0000000..9a09831 --- /dev/null +++ b/comet/debrid/debridlink.py @@ -0,0 +1,124 @@ +import aiohttp +import asyncio + +from RTN import parse + +from comet.utils.general import is_video +from comet.utils.logger import logger + + +class DebridLink: + def __init__(self, session: aiohttp.ClientSession, debrid_api_key: str): + session.headers["Authorization"] = f"Bearer {debrid_api_key}" + self.session = session + self.proxy = None + + self.api_url = "https://debrid-link.com/api/v2" + + async def check_premium(self): + try: + check_premium = await self.session.get( + f"{self.api_url}/account/infos" + ) + check_premium = await check_premium.text() + if '"accountType":1' in check_premium: + return True + except Exception as e: + logger.warning( + f"Exception while checking premium status on Debrid-Link: {e}" + ) + + return False + + async def get_instant(self, chunk: list): + try: + get_instant = await self.session.get( + f"{self.api_url}/seedbox/cached?url={','.join(chunk)}" + ) + return await get_instant.json() + except Exception as e: + logger.warning( + f"Exception while checking hashes instant availability on Debrid-Link: {e}" + ) + + async def get_files( + self, torrent_hashes: list, type: str, season: str, episode: str + ): + chunk_size = 250 + chunks = [ + torrent_hashes[i : i + chunk_size] + for i in range(0, len(torrent_hashes), chunk_size) + ] + + tasks = [] + for chunk in chunks: + tasks.append(self.get_instant(chunk)) + + responses = await asyncio.gather(*tasks) + + availability = [] + for response in responses: + if response is None: + continue + + availability.append(response) + + files = {} + for result in availability: + if "success" not in result or not result["success"]: + continue + + if type == "series": + for hash in result["value"]: + hash_files = result["value"][hash]["files"] + for file in hash_files: + filename = file["name"] + + if not is_video(filename): + continue + + filename_parsed = parse(filename) + if ( + season in filename_parsed.season + and episode in filename_parsed.episode + ): + files[hash] = { + "index": hash_files.index(file), + "title": filename, + "size": file["size"], + } + + continue + + for hash in result["value"]: + hash_files = result["value"][hash]["files"] + for file in hash_files: + filename = file["name"] + + if not is_video(filename): + continue + + files[hash] = { + "index": hash_files.index(file), + "title": filename, + "size": file["size"], + } + + return files + + async def generate_download_link(self, hash: str, index: str): + try: + add_torrent = await self.session.post( + f"{self.api_url}/seedbox/add", + data={ + "url": hash, + "async": True + } + ) + add_torrent = await add_torrent.json() + + return add_torrent["value"]["files"][int(index)]["downloadUrl"] + except Exception as e: + logger.warning( + f"Exception while getting download link from Debrid-Link for {hash}|{index}: {e}" + ) diff --git a/comet/debrid/manager.py b/comet/debrid/manager.py index 92aef27..86b30e6 100644 --- a/comet/debrid/manager.py +++ b/comet/debrid/manager.py @@ -4,6 +4,7 @@ from .realdebrid import RealDebrid from .alldebrid import AllDebrid from .premiumize import Premiumize from .torbox import TorBox +from .debridlink import DebridLink def getDebrid(session: aiohttp.ClientSession, config: dict): @@ -17,3 +18,5 @@ def getDebrid(session: aiohttp.ClientSession, config: dict): return Premiumize(session, debrid_api_key) elif debrid_service == "torbox": return TorBox(session, debrid_api_key) + elif debrid_service == "debridlink": + return DebridLink(session, debrid_api_key) diff --git a/comet/templates/index.html b/comet/templates/index.html index b4c981f..b69e052 100644 --- a/comet/templates/index.html +++ b/comet/templates/index.html @@ -537,6 +537,7 @@ All-Debrid Premiumize TorBox + Debrid-Link @@ -561,6 +562,8 @@ apiKeyLink.href = "https://premiumize.me/account"; } else if (selectedService === "torbox") { apiKeyLink.href = "https://torbox.app/settings"; + } else if (selectedService === "debridlink") { + apiKeyLink.href = "https://debrid-link.com/webapp/apikey"; } }); diff --git a/comet/utils/general.py b/comet/utils/general.py index 9ea073d..237a151 100644 --- a/comet/utils/general.py +++ b/comet/utils/general.py @@ -200,6 +200,8 @@ def get_debrid_extension(debridService: str): debrid_extension = "PM" elif debridService == "torbox": debrid_extension = "TB" + elif debridService == "debridlink": + debrid_extension = "DL" return debrid_extension diff --git a/comet/utils/models.py b/comet/utils/models.py index e0cdd7f..f84325e 100644 --- a/comet/utils/models.py +++ b/comet/utils/models.py @@ -67,7 +67,7 @@ class ConfigModel(BaseModel): @field_validator("debridService") def check_debrid_service(cls, v): - if v not in ["realdebrid", "alldebrid", "premiumize", "torbox"]: + if v not in ["realdebrid", "alldebrid", "premiumize", "torbox", "debridlink"]: raise ValueError("Invalid debridService") return v