diff --git a/mediaflow_proxy/extractors/__pycache__/doodstream.cpython-311.pyc b/mediaflow_proxy/extractors/__pycache__/doodstream.cpython-311.pyc new file mode 100644 index 0000000..1637648 Binary files /dev/null and b/mediaflow_proxy/extractors/__pycache__/doodstream.cpython-311.pyc differ diff --git a/mediaflow_proxy/extractors/__pycache__/mixdrop.cpython-311.pyc b/mediaflow_proxy/extractors/__pycache__/mixdrop.cpython-311.pyc new file mode 100644 index 0000000..7ec2777 Binary files /dev/null and b/mediaflow_proxy/extractors/__pycache__/mixdrop.cpython-311.pyc differ diff --git a/mediaflow_proxy/extractors/__pycache__/uqload.cpython-311.pyc b/mediaflow_proxy/extractors/__pycache__/uqload.cpython-311.pyc new file mode 100644 index 0000000..e31496d Binary files /dev/null and b/mediaflow_proxy/extractors/__pycache__/uqload.cpython-311.pyc differ diff --git a/mediaflow_proxy/extractors/doodstream.py b/mediaflow_proxy/extractors/doodstream.py new file mode 100644 index 0000000..a9caff4 --- /dev/null +++ b/mediaflow_proxy/extractors/doodstream.py @@ -0,0 +1,22 @@ +import httpx +import time +import re +from mediaflow_proxy.configs import settings +async def doodstream_url(d: str, use_request_proxy: bool): + async with httpx.AsyncClient(proxy=settings.proxy_url if use_request_proxy else None) as client: + headers = { + "Range": "bytes=0-", + "Referer": "https://d000d.com/", + } + + response = await client.get(d, follow_redirects=True) + if response.status_code == 200: + # Get unique timestamp for the request + real_time = str(int(time.time())) + pattern = r"(\/pass_md5\/.*?)'.*(\?token=.*?expiry=)" + match = re.search(pattern, response.text, re.DOTALL) + if match: + url =f'https://d000d.com{match[1]}' + rebobo = await client.get(url, headers=headers, follow_redirects=True) + final_url = f'{rebobo.text}123456789{match[2]}{real_time}' + return final_url \ No newline at end of file diff --git a/mediaflow_proxy/extractors/mixdrop.py b/mediaflow_proxy/extractors/mixdrop.py new file mode 100644 index 0000000..b04be24 --- /dev/null +++ b/mediaflow_proxy/extractors/mixdrop.py @@ -0,0 +1,24 @@ +import httpx +import re +import string +from mediaflow_proxy.configs import settings + + +async def mixdrop_url(d: str, use_request_proxy: bool): + headers = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.10; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3', + 'Accept-Language': 'en-US,en;q=0.5' + } + async with httpx.AsyncClient(proxy=settings.proxy_url if use_request_proxy else None) as client: + response = await client.get(d, headers=headers, follow_redirects=True,timeout = 30) + [s1, s2] = re.search(r"\}\('(.+)',.+,'(.+)'\.split", response.text).group(1, 2) + schema = s1.split(";")[2][5:-1] + terms = s2.split("|") + charset = string.digits + string.ascii_letters + d = dict() + for i in range(len(terms)): + d[charset[i]] = terms[i] or charset[i] + final_url = 'https:' + for c in schema: + final_url += d[c] if c in d else c + return final_url \ No newline at end of file diff --git a/mediaflow_proxy/extractors/uqload.py b/mediaflow_proxy/extractors/uqload.py new file mode 100644 index 0000000..e6b5022 --- /dev/null +++ b/mediaflow_proxy/extractors/uqload.py @@ -0,0 +1,13 @@ +import httpx +import re +from mediaflow_proxy.configs import settings + + +async def uqload_url(d: str, use_request_proxy: bool): + async with httpx.AsyncClient(proxy=settings.proxy_url if use_request_proxy else None) as client: + + response = await client.get(d, follow_redirects=True) + video_url_match = re.search(r'sources: \["(.*?)"\]', response.text) + if video_url_match: + final_url = video_url_match.group(1) + return final_url \ No newline at end of file diff --git a/mediaflow_proxy/extractors_routes.py b/mediaflow_proxy/extractors_routes.py new file mode 100644 index 0000000..c612a7c --- /dev/null +++ b/mediaflow_proxy/extractors_routes.py @@ -0,0 +1,61 @@ +from fastapi import APIRouter,Query +from fastapi.responses import JSONResponse +from .extractors.doodstream import doodstream_url +from .extractors.uqload import uqload_url +from .extractors.mixdrop import mixdrop_url +extractor_router = APIRouter() + + +@extractor_router.get("/doodstream") +async def doodstream_extractor(d: str = Query(..., description="DoodStream URL"), use_request_proxy: bool = Query(False, description="Whether to use the MediaFlow proxy configuration.")): + ''' + Extract a clean link from DoodStream URL + + Args: request (Request): The incoming HTTP request + + Returns: The clean link (url) and the headers needed to access the url + + N.B. You can't use a rotating proxy for this endpoint + ''' + final_url = await doodstream_url(d,use_request_proxy) + headers_dict = { + "Referer": "https://d000d.com/" + } #Needed Headers to access the Response + return JSONResponse(content={"url": final_url,"headers": headers_dict}) + + + +@extractor_router.get("/uqload") +async def uqload_extractor(d: str = Query(..., description="Uqload Url"), use_request_proxy: bool = Query(False, description="Whether to use the MediaFlow proxy configuration.")): + ''' + Extract a clean link from Uqload URL + + Args: request (Request): The incoming HTTP request + + Returns: The clean link (url) and the headers needed to access the url + + ''' + final_url = await uqload_url(d,use_request_proxy) + headers_dict = { + "Referer": "https://uqload.to/" + } + return JSONResponse(content={"url": final_url,"headers": headers_dict}) + + +@extractor_router.get("/mixdrop") +async def mixdrop_extractor(d: str = Query(..., description="MixDrop URL",), use_request_proxy: bool = Query(False, description="Whether to use the MediaFlow proxy configuration.")): + ''' + Extract a clean link from MixDrop URL + + Args: request (Request): The incoming HTTP request + + Returns: The clean link (url) and the headers needed to access the url + + ''' + final_url = await mixdrop_url(d,use_request_proxy) + headers_dict = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.10; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3" + } + return JSONResponse(content={"url": final_url,"headers": headers_dict}) + + diff --git a/mediaflow_proxy/main.py b/mediaflow_proxy/main.py index 127b767..9e62878 100644 --- a/mediaflow_proxy/main.py +++ b/mediaflow_proxy/main.py @@ -9,6 +9,7 @@ from starlette.staticfiles import StaticFiles from mediaflow_proxy.configs import settings from mediaflow_proxy.routes import proxy_router +from mediaflow_proxy.extractors_routes import extractor_router from mediaflow_proxy.schemas import GenerateUrlRequest from mediaflow_proxy.utils.crypto_utils import EncryptionHandler, EncryptionMiddleware from mediaflow_proxy.utils.http_utils import encode_mediaflow_proxy_url @@ -16,7 +17,7 @@ from mediaflow_proxy.utils.http_utils import encode_mediaflow_proxy_url logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s") app = FastAPI() api_password_query = APIKeyQuery(name="api_password", auto_error=False) -api_password_header = APIKeyHeader(name="api_password", auto_error=False) +api_password_header = APIKeyHeader(name="api_password", auto_error=False) app.add_middleware( CORSMiddleware, allow_origins=["*"], @@ -74,6 +75,8 @@ async def generate_encrypted_or_encoded_url(request: GenerateUrlRequest): app.include_router(proxy_router, prefix="/proxy", tags=["proxy"], dependencies=[Depends(verify_api_key)]) +app.include_router(extractor_router, prefix="/extractors", tags=["extractors"], dependencies=[Depends(verify_api_key)]) + static_path = resources.files("mediaflow_proxy").joinpath("static") app.mount("/", StaticFiles(directory=str(static_path), html=True), name="static")