Update app.py
Browse files
app.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
| 1 |
from fastapi.responses import JSONResponse, StreamingResponse, Response
|
| 2 |
from fastapi.middleware.cors import CORSMiddleware
|
| 3 |
from fastapi import FastAPI, HTTPException, Request
|
| 4 |
-
import mimetypes
|
| 5 |
from threading import Thread
|
| 6 |
from Instance import Instance
|
| 7 |
from api import LoadBalancerAPI
|
|
@@ -32,18 +31,25 @@ app.add_middleware(
|
|
| 32 |
allow_headers=["*"],
|
| 33 |
)
|
| 34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
async def serve_video(file_path: str, request: Request):
|
| 36 |
"""Serve video file with support for range requests and proper CORS headers."""
|
| 37 |
if not os.path.isfile(file_path):
|
| 38 |
raise HTTPException(status_code=404, detail="Video file not found")
|
| 39 |
-
|
| 40 |
file_size = os.path.getsize(file_path)
|
| 41 |
range_header = request.headers.get('range', None)
|
| 42 |
|
| 43 |
# Determine the MIME type based on the file extension
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
mime_type = 'application/octet-stream' # Fallback MIME type
|
| 47 |
|
| 48 |
# CORS headers to attach to all responses
|
| 49 |
cors_headers = {
|
|
@@ -132,28 +138,28 @@ async def get_movie_api(request: Request, title: str):
|
|
| 132 |
"""Endpoint to get the movie by title with support for range requests."""
|
| 133 |
if not title:
|
| 134 |
raise HTTPException(status_code=400, detail="Title parameter is required")
|
| 135 |
-
|
| 136 |
# Check if the film is already cached
|
| 137 |
if title in instance.FILM_STORE:
|
| 138 |
cache_path = instance.FILM_STORE[title]
|
| 139 |
if os.path.exists(cache_path):
|
| 140 |
return await serve_video(cache_path, request)
|
| 141 |
-
|
| 142 |
movie_path = instance.find_movie_path(title)
|
| 143 |
-
|
| 144 |
if not movie_path:
|
| 145 |
raise HTTPException(status_code=404, detail="Movie not found")
|
| 146 |
-
|
| 147 |
cache_path = os.path.join(CACHE_DIR, movie_path)
|
| 148 |
file_url = f"https://huggingface.co/{REPO}/resolve/main/{movie_path}"
|
| 149 |
film_id = instance.get_film_id(title)
|
| 150 |
-
|
| 151 |
# Start the download in a separate thread if not already downloading
|
| 152 |
if film_id not in instance.download_threads or not instance.download_threads[film_id].is_alive():
|
| 153 |
thread = Thread(target=instance.download_film, args=(file_url, TOKEN, cache_path, film_id, title))
|
| 154 |
instance.download_threads[film_id] = thread
|
| 155 |
thread.start()
|
| 156 |
-
|
| 157 |
return JSONResponse({"status": "Download started", "film_id": film_id})
|
| 158 |
|
| 159 |
@app.get("/api/get/tv/{title}/{season}/{episode}")
|
|
@@ -171,7 +177,7 @@ async def get_tv_show_api(request: Request, title: str, season: str, episode: st
|
|
| 171 |
return await serve_video(cache_path, request)
|
| 172 |
|
| 173 |
tv_path = instance.find_tv_path(title)
|
| 174 |
-
|
| 175 |
if not tv_path:
|
| 176 |
raise HTTPException(status_code=404, detail="TV show not found")
|
| 177 |
|
|
@@ -189,21 +195,21 @@ async def get_tv_show_api(request: Request, title: str, season: str, episode: st
|
|
| 189 |
|
| 190 |
if not episode_path:
|
| 191 |
raise HTTPException(status_code=404, detail="Episode not found")
|
| 192 |
-
|
| 193 |
cache_path = os.path.join(CACHE_DIR, episode_path)
|
| 194 |
file_url = f"https://huggingface.co/{REPO}/resolve/main/{episode_path}"
|
| 195 |
episode_id = instance.encode_episodeid(title, season, episode)
|
| 196 |
-
|
| 197 |
# Start the download in a separate thread if not already downloading
|
| 198 |
if episode_id not in instance.download_threads or not instance.download_threads[episode_id].is_alive():
|
| 199 |
thread = Thread(target=instance.download_episode, args=(file_url, TOKEN, cache_path, episode_id, title))
|
| 200 |
instance.download_threads[episode_id] = thread
|
| 201 |
thread.start()
|
| 202 |
-
|
| 203 |
return JSONResponse({"status": "Download started", "episode_id": episode_id})
|
| 204 |
|
| 205 |
@app.get("/api/get/progress/{id}")
|
| 206 |
async def get_progress_api(id: str):
|
| 207 |
"""Endpoint to get the download progress of a movie or TV show episode."""
|
| 208 |
progress = instance.get_download_progress(id)
|
| 209 |
-
return JSONResponse({"id": id, "progress": progress})
|
|
|
|
| 1 |
from fastapi.responses import JSONResponse, StreamingResponse, Response
|
| 2 |
from fastapi.middleware.cors import CORSMiddleware
|
| 3 |
from fastapi import FastAPI, HTTPException, Request
|
|
|
|
| 4 |
from threading import Thread
|
| 5 |
from Instance import Instance
|
| 6 |
from api import LoadBalancerAPI
|
|
|
|
| 31 |
allow_headers=["*"],
|
| 32 |
)
|
| 33 |
|
| 34 |
+
# Mapping of file extensions to MIME types
|
| 35 |
+
MIME_TYPES = {
|
| 36 |
+
".mp4": "video/mp4",
|
| 37 |
+
".webm": "video/webm",
|
| 38 |
+
".mkv": "video/webm",
|
| 39 |
+
".ts": "video/mp2t",
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
async def serve_video(file_path: str, request: Request):
|
| 43 |
"""Serve video file with support for range requests and proper CORS headers."""
|
| 44 |
if not os.path.isfile(file_path):
|
| 45 |
raise HTTPException(status_code=404, detail="Video file not found")
|
| 46 |
+
|
| 47 |
file_size = os.path.getsize(file_path)
|
| 48 |
range_header = request.headers.get('range', None)
|
| 49 |
|
| 50 |
# Determine the MIME type based on the file extension
|
| 51 |
+
file_extension = os.path.splitext(file_path)[1].lower()
|
| 52 |
+
mime_type = MIME_TYPES.get(file_extension, 'application/octet-stream') # Default to octet-stream if no match
|
|
|
|
| 53 |
|
| 54 |
# CORS headers to attach to all responses
|
| 55 |
cors_headers = {
|
|
|
|
| 138 |
"""Endpoint to get the movie by title with support for range requests."""
|
| 139 |
if not title:
|
| 140 |
raise HTTPException(status_code=400, detail="Title parameter is required")
|
| 141 |
+
|
| 142 |
# Check if the film is already cached
|
| 143 |
if title in instance.FILM_STORE:
|
| 144 |
cache_path = instance.FILM_STORE[title]
|
| 145 |
if os.path.exists(cache_path):
|
| 146 |
return await serve_video(cache_path, request)
|
| 147 |
+
|
| 148 |
movie_path = instance.find_movie_path(title)
|
| 149 |
+
|
| 150 |
if not movie_path:
|
| 151 |
raise HTTPException(status_code=404, detail="Movie not found")
|
| 152 |
+
|
| 153 |
cache_path = os.path.join(CACHE_DIR, movie_path)
|
| 154 |
file_url = f"https://huggingface.co/{REPO}/resolve/main/{movie_path}"
|
| 155 |
film_id = instance.get_film_id(title)
|
| 156 |
+
|
| 157 |
# Start the download in a separate thread if not already downloading
|
| 158 |
if film_id not in instance.download_threads or not instance.download_threads[film_id].is_alive():
|
| 159 |
thread = Thread(target=instance.download_film, args=(file_url, TOKEN, cache_path, film_id, title))
|
| 160 |
instance.download_threads[film_id] = thread
|
| 161 |
thread.start()
|
| 162 |
+
|
| 163 |
return JSONResponse({"status": "Download started", "film_id": film_id})
|
| 164 |
|
| 165 |
@app.get("/api/get/tv/{title}/{season}/{episode}")
|
|
|
|
| 177 |
return await serve_video(cache_path, request)
|
| 178 |
|
| 179 |
tv_path = instance.find_tv_path(title)
|
| 180 |
+
|
| 181 |
if not tv_path:
|
| 182 |
raise HTTPException(status_code=404, detail="TV show not found")
|
| 183 |
|
|
|
|
| 195 |
|
| 196 |
if not episode_path:
|
| 197 |
raise HTTPException(status_code=404, detail="Episode not found")
|
| 198 |
+
|
| 199 |
cache_path = os.path.join(CACHE_DIR, episode_path)
|
| 200 |
file_url = f"https://huggingface.co/{REPO}/resolve/main/{episode_path}"
|
| 201 |
episode_id = instance.encode_episodeid(title, season, episode)
|
| 202 |
+
|
| 203 |
# Start the download in a separate thread if not already downloading
|
| 204 |
if episode_id not in instance.download_threads or not instance.download_threads[episode_id].is_alive():
|
| 205 |
thread = Thread(target=instance.download_episode, args=(file_url, TOKEN, cache_path, episode_id, title))
|
| 206 |
instance.download_threads[episode_id] = thread
|
| 207 |
thread.start()
|
| 208 |
+
|
| 209 |
return JSONResponse({"status": "Download started", "episode_id": episode_id})
|
| 210 |
|
| 211 |
@app.get("/api/get/progress/{id}")
|
| 212 |
async def get_progress_api(id: str):
|
| 213 |
"""Endpoint to get the download progress of a movie or TV show episode."""
|
| 214 |
progress = instance.get_download_progress(id)
|
| 215 |
+
return JSONResponse({"id": id, "progress": progress})
|