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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +96 -90
app.py CHANGED
@@ -5,9 +5,11 @@ import asyncio
5
  from typing import Dict
6
  import os
7
  import mimetypes
 
8
 
9
  app = FastAPI()
10
 
 
11
  HTML_CONTENT = """
12
  <!DOCTYPE html>
13
  <html lang="en">
@@ -697,45 +699,46 @@ HTML_CONTENT = """
697
  const formData = new FormData();
698
  formData.append('file', file);
699
 
700
- while (true) {
701
- try {
702
- const xhr = new XMLHttpRequest();
703
- xhr.open('POST', '/upload', true);
704
- xhr.upload.onprogress = (event) => updateProgress(event, progressBar.querySelector('.progress'));
705
-
706
- xhr.onload = function() {
707
- if (xhr.status === 200) {
708
- const response = JSON.parse(xhr.responseText);
709
- if (response.url) {
710
- addResultLink(response.url, file.name, response.originalExtension);
711
- saveToHistory(file.name, response.url, response.originalExtension);
712
- resetUploadState();
713
- return;
714
- } else {
715
- throw new Error('Upload failed: ' + response.error);
716
- }
717
- } else {
718
- throw new Error(`HTTP error! status: ${xhr.status}`);
719
- }
720
- };
721
-
722
- xhr.onerror = function() {
723
- throw new Error('Network error occurred');
724
- };
725
 
726
- xhr.send(formData);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
727
 
728
- await new Promise((resolve, reject) => {
729
- xhr.onloadend = resolve;
730
- xhr.onerror = reject;
731
- });
 
732
 
733
- break;
734
- } catch (error) {
735
- console.error('Upload error:', error);
736
- await new Promise(resolve => setTimeout(resolve, 1000));
737
- }
738
- }
739
  }
740
 
741
  function createProgressBar(fileName) {
@@ -754,11 +757,8 @@ HTML_CONTENT = """
754
  return container;
755
  }
756
 
757
- function updateProgress(event, progressBar) {
758
- if (event.lengthComputable) {
759
- const percentComplete = (event.loaded / event.total) * 100;
760
- progressBar.style.width = percentComplete + '%';
761
- }
762
  }
763
 
764
  function resetUploadState() {
@@ -946,12 +946,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 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']
953
 
954
- if original_extension.lower() in supported_types:
955
  temp_filename = file.filename
956
  content_type = file.content_type
957
  else:
@@ -960,29 +960,32 @@ 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."}, 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]}"
975
 
976
- if original_extension.lower() not in supported_types:
 
977
  mirrored_url = mirrored_url.replace('.png', '')
978
 
979
  return JSONResponse(content={"url": mirrored_url, "originalExtension": original_extension})
980
 
 
981
  @app.get("/upload/{path:path}")
982
  async def handle_file_stream(path: str, request: Request):
983
  original_url = f'https://replicate.delivery/pbxt/{path}'
984
 
985
- if not path.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.mp4', '.mp3', '.pdf', '.txt')):
 
986
  original_url += '.png'
987
 
988
  range_header = request.headers.get('Range')
@@ -1003,6 +1006,7 @@ async def handle_file_stream(path: str, request: Request):
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:
@@ -1014,7 +1018,8 @@ async def handle_file_stream(path: str, request: Request):
1014
 
1015
 
1016
  @app.get("/embed")
1017
- async def embed_video(url: str, thumbnail: str):
 
1018
  html = f'''
1019
  <html>
1020
  <head>
@@ -1032,80 +1037,81 @@ async def embed_video(url: str, thumbnail: str):
1032
  <meta property="og:image:type" content="image/png">
1033
  <style>
1034
  body, html {{ margin: 0; padding: 0; height: 100%; background: #000; }}
1035
- #thumbnail {{ width: 100%; height: 100%; object-fit: contain; cursor: pointer; }}
1036
- #video {{ display: none; width: 100%; height: 100%; object-fit: contain; }}
1037
  </style>
1038
  </head>
1039
  <body>
1040
- <img id="thumbnail" src="{thumbnail}" onclick="playVideo()">
1041
- <video id="video" controls autoplay>
1042
  <source src="{url}" type="video/mp4">
1043
  Your browser does not support the video tag.
1044
  </video>
1045
- <script>
1046
- function playVideo() {{
1047
- document.getElementById('thumbnail').style.display = 'none';
1048
- document.getElementById('video').style.display = 'block';
1049
- document.getElementById('video').play();
1050
- }}
1051
- </script>
1052
  </body>
1053
  </html>
1054
  '''
1055
  return HTMLResponse(content=html)
1056
 
 
1057
  async def get_cookies() -> Dict[str, str]:
1058
  try:
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
 
 
1068
  async def initiate_upload(cookies: Dict[str, str], filename: str, content_type: str) -> Dict:
1069
  url = f'https://replicate.com/api/upload/{filename}?content_type={content_type}'
 
 
 
 
 
 
 
 
 
 
 
 
1070
  try:
1071
- response = requests.post(url, cookies=cookies, headers={
1072
- 'X-CSRFToken': cookies.get('csrftoken'),
1073
- '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',
1074
- 'Referer': 'https://replicate.com/levelsio/neon-tokyo',
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
 
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">
 
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
  return container;
758
  }
759
 
760
+ function updateProgress(progressBar, percent) {
761
+ progressBar.style.width = percent + '%';
 
 
 
762
  }
763
 
764
  function resetUploadState() {
 
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
 
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')
 
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:
 
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
  <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