rkihacker commited on
Commit
25a03e7
·
verified ·
1 Parent(s): 979306d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +113 -128
app.py CHANGED
@@ -1,15 +1,14 @@
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
7
  import mimetypes
8
- import json
9
 
10
  app = FastAPI()
11
 
12
- # The HTML_CONTENT remains the same as your provided version.
13
  HTML_CONTENT = """
14
  <!DOCTYPE html>
15
  <html lang="en">
@@ -446,7 +445,7 @@ HTML_CONTENT = """
446
  text-align: center;
447
  }
448
 
449
- .quick-open-content img,
450
  .quick-open-content video,
451
  .quick-open-content audio {
452
  max-width: 100%;
@@ -699,46 +698,45 @@ HTML_CONTENT = """
699
  const formData = new FormData();
700
  formData.append('file', file);
701
 
702
- const xhr = new XMLHttpRequest();
703
- xhr.open('POST', '/upload', true);
704
-
705
- xhr.upload.onprogress = (event) => {
706
- if (event.lengthComputable) {
707
- const percentComplete = (event.loaded / event.total) * 100;
708
- updateProgress(progressBar.querySelector('.progress'), percentComplete);
709
- }
710
- };
 
 
 
 
 
 
 
 
 
 
 
 
711
 
712
- xhr.onload = function() {
713
- loadingSpinner.style.display = 'none';
714
- uploadBtn.disabled = false;
715
-
716
- if (xhr.status === 200) {
717
- const response = JSON.parse(xhr.responseText);
718
- if (response.url) {
719
- addResultLink(response.url, file.name, response.originalExtension);
720
- saveToHistory(file.name, response.url, response.originalExtension);
721
- resetUploadState();
722
- } else {
723
- alert('Upload failed: ' + response.error);
724
- }
725
- } else {
726
- try {
727
- const errorResponse = JSON.parse(xhr.responseText);
728
- alert(`Error: ${errorResponse.error || 'An unknown error occurred.'}`);
729
- } catch (e) {
730
- alert(`An unexpected error occurred. Status: ${xhr.status}`);
731
- }
732
- }
733
- };
734
 
735
- xhr.onerror = function() {
736
- loadingSpinner.style.display = 'none';
737
- uploadBtn.disabled = false;
738
- alert('Network error occurred. Please try again.');
739
- };
 
740
 
741
- xhr.send(formData);
 
 
 
 
 
742
  }
743
 
744
  function createProgressBar(fileName) {
@@ -757,8 +755,11 @@ HTML_CONTENT = """
757
  return container;
758
  }
759
 
760
- function updateProgress(progressBar, percent) {
761
- progressBar.style.width = percent + '%';
 
 
 
762
  }
763
 
