Update app.py
Browse files
app.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
| 1 |
from fastapi import FastAPI, File, UploadFile, Request
|
| 2 |
-
from fastapi.responses import HTMLResponse, JSONResponse, StreamingResponse
|
| 3 |
import requests
|
| 4 |
-
import time
|
| 5 |
import asyncio
|
| 6 |
from typing import Dict
|
| 7 |
import os
|
|
@@ -445,7 +444,7 @@ HTML_CONTENT = """
|
|
| 445 |
text-align: center;
|
| 446 |
}
|
| 447 |
|
| 448 |
-
|
| 449 |
.quick-open-content video,
|
| 450 |
.quick-open-content audio {
|
| 451 |
max-width: 100%;
|
|
@@ -889,7 +888,7 @@ HTML_CONTENT = """
|
|
| 889 |
historyModal.style.display = "block";
|
| 890 |
}
|
| 891 |
|
| 892 |
-
|
| 893 |
quickOpenContent.innerHTML = '';
|
| 894 |
const fullUrl = window.location.origin + url;
|
| 895 |
|
|
@@ -947,7 +946,7 @@ async def handle_upload(file: UploadFile = File(...)):
|
|
| 947 |
|
| 948 |
cookies = await get_cookies()
|
| 949 |
if 'csrftoken' not in cookies or 'sessionid' not in cookies:
|
| 950 |
-
return JSONResponse(content={"error": "Failed"}, status_code=500)
|
| 951 |
|
| 952 |
original_extension = os.path.splitext(file.filename)[1][1:]
|
| 953 |
supported_types = ['mp4', 'png', 'jpg', 'jpeg', 'gif', 'mp3', 'pdf', 'txt']
|
|
@@ -961,12 +960,15 @@ async def handle_upload(file: UploadFile = File(...)):
|
|
| 961 |
|
| 962 |
upload_result = await initiate_upload(cookies, temp_filename, content_type)
|
| 963 |
if not upload_result or 'upload_url' not in upload_result:
|
| 964 |
-
return JSONResponse(content={"error": "Failed to upload"}, status_code=500)
|
|
|
|
|
|
|
|
|
|
| 965 |
|
| 966 |
file_content = await file.read()
|
| 967 |
upload_success = await retry_upload(upload_result['upload_url'], file_content, content_type)
|
| 968 |
if not upload_success:
|
| 969 |
-
return JSONResponse(content={"error": "
|
| 970 |
|
| 971 |
original_url = upload_result['serving_url']
|
| 972 |
mirrored_url = f"/upload/{original_url.split('/pbxt/')[1]}"
|
|
@@ -985,25 +987,31 @@ async def handle_file_stream(path: str, request: Request):
|
|
| 985 |
|
| 986 |
range_header = request.headers.get('Range')
|
| 987 |
headers = {'Range': range_header} if range_header else {}
|
| 988 |
-
|
|
|
|
|
|
|
|
|
|
| 989 |
|
| 990 |
-
|
| 991 |
-
|
| 992 |
-
|
| 993 |
|
| 994 |
-
|
| 995 |
-
|
| 996 |
-
|
| 997 |
|
| 998 |
-
|
| 999 |
-
|
| 1000 |
|
| 1001 |
-
|
| 1002 |
-
|
| 1003 |
-
|
| 1004 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1005 |
|
| 1006 |
-
return StreamingResponse(generate(), status_code=response.status_code, headers=headers)
|
| 1007 |
|
| 1008 |
@app.get("/embed")
|
| 1009 |
async def embed_video(url: str, thumbnail: str):
|
|
@@ -1051,8 +1059,9 @@ async def get_cookies() -> Dict[str, str]:
|
|
| 1051 |
response = requests.get('https://replicate.com/levelsio/neon-tokyo', headers={
|
| 1052 |
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36'
|
| 1053 |
})
|
|
|
|
| 1054 |
return dict(response.cookies)
|
| 1055 |
-
except
|
| 1056 |
print(f'Error fetching the page: {e}')
|
| 1057 |
return {}
|
| 1058 |
|
|
@@ -1066,37 +1075,37 @@ async def initiate_upload(cookies: Dict[str, str], filename: str, content_type:
|
|
| 1066 |
'Origin': 'https://replicate.com',
|
| 1067 |
'Accept': '*/*',
|
| 1068 |
'Accept-Language': 'en-US,en;q=0.5',
|
| 1069 |
-
'Accept-Encoding': '
|
| 1070 |
'Sec-Fetch-Dest': 'empty',
|
| 1071 |
'Sec-Fetch-Mode': 'cors',
|
| 1072 |
'Sec-Fetch-Site': 'same-origin',
|
| 1073 |
-
'Sec-GPC': '1',
|
| 1074 |
-
'Priority': 'u=1, i'
|
| 1075 |
})
|
|
|
|
| 1076 |
return response.json()
|
| 1077 |
-
except
|
| 1078 |
print(f'Error initiating upload: {e}')
|
| 1079 |
-
|
| 1080 |
|
| 1081 |
-
async def
|
| 1082 |
try:
|
| 1083 |
response = requests.put(upload_url, data=file_content, headers={'Content-Type': content_type})
|
|
|
|
| 1084 |
return response.status_code == 200
|
| 1085 |
-
except
|
| 1086 |
print(f'Error uploading file: {e}')
|
| 1087 |
return False
|
| 1088 |
|
| 1089 |
async def retry_upload(upload_url: str, file_content: bytes, content_type: str, max_retries: int = 5, delay: int = 1) -> bool:
|
| 1090 |
-
|
| 1091 |
try:
|
| 1092 |
-
success = await
|
| 1093 |
if success:
|
| 1094 |
return True
|
| 1095 |
-
print("Upload failed. Retrying...")
|
| 1096 |
except Exception as e:
|
| 1097 |
-
print(f"Error during upload: {e}")
|
| 1098 |
|
| 1099 |
await asyncio.sleep(delay)
|
| 1100 |
delay = min(delay * 2, 60)
|
| 1101 |
|
| 1102 |
-
return False
|
|
|
|
| 1 |
from fastapi import FastAPI, File, UploadFile, Request
|
| 2 |
+
from fastapi.responses import HTMLResponse, JSONResponse, StreamingResponse
|
| 3 |
import requests
|
|
|
|
| 4 |
import asyncio
|
| 5 |
from typing import Dict
|
| 6 |
import os
|
|
|
|
| 444 |
text-align: center;
|
| 445 |
}
|
| 446 |
|
| 447 |
+
.quick-open-content img,
|
| 448 |
.quick-open-content video,
|
| 449 |
.quick-open-content audio {
|
| 450 |
max-width: 100%;
|
|
|
|
| 888 |
historyModal.style.display = "block";
|
| 889 |
}
|
| 890 |
|
| 891 |
+
function quickOpen(url, fileName, originalExtension) {
|
| 892 |
quickOpenContent.innerHTML = '';
|
| 893 |
const fullUrl = window.location.origin + url;
|
| 894 |
|
|
|
|
| 946 |
|
| 947 |
cookies = await get_cookies()
|
| 948 |
if 'csrftoken' not in cookies or 'sessionid' not in cookies:
|
| 949 |
+
return JSONResponse(content={"error": "Failed to get cookies from Replicate."}, status_code=500)
|
| 950 |
|
| 951 |
original_extension = os.path.splitext(file.filename)[1][1:]
|
| 952 |
supported_types = ['mp4', 'png', 'jpg', 'jpeg', 'gif', 'mp3', 'pdf', 'txt']
|
|
|
|
| 960 |
|
| 961 |
upload_result = await initiate_upload(cookies, temp_filename, content_type)
|
| 962 |
if not upload_result or 'upload_url' not in upload_result:
|
| 963 |
+
return JSONResponse(content={"error": "Failed to initiate upload with Replicate."}, status_code=500)
|
| 964 |
+
|
| 965 |
+
# Log the real Replicate URL
|
| 966 |
+
print(f"Real Replicate URL: {upload_result['serving_url']}")
|
| 967 |
|
| 968 |
file_content = await file.read()
|
| 969 |
upload_success = await retry_upload(upload_result['upload_url'], file_content, content_type)
|
| 970 |
if not upload_success:
|
| 971 |
+
return JSONResponse(content={"error": "File upload to Replicate failed after multiple attempts."}, status_code=500)
|
| 972 |
|
| 973 |
original_url = upload_result['serving_url']
|
| 974 |
mirrored_url = f"/upload/{original_url.split('/pbxt/')[1]}"
|
|
|
|
| 987 |
|
| 988 |
range_header = request.headers.get('Range')
|
| 989 |
headers = {'Range': range_header} if range_header else {}
|
| 990 |
+
|
| 991 |
+
try:
|
| 992 |
+
response = requests.get(original_url, headers=headers, stream=True)
|
| 993 |
+
response.raise_for_status()
|
| 994 |
|
| 995 |
+
def generate():
|
| 996 |
+
for chunk in response.iter_content(chunk_size=8192):
|
| 997 |
+
yield chunk
|
| 998 |
|
| 999 |
+
response_headers = dict(response.headers)
|
| 1000 |
+
response_headers['Access-Control-Allow-Origin'] = '*'
|
| 1001 |
+
response_headers['Content-Disposition'] = 'inline'
|
| 1002 |
|
| 1003 |
+
if response.status_code == 206:
|
| 1004 |
+
response_headers['Content-Range'] = response.headers.get('Content-Range')
|
| 1005 |
|
| 1006 |
+
original_extension = os.path.splitext(path)[1][1:]
|
| 1007 |
+
content_type, _ = mimetypes.guess_type(f"file.{original_extension}")
|
| 1008 |
+
if content_type:
|
| 1009 |
+
response_headers['Content-Type'] = content_type
|
| 1010 |
+
|
| 1011 |
+
return StreamingResponse(generate(), status_code=response.status_code, headers=response_headers)
|
| 1012 |
+
except requests.exceptions.RequestException as e:
|
| 1013 |
+
return JSONResponse(content={"error": f"Failed to fetch file from Replicate: {e}"}, status_code=500)
|
| 1014 |
|
|
|
|
| 1015 |
|
| 1016 |
@app.get("/embed")
|
| 1017 |
async def embed_video(url: str, thumbnail: str):
|
|
|
|
| 1059 |
response = requests.get('https://replicate.com/levelsio/neon-tokyo', headers={
|
| 1060 |
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36'
|
| 1061 |
})
|
| 1062 |
+
response.raise_for_status()
|
| 1063 |
return dict(response.cookies)
|
| 1064 |
+
except requests.exceptions.RequestException as e:
|
| 1065 |
print(f'Error fetching the page: {e}')
|
| 1066 |
return {}
|
| 1067 |
|
|
|
|
| 1075 |
'Origin': 'https://replicate.com',
|
| 1076 |
'Accept': '*/*',
|
| 1077 |
'Accept-Language': 'en-US,en;q=0.5',
|
| 1078 |
+
'Accept-Encoding': 'gzip, deflate, br',
|
| 1079 |
'Sec-Fetch-Dest': 'empty',
|
| 1080 |
'Sec-Fetch-Mode': 'cors',
|
| 1081 |
'Sec-Fetch-Site': 'same-origin',
|
|
|
|
|
|
|
| 1082 |
})
|
| 1083 |
+
response.raise_for_status()
|
| 1084 |
return response.json()
|
| 1085 |
+
except requests.exceptions.RequestException as e:
|
| 1086 |
print(f'Error initiating upload: {e}')
|
| 1087 |
+
return {}
|
| 1088 |
|
| 1089 |
+
async def upload_file_to_gcs(upload_url: str, file_content: bytes, content_type: str) -> bool:
|
| 1090 |
try:
|
| 1091 |
response = requests.put(upload_url, data=file_content, headers={'Content-Type': content_type})
|
| 1092 |
+
response.raise_for_status()
|
| 1093 |
return response.status_code == 200
|
| 1094 |
+
except requests.exceptions.RequestException as e:
|
| 1095 |
print(f'Error uploading file: {e}')
|
| 1096 |
return False
|
| 1097 |
|
| 1098 |
async def retry_upload(upload_url: str, file_content: bytes, content_type: str, max_retries: int = 5, delay: int = 1) -> bool:
|
| 1099 |
+
for attempt in range(max_retries):
|
| 1100 |
try:
|
| 1101 |
+
success = await upload_file_to_gcs(upload_url, file_content, content_type)
|
| 1102 |
if success:
|
| 1103 |
return True
|
| 1104 |
+
print(f"Upload attempt {attempt + 1} failed. Retrying in {delay} seconds...")
|
| 1105 |
except Exception as e:
|
| 1106 |
+
print(f"Error during upload attempt {attempt + 1}: {e}")
|
| 1107 |
|
| 1108 |
await asyncio.sleep(delay)
|
| 1109 |
delay = min(delay * 2, 60)
|
| 1110 |
|
| 1111 |
+
return False
|