Spaces:
Paused
Paused
File size: 5,864 Bytes
75a43dd e519d79 75a43dd e519d79 75a43dd e519d79 75a43dd e519d79 75a43dd e519d79 75a43dd e519d79 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | import os
import random
import traceback
import logging
from fastapi import FastAPI, Depends, HTTPException, Security, Request
from fastapi.security.api_key import APIKeyHeader
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.middleware.cors import CORSMiddleware
from moviebox_api import (
Search, Session, SubjectType,
DownloadableMovieFilesDetail, DownloadableTVSeriesFilesDetail,
Trending, Homepage, MovieDetails, TVSeriesDetails,
Recommend, PopularSearch, HotMoviesAndTVSeries
)
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Your residential proxy list to defeat the 403 DataCenter Ban!
RAW_PROXIES = [
"31.59.20.176:6754:kfcqidym:pb146svuz0dy",
"23.95.150.145:6114:kfcqidym:pb146svuz0dy",
"198.23.239.134:6540:kfcqidym:pb146svuz0dy",
"45.38.107.97:6014:kfcqidym:pb146svuz0dy",
"107.172.163.27:6543:kfcqidym:pb146svuz0dy",
"198.105.121.200:6462:kfcqidym:pb146svuz0dy",
"64.137.96.74:6641:kfcqidym:pb146svuz0dy",
"216.10.27.159:6837:kfcqidym:pb146svuz0dy",
"142.111.67.146:5611:kfcqidym:pb146svuz0dy",
"191.96.254.138:6185:kfcqidym:pb146svuz0dy"
]
selected = random.choice(RAW_PROXIES)
ip, port, user, pw = selected.split(":")
PROXY_URL = f"http://{user}:{pw}@{ip}:{port}"
app = FastAPI(title="TorchFlix API")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
API_KEY = "elijah2909_secret_key"
api_key_header = APIKeyHeader(name="X-API-Key", auto_error=False)
async def get_api_key(api_key: str = Security(api_key_header)):
if api_key == API_KEY: return api_key
raise HTTPException(status_code=403, detail="Invalid API Key.")
# Start session with Residential Proxy
session = Session(proxy=PROXY_URL)
@app.middleware("http")
async def debug_requests(request: Request, call_next):
return await call_next(request)
@app.get("/", response_class=HTMLResponse)
async def serve_ui():
try:
with open("index.html", "r") as f:
return f.read()
except Exception as e:
return f"<h1>Error loading UI</h1><p>index.html not found! {e}</p>"
async def _get_target_item(query: str, type: str):
sub_type = SubjectType.MOVIES if type == "movie" else SubjectType.TV_SERIES
search = Search(session, query=query, subject_type=sub_type)
results = await search.get_content_model()
if not results.items: raise Exception(f"No {type} found for query: {query}")
return results.first_item
@app.get("/api/search")
async def search_media(query: str, type: str = "all", api_key: str = Depends(get_api_key)):
try:
sub_type = SubjectType.ALL
if type.lower() == "movie": sub_type = SubjectType.MOVIES
elif type.lower() == "series": sub_type = SubjectType.TV_SERIES
return await Search(session, query=query, subject_type=sub_type, per_page=15).get_content()
except Exception as e: return JSONResponse(status_code=500, content={"error": str(e)})
@app.get("/api/trending")
async def get_trending(api_key: str = Depends(get_api_key)):
try: return await Trending(session).get_content()
except Exception as e: return JSONResponse(status_code=500, content={"error": str(e)})
@app.get("/api/media-files")
async def get_media_files(query: str, type: str = "movie", season: int = 1, episode: int = 1, api_key: str = Depends(get_api_key)):
try:
target_item = await _get_target_item(query, type)
if type == "movie":
details = await DownloadableMovieFilesDetail(session, target_item).get_content_model()
else:
details = await DownloadableTVSeriesFilesDetail(session, target_item).get_content_model(season=season, episode=episode)
videos = [{"resolution": getattr(d, 'resolution', 0), "url": str(getattr(d, 'url', '')), "size": getattr(d, 'size', 0), "ext": getattr(d, 'ext', 'mp4')} for d in details.downloads]
subs = [{"language": getattr(c, 'lanName', ''), "url": str(getattr(c, 'url', '')), "ext": getattr(c, 'ext', 'srt')} for c in details.captions]
return {"status": "success", "title": target_item.title, "videos": videos, "subtitles": subs, "proxy_used": ip}
except Exception as e:
return JSONResponse(status_code=500, content={"error": str(e), "trace": traceback.format_exc()})
@app.get("/api/homepage")
async def get_homepage(api_key: str = Depends(get_api_key)):
try: return await Homepage(session).get_content()
except Exception as e: return JSONResponse(status_code=500, content={"error": str(e)})
@app.get("/api/details")
async def get_details(query: str, type: str = "movie", api_key: str = Depends(get_api_key)):
try:
target_item = await _get_target_item(query, type)
if type == "movie": return await MovieDetails(target_item, session).get_content()
else: return await TVSeriesDetails(target_item, session).get_content()
except Exception as e: return JSONResponse(status_code=500, content={"error": str(e)})
@app.get("/api/recommendations")
async def get_recommendations(query: str, type: str = "movie", api_key: str = Depends(get_api_key)):
try: return await Recommend(session, await _get_target_item(query, type)).get_content()
except Exception as e: return JSONResponse(status_code=500, content={"error": str(e)})
@app.get("/api/popular-searches")
async def get_popular_searches(api_key: str = Depends(get_api_key)):
try: return await PopularSearch(session).get_content()
except Exception as e: return JSONResponse(status_code=500, content={"error": str(e)})
@app.get("/api/hot")
async def get_hot(api_key: str = Depends(get_api_key)):
try: return await HotMoviesAndTVSeries(session).get_content()
except Exception as e: return JSONResponse(status_code=500, content={"error": str(e)}) |