764
  function resetUploadState() {
@@ -888,7 +889,7 @@ HTML_CONTENT = """
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,12 +947,12 @@ async def handle_upload(file: UploadFile = File(...)):
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 authentication cookies from Replicate."}, status_code=500)
950
 
951
- original_extension = os.path.splitext(file.filename)[1][1:].lower()
952
  supported_types = ['mp4', 'png', 'jpg', 'jpeg', 'gif', 'mp3', 'pdf', 'txt']
953
 
954
- if original_extension in supported_types:
955
  temp_filename = file.filename
956
  content_type = file.content_type
957
  else:
@@ -960,66 +961,52 @@ async def handle_upload(file: UploadFile = File(...)):
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. The endpoint may be protected or changed."}, status_code=500)
964
-
965
- # Log the real Replicate URL for debugging
966
- print(f"Real Replicate Serving URL: {upload_result.get('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's storage 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]}"
975
 
976
- if original_extension not in supported_types:
977
- # If the original file was unsupported, the mirrored URL from replicate will have .png, remove it.
978
  mirrored_url = mirrored_url.replace('.png', '')
979
 
980
  return JSONResponse(content={"url": mirrored_url, "originalExtension": original_extension})
981
 
982
-
983
  @app.get("/upload/{path:path}")
984
  async def handle_file_stream(path: str, request: Request):
985
  original_url = f'https://replicate.delivery/pbxt/{path}'
986
 
987
- # If the path doesn't have a common extension, it's likely an unsupported type we wrapped in .png
988
- if not any(path.lower().endswith(f".{ext}") for ext in ['png', 'jpg', 'jpeg', 'gif', 'mp4', 'mp3', 'pdf', 'txt']):
989
  original_url += '.png'
990
 
991
  range_header = request.headers.get('Range')
992
  headers = {'Range': range_header} if range_header else {}
993
-
994
- try:
995
- response = requests.get(original_url, headers=headers, stream=True)
996
- response.raise_for_status()
997
-
998
- def generate():
999
- for chunk in response.iter_content(chunk_size=8192):
1000
- yield chunk
1001
 
1002
- response_headers = dict(response.headers)
1003
- response_headers['Access-Control-Allow-Origin'] = '*'
1004
- response_headers['Content-Disposition'] = 'inline'
1005
 
1006
- if response.status_code == 206:
1007
- response_headers['Content-Range'] = response.headers.get('Content-Range')
 
1008
 
1009
- # Guess content type from original extension in path for correct browser handling
1010
- original_extension = os.path.splitext(path)[1][1:]
1011
- content_type, _ = mimetypes.guess_type(f"file.{original_extension}")
1012
- if content_type:
1013
- response_headers['Content-Type'] = content_type
1014
 
1015
- return StreamingResponse(generate(), status_code=response.status_code, headers=response_headers)
1016
- except requests.exceptions.RequestException as e:
1017
- return JSONResponse(content={"error": f"Failed to fetch file from Replicate: {e}"}, status_code=500)
 
1018
 
 
1019
 
1020
  @app.get("/embed")
1021
- async def embed_video(url: str, thumbnail: str = "https://i.imgur.com/8liH2yB.png"):
1022
- # Added a default thumbnail
1023
  html = f'''
1024
  <html>
1025
  <head>
@@ -1037,81 +1024,79 @@ async def embed_video(url: str, thumbnail: str = "https://i.imgur.com/8liH2yB.pn
1037
  <meta property="og:image:type" content="image/png">
1038
  <style>
1039
  body, html {{ margin: 0; padding: 0; height: 100%; background: #000; }}
1040
- video {{ width: 100%; height: 100%; object-fit: contain; }}
 
1041
  </style>
1042
  </head>
1043
  <body>
1044
- <video controls autoplay>
 
1045
  <source src="{url}" type="video/mp4">
1046
  Your browser does not support the video tag.
1047
  </video>
 
 
 
 
 
 
 
1048
  </body>
1049
  </html>
1050
  '''
1051
  return HTMLResponse(content=html)
1052
 
1053
-
1054
  async def get_cookies() -> Dict[str, str]:
1055
  try:
1056
- response = requests.get('https://replicate.com/explore', headers={
1057
  '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'
1058
  })
1059
- response.raise_for_status()
1060
  return dict(response.cookies)
1061
- except requests.exceptions.RequestException as e:
1062
- print(f'Error fetching cookies from Replicate: {e}')
1063
  return {}
1064
 
1065
-
1066
  async def initiate_upload(cookies: Dict[str, str], filename: str, content_type: str) -> Dict:
1067
  url = f'https://replicate.com/api/upload/{filename}?content_type={content_type}'
1068
- headers = {
1069
- 'X-CSRFToken': cookies.get('csrftoken'),
1070
- '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',
1071
- 'Referer': 'https://replicate.com/explore',
1072
- 'Origin': 'https://replicate.com',
1073
- 'Accept': '*/*',
1074
- 'Accept-Language': 'en-US,en;q=0.5',
1075
- 'Accept-Encoding': 'gzip, deflate, br', # More standard encoding
1076
- 'Sec-Fetch-Dest': 'empty',
1077
- 'Sec-Fetch-Mode': 'cors',
1078
- 'Sec-Fetch-Site': 'same-origin',
1079
- }
1080
  try:
1081
- response = requests.post(url, cookies=cookies, headers=headers)
1082
- response.raise_for_status()
 
 
 
 
 
 
 
 
 
 
 
 
1083
  return response.json()
1084
- except requests.exceptions.HTTPError as http_err:
1085
- print(f'HTTP error during upload initiation: {http_err}')
1086
- print(f'Response status: {response.status_code}')
1087
- print(f'Response text: {response.text}')
1088
- return {}
1089
- except json.JSONDecodeError:
1090
- print('Failed to decode JSON from Replicate API.')
1091
- print(f'Response status: {response.status_code}')
1092
- print(f'Response text: {response.text}') # This is the crucial log
1093
- return {}
1094
  except Exception as e:
1095
- print(f'An unexpected error occurred during upload initiation: {e}')
1096
- return {}
1097
-
1098
 
1099
- async def upload_file_to_gcs(upload_url: str, file_content: bytes, content_type: str) -> bool:
1100
  try:
1101
  response = requests.put(upload_url, data=file_content, headers={'Content-Type': content_type})
1102
- response.raise_for_status()
1103
  return response.status_code == 200
1104
- except requests.exceptions.RequestException as e:
1105
- print(f'Error during final file upload to GCS: {e}')
1106
  return False
1107
 
1108
-
1109
- async def retry_upload(upload_url: str, file_content: bytes, content_type: str, max_retries: int = 3, delay: int = 1) -> bool:
1110
- for attempt in range(max_retries):
1111
- success = await upload_file_to_gcs(upload_url, file_content, content_type)
1112
- if success:
1113
- return True
1114
- print(f"Upload attempt {attempt + 1} failed. Retrying in {delay} seconds...")
 
 
 
1115
  await asyncio.sleep(delay)
1116
- delay *= 2
1117
- return False
 
 
1
  from fastapi import FastAPI, File, UploadFile, Request
2
+ from fastapi.responses import HTMLResponse, JSONResponse, StreamingResponse, FileResponse
3
  import requests
4
+ import time
5
  import asyncio
6
  from typing import Dict
7
  import os
8
  import mimetypes
 
9
 
10
  app = FastAPI()
11
 
 
12
  HTML_CONTENT = """
13
  <!DOCTYPE html>
14
  <html lang="en">
 
445
  text-align: center;
446
  }
