-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(debrid): add support for stremthru
- Loading branch information
1 parent
083efb6
commit 26882b9
Showing
14 changed files
with
274 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
import asyncio | ||
from typing import Optional | ||
|
||
import aiohttp | ||
from RTN import parse | ||
|
||
from comet.utils.general import is_video | ||
from comet.utils.logger import logger | ||
|
||
|
||
class StremThru: | ||
def __init__( | ||
self, | ||
session: aiohttp.ClientSession, | ||
url: str, | ||
store: str, | ||
store_token: Optional[str] = None, | ||
credential: Optional[str] = None, | ||
): | ||
if not credential and not store_token: | ||
raise TypeError("either stremthru credential or store token is required") | ||
|
||
if not self.is_supported_store(store): | ||
raise ValueError(f"unsupported store: {store}") | ||
|
||
self.__is_proxy_authorized = False | ||
|
||
session.headers["X-StremThru-Store-Name"] = store | ||
|
||
if credential: | ||
session.headers["Proxy-Authorization"] = f"Basic {credential}" | ||
self.__is_proxy_authorized = True | ||
elif store_token: | ||
session.headers["X-StremThru-Store-Authorization"] = f"Bearer {store_token}" | ||
|
||
self.session = session | ||
self.base_url = f"{url}/v0/store" | ||
self.name = f"StremThru[{store}]" | ||
|
||
def should_try_to_proxy_stream(self): | ||
return not self.__is_proxy_authorized | ||
|
||
@staticmethod | ||
def is_supported_store(store: str): | ||
if store == "alldebrid": | ||
return True | ||
return False | ||
|
||
async def check_premium(self): | ||
try: | ||
user = await self.session.get(f"{self.base_url}/user") | ||
user = await user.json() | ||
return user["data"]["subscription_status"] == "premium" | ||
except Exception as e: | ||
logger.warning( | ||
f"Exception while checking premium status on {self.name}: {e}" | ||
) | ||
|
||
return False | ||
|
||
async def get_instant(self, magnets: list): | ||
try: | ||
magnet = await self.session.get( | ||
f"{self.base_url}/magnet?magnet={','.join(magnets)}" | ||
) | ||
return await magnet.json() | ||
except Exception as e: | ||
logger.warning( | ||
f"Exception while checking hash instant availability on {self.name}: {e}" | ||
) | ||
|
||
async def get_files( | ||
self, torrent_hashes: list, type: str, season: str, episode: str, kitsu: bool | ||
): | ||
chunk_size = 25 | ||
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 = [ | ||
response["data"]["items"] | ||
for response in responses | ||
if response and "data" in response | ||
] | ||
|
||
files = {} | ||
|
||
if type == "series": | ||
for magnets in availability: | ||
for magnet in magnets: | ||
if magnet["status"] != "cached": | ||
continue | ||
|
||
for file in magnet["files"]: | ||
filename = file["name"] | ||
|
||
if not is_video(filename) or "sample" in filename: | ||
continue | ||
|
||
filename_parsed = parse(filename) | ||
|
||
if episode not in filename_parsed.episodes: | ||
continue | ||
|
||
if kitsu: | ||
if filename_parsed.seasons: | ||
continue | ||
else: | ||
if season not in filename_parsed.seasons: | ||
continue | ||
|
||
files[magnet["hash"]] = { | ||
"index": file["index"], | ||
"title": filename, | ||
"size": file["size"], | ||
} | ||
|
||
break | ||
else: | ||
for magnets in availability: | ||
for magnet in magnets: | ||
if magnet["status"] != "cached": | ||
continue | ||
|
||
for file in magnet["files"]: | ||
filename = file["name"] | ||
|
||
if not is_video(filename) or "sample" in filename: | ||
continue | ||
|
||
files[magnet["hash"]] = { | ||
"index": file["index"], | ||
"title": filename, | ||
"size": file["size"], | ||
} | ||
|
||
break | ||
|
||
return files | ||
|
||
async def generate_download_link(self, hash: str, index: str): | ||
try: | ||
magnet = await self.session.post( | ||
f"{self.base_url}/magnet", | ||
json={"magnet": f"magnet:?xt=urn:btih:{hash}"}, | ||
) | ||
magnet = await magnet.json() | ||
|
||
file = next( | ||
( | ||
file | ||
for file in magnet["data"]["files"] | ||
if file["index"] == int(index) | ||
), | ||
None, | ||
) | ||
|
||
if not file: | ||
return | ||
|
||
link = await self.session.post( | ||
f"{self.base_url}/link/generate", | ||
json={"link": file["link"]}, | ||
) | ||
link = await link.json() | ||
|
||
return link["data"]["link"] | ||
except Exception as e: | ||
logger.warning( | ||
f"Exception while getting download link from {self.name} for {hash}|{index}: {e}" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.