| import httpx |
| import logging |
| from fastapi import FastAPI, HTTPException |
| from fastapi.middleware.cors import CORSMiddleware |
| from typing import List, Optional, Dict, Any |
| from pydantic import BaseModel |
|
|
| |
| VEGA_API_BASE = "https://sanch1tx-vega-providers.hf.space" |
| MODFLIX_JSON_URL = "https://raw.githubusercontent.com/himanshu8443/providers/main/modflix.json" |
|
|
| |
| |
| PROVIDER_ID_MAP = { |
| "vegamovies": "vega", |
| "moviesmod": "mod", |
| "uhdmovies": "uhd", |
| "moviesdrive": "drive", |
| "luxmovies": "luxMovies", |
| "topmovies": "topmovies", |
| "nfmirror": "netflixMirror", |
| "primemirror": "primeMirror", |
| "tokyoinsider": "tokyoInsider", |
| "skymovieshd": "skyMovieHD", |
| "moviebox": "movieBox", |
| "cinevood": "1cinevood", |
| "kmmovies": "kmMovies", |
| "katmoviefix": "katMovieFix", |
| "joya9tv1": "Joya9tv", |
| "cinewood": "1cinevood" |
| } |
|
|
| |
| DEFAULT_CATALOGS = { |
| "drive": [ |
| {"title": "Latest", "filter": ""}, |
| {"title": "Anime", "filter": "category/anime/"}, |
| {"title": "Netflix", "filter": "category/netflix/"}, |
| {"title": "4K", "filter": "category/2160p-4k/"}, |
| ], |
| "vega": [ |
| {"title": "New", "filter": ""}, |
| {"title": "Netflix", "filter": "web-series/netflix"}, |
| {"title": "Amazon Prime", "filter": "web-series/amazon-prime-video"}, |
| ], |
| "default": [ |
| {"title": "Latest", "filter": ""}, |
| {"title": "Trending", "filter": "trending"}, |
| ] |
| } |
|
|
| |
| FALLBACK_PROVIDERS = [ |
| {"name": "Vega", "value": "vega", "baseUrl": VEGA_API_BASE, "isActive": True}, |
| {"name": "UHD", "value": "uhd", "baseUrl": VEGA_API_BASE, "isActive": True}, |
| {"name": "Drive", "value": "drive", "baseUrl": VEGA_API_BASE, "isActive": True}, |
| {"name": "Movies4u", "value": "movies4u", "baseUrl": VEGA_API_BASE, "isActive": True}, |
| ] |
|
|
| app = FastAPI(title="Vega Providers Gateway") |
|
|
| app.add_middleware( |
| CORSMiddleware, |
| allow_origins=["*"], |
| allow_credentials=True, |
| allow_methods=["*"], |
| allow_headers=["*"], |
| ) |
|
|
| logging.basicConfig(level=logging.INFO) |
| logger = logging.getLogger("vega_gateway") |
|
|
| class ProviderModel(BaseModel): |
| name: str |
| value: str |
| baseUrl: str |
| isActive: bool |
|
|
| @app.get("/") |
| async def root(): |
| return {"status": "ok", "message": "Vega Python Gateway Active"} |
|
|
| @app.get("/providers", response_model=List[ProviderModel]) |
| async def get_providers(): |
| async with httpx.AsyncClient() as client: |
| try: |
| response = await client.get(MODFLIX_JSON_URL, timeout=4.0) |
| if response.status_code == 200: |
| data = response.json() |
| providers = [] |
| |
| raw_list = data if isinstance(data, list) else data.get("providers", []) |
| |
| for p in raw_list: |
| if isinstance(p, dict): |
| name = p.get("name") or "Unknown" |
| raw_val = p.get("value") or p.get("id") or name |
| |
| |
| val = PROVIDER_ID_MAP.get(raw_val.lower(), raw_val) |
| |
| if val: |
| providers.append({ |
| "name": name, |
| "value": val, |
| "baseUrl": p.get("baseUrl") or VEGA_API_BASE, |
| "isActive": True |
| }) |
| if providers: return providers |
| except Exception: |
| pass |
| return FALLBACK_PROVIDERS |
|
|
| @app.get("/{provider}/catalog") |
| async def get_catalog(provider: str): |
| |
| provider_id = PROVIDER_ID_MAP.get(provider.lower(), provider) |
| |
| url = f"{VEGA_API_BASE}/{provider_id}/catalog" |
| try: |
| async with httpx.AsyncClient() as client: |
| resp = await client.get(url, timeout=5.0) |
| if resp.status_code == 200: |
| data = resp.json() |
| if isinstance(data, list) and len(data) > 0: |
| return {"catalog": data} |
| if isinstance(data, dict) and "catalog" in data: |
| return data |
| except Exception: |
| pass |
| |
| fallback = DEFAULT_CATALOGS.get(provider_id) or DEFAULT_CATALOGS.get("default") |
| return {"catalog": fallback} |
|
|
| @app.get("/{provider}/posts") |
| async def get_posts(provider: str, filter: str = "", page: int = 1): |
| provider_id = PROVIDER_ID_MAP.get(provider.lower(), provider) |
| url = f"{VEGA_API_BASE}/{provider_id}/posts" |
| params = {"filter": filter, "page": page} |
| |
| async with httpx.AsyncClient() as client: |
| try: |
| resp = await client.get(url, params=params, timeout=12.0) |
| if resp.status_code == 200: |
| data = resp.json() |
| if isinstance(data, list): return data |
| |
| if isinstance(data, dict) and "error" in data: |
| logger.error(f"Upstream error for {provider_id}: {data['error']}") |
| except Exception as e: |
| logger.error(f"Error posts {provider_id}: {e}") |
| pass |
| return [] |
|
|
| @app.get("/{provider}/meta") |
| async def get_meta(provider: str, link: str): |
| provider_id = PROVIDER_ID_MAP.get(provider.lower(), provider) |
| url = f"{VEGA_API_BASE}/{provider_id}/meta" |
| params = {"link": link} |
| async with httpx.AsyncClient() as client: |
| try: |
| resp = await client.get(url, params=params, timeout=15.0) |
| if resp.status_code == 200: |
| return resp.json() |
| except Exception: |
| pass |
| raise HTTPException(status_code=404, detail="Meta not found") |
|
|
| @app.get("/{provider}/episodes") |
| async def get_episodes(provider: str, url: str): |
| provider_id = PROVIDER_ID_MAP.get(provider.lower(), provider) |
| api_url = f"{VEGA_API_BASE}/{provider_id}/episodes" |
| params = {"url": url} |
| async with httpx.AsyncClient() as client: |
| try: |
| resp = await client.get(api_url, params=params, timeout=15.0) |
| if resp.status_code == 200 and isinstance(resp.json(), list): |
| return resp.json() |
| except Exception: |
| pass |
| return [] |
|
|
| @app.get("/{provider}/stream") |
| async def get_stream(provider: str, link: str, type: str = "movie"): |
| provider_id = PROVIDER_ID_MAP.get(provider.lower(), provider) |
| api_url = f"{VEGA_API_BASE}/{provider_id}/stream" |
| params = {"link": link, "type": type} |
| async with httpx.AsyncClient() as client: |
| try: |
| resp = await client.get(api_url, params=params, timeout=45.0) |
| if resp.status_code == 200 and isinstance(resp.json(), list): |
| return resp.json() |
| except: |
| pass |
| return [] |