447
 
448
+ .quick-open-content img,
449
  .quick-open-content video,
450
  .quick-open-content audio {
451
  max-width: 100%;
 
698
  const formData = new FormData();
699
  formData.append('file', file);
700
 
701
+ while (true) {
702
+ try {
703
+ const xhr = new XMLHttpRequest();
704
+ xhr.open('POST', '/upload', true);
705
+ xhr.upload.onprogress = (event) => updateProgress(event, progressBar.querySelector('.progress'));
706
+
707
+ xhr.onload = function() {
708
+ if (xhr.status === 200) {
709
+ const response = JSON.parse(xhr.responseText);
710
+ if (response.url) {
711
+ addResultLink(response.url, file.name, response.originalExtension);
712
+ saveToHistory(file.name, response.url, response.originalExtension);
713
+ resetUploadState();
714
+ return;
715
+ } else {
716
+ throw new Error('Upload failed: ' + response.error);
717
+ }
718
+ } else {
719
+ throw new Error(`HTTP error! status: ${xhr.status}`);
720
+ }
721
+ };
722
 
723
+ xhr.onerror = function() {
724
+ throw new Error('Network error occurred');
725
+ };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
726
 
727
+ xhr.send(formData);
728
+
729
+ await new Promise((resolve, reject) => {
730
+ xhr.onloadend = resolve;
731
+ xhr.onerror = reject;
732
+ });
733
 
734
+ break;
735
+ } catch (error) {
736
+ console.error('Upload error:', error);
737
+ await new Promise(resolve => setTimeout(resolve, 1000));
738
+ }
739
+ }
740
  }
741
 
742
  function createProgressBar(fileName) {
 
755
  return container;
756
  }
757
 
758
+ function updateProgress(event, progressBar) {
759
+ if (event.lengthComputable) {
760
+ const percentComplete = (event.loaded / event.total) * 100;
761
+ progressBar.style.width = percentComplete + '%';
762
+ }
763
  }
764
 
765
  function resetUploadState() {
 
889
  historyModal.style.display = "block";
890
  }
891
 
