mirror of
https://github.com/Viren070/AIOStremio.git
synced 2025-12-01 23:24:19 +01:00
first commit
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Dict, List
|
||||
|
||||
|
||||
class StreamingService(ABC):
|
||||
@abstractmethod
|
||||
async def get_streams(self, meta_id: str) -> List[Dict]:
|
||||
pass
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def name(self) -> str:
|
||||
pass
|
||||
@@ -0,0 +1,67 @@
|
||||
import base64
|
||||
import os
|
||||
from typing import Dict, List
|
||||
|
||||
import httpx
|
||||
from fastapi import HTTPException
|
||||
|
||||
from utils.config import config
|
||||
from utils.logger import logger
|
||||
|
||||
from .base import StreamingService
|
||||
|
||||
|
||||
class CometService(StreamingService):
|
||||
def __init__(self):
|
||||
self.base_url = config.get("addon_config", "comet", "base_url")
|
||||
self.debrid_api_key = config.get_addon_debrid_api_key("comet")
|
||||
self.debrid_service = config.get_addon_debrid_service("comet")
|
||||
self.options = f"""{{
|
||||
"indexers": ["bitsearch", "eztv", "thepiratebay", "therarbg", "yts"],
|
||||
"maxResults": 0,
|
||||
"maxResultsPerResolution": 0,
|
||||
"maxSize": 0,
|
||||
"reverseResultOrder": false,
|
||||
"removeTrash": true,
|
||||
"resultFormat": ["All"],
|
||||
"resolutions": ["All"],
|
||||
"languages": ["All"],
|
||||
"debridService": "{self.debrid_service}",
|
||||
"debridApiKey": "{self.debrid_api_key}",
|
||||
"stremthruUrl": "",
|
||||
"debridStreamProxyPassword": ""
|
||||
}}"""
|
||||
self.options_encoded = base64.b64encode(self.options.encode()).decode("utf-8")
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "Comet"
|
||||
|
||||
async def _fetch_from_comet(self, url: str) -> Dict:
|
||||
async with httpx.AsyncClient() as client:
|
||||
try:
|
||||
response = await client.get(url)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
logger.debug(f"Comet response: {data}")
|
||||
return data
|
||||
except httpx.HTTPError as e:
|
||||
logger.error(f"Comet request failed: {str(e)}")
|
||||
raise HTTPException(status_code=502, detail="Upstream service error")
|
||||
|
||||
async def get_streams(self, meta_id: str) -> List[Dict]:
|
||||
url = f"{self.base_url}/{self.options_encoded}/stream/{meta_id}"
|
||||
logger.debug(f"Comet stream url: {url}")
|
||||
data = await self._fetch_from_comet(url)
|
||||
streams = data.get("streams", [])
|
||||
for stream in streams:
|
||||
stream["service"] = self.name
|
||||
|
||||
stream_name = stream.get("name", "")
|
||||
if stream_name.startswith("["):
|
||||
prefix = stream_name[1:stream_name.find("]")] if "]" in stream_name else ""
|
||||
stream["is_cached"] = "⚡" in prefix
|
||||
else:
|
||||
stream["is_cached"] = True
|
||||
|
||||
return streams
|
||||
@@ -0,0 +1,53 @@
|
||||
import base64
|
||||
import os
|
||||
from typing import Dict, List
|
||||
|
||||
import httpx
|
||||
from fastapi import HTTPException
|
||||
|
||||
from utils.config import config
|
||||
from utils.logger import logger
|
||||
|
||||
from .base import StreamingService
|
||||
|
||||
|
||||
class DebridioService(StreamingService):
|
||||
def __init__(self):
|
||||
self.base_url = "https://debridio.adobotec.com"
|
||||
self.debrid_api_key = config.get_addon_debrid_api_key("debridio")
|
||||
self.debrid_service = config.get_addon_debrid_service("debridio")
|
||||
self.options = f'{{"provider":"{self.debrid_service}","apiKey":"{self.debrid_api_key}","disableUncached":false,"qualityOrder":[],"excludeSize":"","maxReturnPerQuality":""}}'
|
||||
self.options_encoded = base64.b64encode(self.options.encode()).decode("utf-8")
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "Debridio"
|
||||
|
||||
async def _fetch_from_debridio(self, url: str) -> Dict:
|
||||
async with httpx.AsyncClient() as client:
|
||||
try:
|
||||
response = await client.get(url)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
logger.debug(f"Debridio response: {data}")
|
||||
return data
|
||||
except httpx.HTTPError as e:
|
||||
logger.error(f"Debridio request failed: {str(e)}")
|
||||
raise HTTPException(status_code=502, detail="Upstream service error")
|
||||
|
||||
async def get_streams(self, meta_id: str) -> List[Dict]:
|
||||
url = f"{self.base_url}/{self.options_encoded}/stream/{meta_id}"
|
||||
logger.debug(f"Debridio stream url: {url}")
|
||||
data = await self._fetch_from_debridio(url)
|
||||
streams = data.get("streams", [])
|
||||
for stream in streams:
|
||||
stream["service"] = self.name
|
||||
|
||||
stream_name = stream.get("name", "")
|
||||
if stream_name.startswith("["):
|
||||
prefix = stream_name[1:stream_name.find("]")] if "]" in stream_name else ""
|
||||
stream["is_cached"] = "+" in prefix
|
||||
else:
|
||||
stream["is_cached"] = True
|
||||
|
||||
return streams
|
||||
@@ -0,0 +1,46 @@
|
||||
import os
|
||||
from typing import Dict, List
|
||||
|
||||
import httpx
|
||||
from fastapi import HTTPException
|
||||
|
||||
from utils.logger import logger
|
||||
|
||||
from .base import StreamingService
|
||||
|
||||
|
||||
class EasynewsService(StreamingService):
|
||||
def __init__(self):
|
||||
self.base_url = "https://ea627ddf0ee7-easynews.baby-beamup.club"
|
||||
self.username = os.getenv("EASYNEWS_USERNAME")
|
||||
self.password = os.getenv("EASYNEWS_PASSWORD")
|
||||
self.options = f"%7B%22username%22%3A%22{self.username}%22%2C%22password%22%3A%22{self.password}%22%7D"
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "Easynews"
|
||||
|
||||
async def _fetch_from_easynews(self, url: str) -> Dict:
|
||||
async with httpx.AsyncClient() as client:
|
||||
try:
|
||||
response = await client.get(url)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
logger.debug(f"Easynews response: {data}")
|
||||
return data
|
||||
except httpx.HTTPError as e:
|
||||
logger.error(f"Easynews request failed: {str(e)}")
|
||||
raise HTTPException(status_code=502, detail="Upstream service error")
|
||||
|
||||
async def get_streams(self, meta_id: str) -> List[Dict]:
|
||||
url = f"{self.base_url}/{self.options}/stream/{meta_id}"
|
||||
logger.debug(f"Easynews stream url: {url}")
|
||||
data = await self._fetch_from_easynews(url)
|
||||
streams = data.get("streams", [])
|
||||
for stream in streams:
|
||||
stream["service"] = self.name
|
||||
|
||||
# Easynews doesn't have a cache
|
||||
stream["is_cached"] = True
|
||||
|
||||
return streams
|
||||
@@ -0,0 +1,45 @@
|
||||
import os
|
||||
from typing import Dict, List
|
||||
|
||||
import httpx
|
||||
from fastapi import HTTPException
|
||||
|
||||
from utils.logger import logger
|
||||
|
||||
from .base import StreamingService
|
||||
|
||||
|
||||
class MediaFusionService(StreamingService):
|
||||
def __init__(self):
|
||||
self.base_url = "https://mediafusion.elfhosted.com"
|
||||
# Generate a MediaFusion URL, then copy the data between https://mediafusion.elfhosted.com/ and /manifest.json
|
||||
self.options = os.getenv("MEDIAFUSION_OPTIONS")
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "MediaFusion"
|
||||
|
||||
async def _fetch_from_mediafusion(self, url: str) -> Dict:
|
||||
async with httpx.AsyncClient(timeout=15) as client:
|
||||
try:
|
||||
response = await client.get(url)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
logger.debug(f"MediaFusion response: {data}")
|
||||
return data
|
||||
except httpx.HTTPError as e:
|
||||
logger.error(f"MediaFusion request failed: {str(e)}")
|
||||
raise HTTPException(status_code=502, detail="Upstream service error")
|
||||
|
||||
async def get_streams(self, meta_id: str) -> List[Dict]:
|
||||
url = f"{self.base_url}/{self.options}/stream/{meta_id}"
|
||||
logger.debug(f"MediaFusion stream url: {url}")
|
||||
data = await self._fetch_from_mediafusion(url)
|
||||
streams = data.get("streams", [])
|
||||
for stream in streams:
|
||||
stream["service"] = self.name
|
||||
|
||||
if "⚡" in stream["name"]:
|
||||
stream["is_cached"] = True
|
||||
|
||||
return streams
|
||||
@@ -0,0 +1,48 @@
|
||||
import base64
|
||||
import os
|
||||
from typing import Dict, List
|
||||
|
||||
import httpx
|
||||
from fastapi import HTTPException
|
||||
|
||||
from utils.config import config
|
||||
from utils.logger import logger
|
||||
|
||||
from .base import StreamingService
|
||||
|
||||
|
||||
class PeerflixService(StreamingService):
|
||||
def __init__(self):
|
||||
self.base_url = "https://peerflix-addon.onrender.com"
|
||||
self.debrid_api_key = config.get_addon_debrid_api_key("peerflix")
|
||||
self.debrid_service = config.get_addon_debrid_service("peerflix")
|
||||
self.options = f'language=en,es|debridoptions=nocatalog,nodownloadlinks|{self.debrid_service}={self.debrid_api_key}|sort=quality-desc'
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "Peerflix"
|
||||
|
||||
async def _fetch_from_peerflix(self, url: str) -> Dict:
|
||||
async with httpx.AsyncClient() as client:
|
||||
try:
|
||||
response = await client.get(url)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
logger.debug(f"Peerflix response: {data}")
|
||||
return data
|
||||
except httpx.HTTPError as e:
|
||||
logger.error(f"Peerflix request failed: {str(e)}")
|
||||
raise HTTPException(status_code=502, detail="Upstream service error")
|
||||
|
||||
async def get_streams(self, meta_id: str) -> List[Dict]:
|
||||
url = f"{self.base_url}/{self.options}/stream/{meta_id}"
|
||||
logger.debug(f"Peerflix stream url: {url}")
|
||||
data = await self._fetch_from_peerflix(url)
|
||||
streams = data.get("streams", [])
|
||||
for stream in streams:
|
||||
stream["service"] = self.name
|
||||
|
||||
# Peerflix streams are always cached
|
||||
stream["is_cached"] = True
|
||||
|
||||
return streams
|
||||
@@ -0,0 +1,41 @@
|
||||
import os
|
||||
from typing import Dict, List
|
||||
|
||||
import httpx
|
||||
from fastapi import HTTPException
|
||||
|
||||
from utils.logger import logger
|
||||
|
||||
from .base import StreamingService
|
||||
|
||||
|
||||
class TorboxService(StreamingService):
|
||||
def __init__(self):
|
||||
self.base_url = "https://stremio.torbox.app"
|
||||
self.debrid_api_key = os.getenv("DEBRID_API_KEY")
|
||||
self.options = f"{self.debrid_api_key}"
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "TorBox"
|
||||
|
||||
async def _fetch_from_torbox(self, url: str) -> Dict:
|
||||
async with httpx.AsyncClient(timeout=15) as client:
|
||||
try:
|
||||
response = await client.get(url)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
logger.debug(f"TorBox response: {data}")
|
||||
return data
|
||||
except httpx.HTTPError as e:
|
||||
logger.error(f"TorBox request failed: {str(e)}")
|
||||
raise HTTPException(status_code=502, detail="Upstream service error")
|
||||
|
||||
async def get_streams(self, meta_id: str) -> List[Dict]:
|
||||
url = f"{self.base_url}/{self.options}/stream/{meta_id}"
|
||||
logger.debug(f"TorBox stream url: {url}")
|
||||
data = await self._fetch_from_torbox(url)
|
||||
streams = data.get("streams", [])
|
||||
for stream in streams:
|
||||
stream["service"] = self.name
|
||||
return streams
|
||||
@@ -0,0 +1,51 @@
|
||||
import os
|
||||
from typing import Dict, List
|
||||
|
||||
import httpx
|
||||
from fastapi import HTTPException
|
||||
|
||||
from utils.config import config
|
||||
from utils.logger import logger
|
||||
|
||||
from .base import StreamingService
|
||||
|
||||
|
||||
class TorrentioService(StreamingService):
|
||||
def __init__(self):
|
||||
self.base_url = "https://torrentio.strem.fun"
|
||||
self.debrid_api_key = config.get_addon_debrid_api_key("torrentio")
|
||||
self.debrid_service = config.get_addon_debrid_service("torrentio")
|
||||
self.options = f"debridoptions=nocatalog|{self.debrid_service}={self.debrid_api_key}"
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "Torrentio"
|
||||
|
||||
async def _fetch_from_torrentio(self, url: str) -> Dict:
|
||||
async with httpx.AsyncClient() as client:
|
||||
try:
|
||||
response = await client.get(url)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
logger.debug(f"Torrentio response: {data}")
|
||||
return data
|
||||
except httpx.HTTPError as e:
|
||||
logger.error(f"Torrentio request failed: {str(e)}")
|
||||
raise HTTPException(status_code=502, detail="Upstream service error")
|
||||
|
||||
async def get_streams(self, meta_id: str) -> List[Dict]:
|
||||
url = f"{self.base_url}/{self.options}/stream/{meta_id}"
|
||||
logger.debug(f"Torrentio stream url: {url}")
|
||||
data = await self._fetch_from_torrentio(url)
|
||||
streams = data.get("streams", [])
|
||||
for stream in streams:
|
||||
stream["service"] = self.name
|
||||
|
||||
stream_name = stream.get("name", "")
|
||||
if stream_name.startswith("["):
|
||||
prefix = stream_name[1:stream_name.find("]")] if "]" in stream_name else ""
|
||||
stream["is_cached"] = "+" in prefix
|
||||
else:
|
||||
stream["is_cached"] = True
|
||||
|
||||
return streams
|
||||
@@ -0,0 +1,39 @@
|
||||
import os
|
||||
from typing import Dict, List
|
||||
|
||||
import httpx
|
||||
from fastapi import HTTPException
|
||||
|
||||
from utils.logger import logger
|
||||
|
||||
from .base import StreamingService
|
||||
|
||||
|
||||
class WatchHubService(StreamingService):
|
||||
def __init__(self):
|
||||
self.base_url = "https://watchhub.stkc.win"
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "WatchHub"
|
||||
|
||||
async def _fetch_from_watchhub(self, url: str) -> Dict:
|
||||
async with httpx.AsyncClient() as client:
|
||||
try:
|
||||
response = await client.get(url)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
logger.debug(f"WatchHub response: {data}")
|
||||
return data
|
||||
except httpx.HTTPError as e:
|
||||
logger.error(f"WatchHub request failed: {str(e)}")
|
||||
return {"streams": []}
|
||||
|
||||
async def get_streams(self, meta_id: str) -> List[Dict]:
|
||||
url = f"{self.base_url}/stream/{meta_id}"
|
||||
logger.debug(f"WatchHub stream url: {url}")
|
||||
data = await self._fetch_from_watchhub(url)
|
||||
streams = data.get("streams", [])
|
||||
for stream in streams:
|
||||
stream["service"] = self.name
|
||||
return streams
|
||||
Reference in New Issue
Block a user