diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ab94c5..6a126d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,40 @@ # Changelog +## [1.49.0](https://github.com/g0ldyy/comet/compare/v1.48.1...v1.49.0) (2024-11-26) + + +### Features + +* torbox speed improvement + torbox proxy stream fix ([30ecbce](https://github.com/g0ldyy/comet/commit/30ecbcec4560510b260c43ec2ed04a82e724c743)) + +## [1.48.1](https://github.com/g0ldyy/comet/compare/v1.48.0...v1.48.1) (2024-11-26) + + +### Bug Fixes + +* we don't want to spam debrid-link shit ([f9c0ec0](https://github.com/g0ldyy/comet/commit/f9c0ec0a84b6fa9a1e791990b690b6f8ffe0922d)) + +## [1.48.0](https://github.com/g0ldyy/comet/compare/v1.47.0...v1.48.0) (2024-11-26) + + +### Features + +* GG Debrid-Link, restrictions defeated 🤓☝️ ([49cd90b](https://github.com/g0ldyy/comet/commit/49cd90bd0092fd25fe866c3a9120e966a855cd76)) + +## [1.47.0](https://github.com/g0ldyy/comet/compare/v1.46.0...v1.47.0) (2024-11-26) + + +### Features + +* random addon id ([1b6a80b](https://github.com/g0ldyy/comet/commit/1b6a80bbe5800771774adeb469d861919dc3f70d)) + +## [1.46.0](https://github.com/g0ldyy/comet/compare/v1.45.0...v1.46.0) (2024-11-24) + + +### Features + +* remove the need to have a pro torbox acc ([253bfea](https://github.com/g0ldyy/comet/commit/253bfeae4f37595bd59263cde8e1eca26d2fa8e2)) + ## [1.45.0](https://github.com/g0ldyy/comet/compare/v1.44.1...v1.45.0) (2024-11-24) diff --git a/README.md b/README.md index 125c6b6..3ed4a4e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +

diff --git a/comet/api/core.py b/comet/api/core.py index 1dabf54..dc7b458 100644 --- a/comet/api/core.py +++ b/comet/api/core.py @@ -1,5 +1,7 @@ import PTT import RTN +import random +import string from fastapi import APIRouter, Request from fastapi.responses import RedirectResponse @@ -61,7 +63,7 @@ async def manifest(b64config: str = None): debrid_extension = get_debrid_extension(config["debridService"]) return { - "id": settings.ADDON_ID, + "id": f"{settings.ADDON_ID}.{''.join(random.choice(string.ascii_letters) for _ in range(4))}", "name": f"{settings.ADDON_NAME}{(' | ' + debrid_extension) if debrid_extension is not None else ''}", "description": "Stremio's fastest torrent/debrid search add-on.", "version": "1.0.0", diff --git a/comet/api/stream.py b/comet/api/stream.py index 51627a3..239c21c 100644 --- a/comet/api/stream.py +++ b/comet/api/stream.py @@ -213,9 +213,7 @@ async def stream( if "searched" in hash: continue - all_sorted_ranked_files[hash] = orjson.loads( - result["data"] - ) + all_sorted_ranked_files[hash] = orjson.loads(result["data"]) if len(all_sorted_ranked_files) != 0 and set(indexers).issubset(trackers_found): debrid_extension = get_debrid_extension( @@ -660,22 +658,30 @@ async def playback(request: Request, b64config: str, hash: str, index: str): range_header = request.headers.get("range", "bytes=0-") try: - response = await session.head( - download_link, headers={"Range": range_header} - ) + if config["debridService"] != "torbox": + response = await session.head( + download_link, headers={"Range": range_header} + ) + else: + response = await session.get( + download_link, headers={"Range": range_header} + ) except aiohttp.ClientResponseError as e: if e.status == 503 and config["debridService"] == "alldebrid": - proxy = ( - settings.DEBRID_PROXY_URL - ) # proxy is not needed to proxy realdebrid stream + proxy = ( + settings.DEBRID_PROXY_URL + ) # proxy is needed only to proxy alldebrid streams - response = await session.head( - download_link, headers={"Range": range_header}, proxy=proxy - ) + response = await session.head( + download_link, headers={"Range": range_header}, proxy=proxy + ) else: - raise + logger.warning(f"Exception while proxying {download_link}: {e}") + return - if response.status == 206: + if response.status == 206 or ( + response.status == 200 and config["debridService"] == "torbox" + ): id = str(uuid.uuid4()) await database.execute( f"INSERT {'OR IGNORE ' if settings.DATABASE_TYPE == 'sqlite' else ''}INTO active_connections (id, ip, content, timestamp) VALUES (:id, :ip, :content, :timestamp){' ON CONFLICT DO NOTHING' if settings.DATABASE_TYPE == 'postgresql' else ''}", diff --git a/comet/debrid/debridlink.py b/comet/debrid/debridlink.py index e7206de..b3f7261 100644 --- a/comet/debrid/debridlink.py +++ b/comet/debrid/debridlink.py @@ -29,20 +29,28 @@ class DebridLink: 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}" - ) + responses = [] + for hash in chunk: + try: + add_torrent = await self.session.post( + f"{self.api_url}/seedbox/add", + data={"url": hash, "wait": True, "async": True}, + ) + add_torrent = await add_torrent.json() + + torrent_id = add_torrent["value"]["id"] + await self.session.delete(f"{self.api_url}/seedbox/{torrent_id}/remove") + + responses.append(add_torrent) + except: + pass + + return responses async def get_files( self, torrent_hashes: list, type: str, season: str, episode: str, kitsu: bool ): - chunk_size = 250 + chunk_size = 10 chunks = [ torrent_hashes[i : i + chunk_size] for i in range(0, len(torrent_hashes), chunk_size) @@ -54,61 +62,67 @@ class DebridLink: responses = await asyncio.gather(*tasks) - availability = [ - response for response in responses if response and response.get("success") - ] + availability = [] + for response_list in responses: + for response in response_list: + availability.append(response) files = {} if type == "series": for result in availability: - for hash, torrent_data in result["value"].items(): - for file in torrent_data["files"]: - filename = file["name"] + torrent_files = result["value"]["files"] + for file in torrent_files: + if file["downloadPercent"] != 100: + continue - if not is_video(filename): + filename = file["name"] + + if not is_video(filename): + continue + + if "sample" in filename.lower(): + 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 - if "sample" in filename.lower(): - continue + files[result["value"]["hashString"]] = { + "index": torrent_files.index(file), + "title": filename, + "size": file["size"], + } - 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[hash] = { - "index": torrent_data["files"].index(file), - "title": filename, - "size": file["size"], - } - - break + break else: for result in availability: - for hash, torrent_data in result["value"].items(): - for file in torrent_data["files"]: - filename = file["name"] + value = result["value"] + torrent_files = value["files"] + for file in torrent_files: + if file["downloadPercent"] != 100: + continue - if not is_video(filename): - continue + filename = file["name"] - if "sample" in filename.lower(): - continue + if not is_video(filename): + continue - files[hash] = { - "index": torrent_data["files"].index(file), - "title": filename, - "size": file["size"], - } + if "sample" in filename.lower(): + continue - break + files[value["hashString"]] = { + "index": torrent_files.index(file), + "title": filename, + "size": file["size"], + } return files diff --git a/comet/debrid/torbox.py b/comet/debrid/torbox.py index 887c2ff..2e9cd6d 100644 --- a/comet/debrid/torbox.py +++ b/comet/debrid/torbox.py @@ -43,7 +43,7 @@ class TorBox: async def get_files( self, torrent_hashes: list, type: str, season: str, episode: str, kitsu: bool ): - chunk_size = 100 + chunk_size = 50 chunks = [ torrent_hashes[i : i + chunk_size] for i in range(0, len(torrent_hashes), chunk_size) diff --git a/comet/utils/general.py b/comet/utils/general.py index 074d2a0..375da71 100644 --- a/comet/utils/general.py +++ b/comet/utils/general.py @@ -716,7 +716,9 @@ async def add_torrent_to_cache( for indexer in indexers: hash = f"searched-{indexer}-{name}-{season}-{episode}" - searched = copy.deepcopy(sorted_ranked_files[list(sorted_ranked_files.keys())[0]]) + searched = copy.deepcopy( + sorted_ranked_files[list(sorted_ranked_files.keys())[0]] + ) searched["infohash"] = hash searched["data"]["tracker"] = indexer