892
+ function quickOpen(url, fileName, originalExtension) {
893
  quickOpenContent.innerHTML = '';
894
  const fullUrl = window.location.origin + url;
895
 
 
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']
954
 
955
+ if original_extension.lower() in supported_types:
956
  temp_filename = file.filename
957
  content_type = file.content_type
958
  else:
 
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": "FAILED GOD MAN AFTER alot of attempts"}, status_code=500)
970
 
971
  original_url = upload_result['serving_url']
972
  mirrored_url = f"/upload/{original_url.split('/pbxt/')[1]}"
973
 
974
+ if original_extension.lower() not in supported_types:
 
975
  mirrored_url = mirrored_url.replace('.png', '')
976
 
977
  return JSONResponse(content={"url": mirrored_url, "originalExtension": original_extension})
978
 
 
979
  @app.get("/upload/{path:path}")
980
  async def handle_file_stream(path: str, request: Request):
981
  original_url = f'https://replicate.delivery/pbxt/{path}'
982
 
983
+ if not path.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.mp4', '.mp3', '.pdf', '.txt')):
 
984
  original_url += '.png'
985
 
986
  range_header = request.headers.get('Range')
987
  headers = {'Range': range_header} if range_header else {}
988
+ response = requests.get(original_url, headers=headers, stream=True)
 
 
 
 
 
 
 
989
 
990
+ def generate():
991
+ for chunk in response.iter_content(chunk_size=8192):
992
+ yield chunk
993
 
994
+ headers = dict(response.headers)
995
+ headers['Access-Control-Allow-Origin'] = '*'
996
+ headers['Content-Disposition'] = 'inline'
997
 
998
+ if response.status_code == 206:
999
+ headers['Content-Range'] = response.headers.get('Content-Range')
 
 
 
1000
 
1001
+ original_extension = os.path.splitext(path)[1][1:]
1002
+ content_type, _ = mimetypes.guess_type(f"file.{original_extension}")
1003
+ if content_type:
1004
+ headers['Content-Type'] = content_type
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):
 
1010
  html = f'''
1011
  <html>
1012
  <head>
 
1024
  <meta property="og:image:type" content="image/png">
1025
  <style>
1026
  body, html {{ margin: 0; padding: 0; height: 100%; background: #000; }}
1027
+ #thumbnail {{ width: 100%; height: 100%; object-fit: contain; cursor: pointer; }}
1028
+ #video {{ display: none; width: 100%; height: 100%; object-fit: contain; }}
1029
  </style>
1030
  </head>
1031
  <body>
1032
+ <img id="thumbnail" src="{thumbnail}" onclick="playVideo()">
1033
+ <video id="video" controls autoplay>
1034
  <source src="{url}" type="video/mp4">
1035
  Your browser does not support the video tag.
1036
  </video>
1037
+ <script>
1038
+ function playVideo() {{
1039
+ document.getElementById('thumbnail').style.display = 'none';
1040
+ document.getElementById('video').style.display = 'block';
1041
+ document.getElementById('video').play();
1042
+ }}
1043
+ </script>
1044
  </body>
1045
  </html>
1046
  '''
1047
  return HTMLResponse(content=html)
1048
 
 
1049
  async def get_cookies() -> Dict[str, str]:
1050
  try:
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 Exception as e:
1056
+ print(f'Error fetching the page: {e}')
1057
  return {}
1058
 
 
1059
  async def initiate_upload(cookies: Dict[str, str], filename: str, content_type: str) -> Dict:
1060
  url = f'https://replicate.com/api/upload/{filename}?content_type={content_type}'
 
 
 
 
 
 
 
 
 
 
 
 
1061
  try:
1062
+ response = requests.post(url, cookies=cookies, headers={
1063
+ 'X-CSRFToken': cookies.get('csrftoken'),
1064
+ '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',
1065
+ 'Referer': 'https://replicate.com/levelsio/neon-tokyo',
1066
+ 'Origin': 'https://replicate.com',
1067
+ 'Accept': '*/*',
1068
+ 'Accept-Language': 'en-US,en;q=0.5',
1069
+ 'Accept-Encoding': 'identity',
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 Exception as e:
1078
+ print(f'Error initiating upload: {e}')
1079
+ raise
 
1080
 
1081
+ async def upload_file(upload_url: str, file_content: bytes, content_type: str) -> bool:
1082
  try:
1083
  response = requests.put(upload_url, data=file_content, headers={'Content-Type': content_type})
 
1084
  return response.status_code == 200
1085
+ except Exception as e:
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
+ while True:
1091
+ try:
1092
+ success = await upload_file(upload_url, file_content, content_type)
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