coollsd commited on
Commit
b3a70f2
·
verified ·
1 Parent(s): 85aea4b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +89 -58
app.py CHANGED
@@ -474,48 +474,47 @@ HTML_CONTENT = """
474
  const progressBar = createProgressBar(file.name);
475
  progressContainer.appendChild(progressBar);
476
 
477
- const formData = new FormData();
478
- formData.append('file', file);
 
479
 
480
- while (true) {
481
- try {
482
- const xhr = new XMLHttpRequest();
483
- xhr.open('POST', '/upload', true);
484
- xhr.upload.onprogress = (event) => updateProgress(event, progressBar.querySelector('.progress'));
485
-
486
- xhr.onload = function() {
487
- if (xhr.status === 200) {
488
- const response = JSON.parse(xhr.responseText);
489
- if (response.url) {
490
- addResultLink(response.url, file.name);
491
- resetUploadState();
492
- return;
493
- } else {
494
- throw new Error('Upload failed: ' + response.error);
495
- }
496
- } else {
497
- throw new Error(`HTTP error! status: ${xhr.status}`);
498
- }
499
- };
500
 
501
- xhr.onerror = function() {
502
- throw new Error('Network error occurred');
503
- };
 
504
 
505
- xhr.send(formData);
506
-
507
- // Wait for the request to complete
508
- await new Promise((resolve, reject) => {
509
- xhr.onloadend = resolve;
510
- xhr.onerror = reject;
511
  });
512
 
513
- break; // Success, exit the loop
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
514
  } catch (error) {
515
  console.error('Upload error:', error);
516
- // Wait for a short time before retrying
517
  await new Promise(resolve => setTimeout(resolve, 1000));
518
- // The loop will continue, retrying the upload
519
  }
520
  }
521
  }
@@ -536,11 +535,8 @@ HTML_CONTENT = """
536
  return container;
537
  }
538
 
539
- function updateProgress(event, progressBar) {
540
- if (event.lengthComputable) {
541
- const percentComplete = (event.loaded / event.total) * 100;
542
- progressBar.style.width = percentComplete + '%';
543
- }
544
  }
545
 
546
  function resetUploadState() {
@@ -613,7 +609,7 @@ async def index():
613
  return HTML_CONTENT
614
 
615
  @app.post("/upload")
616
- async def handle_upload(file: UploadFile = File(...)):
617
  if not file.filename:
618
  return JSONResponse(content={"error": "No file selected."}, status_code=400)
619
 
@@ -621,19 +617,26 @@ async def handle_upload(file: UploadFile = File(...)):
621
  if 'csrftoken' not in cookies or 'sessionid' not in cookies:
622
  return JSONResponse(content={"error": "Failed to obtain necessary cookies"}, status_code=500)
623
 
624
- upload_result = await initiate_upload(cookies, file.filename, file.content_type)
625
- if not upload_result or 'upload_url' not in upload_result:
626
- return JSONResponse(content={"error": "Failed to initiate upload"}, status_code=500)
 
 
 
 
 
627
 
628
  file_content = await file.read()
629
- upload_success = await retry_upload(upload_result['upload_url'], file_content, file.content_type)
630
  if not upload_success:
631
  return JSONResponse(content={"error": "File upload failed after multiple attempts"}, status_code=500)
632
 
633
- original_url = upload_result['serving_url']
634
- mirrored_url = f"/rbxg/{original_url.split('/pbxt/')[1]}"
635
-
636
- return JSONResponse(content={"url": mirrored_url})
 
 
637
 
638
  @app.get("/rbxg/{path:path}")
639
  async def handle_video_stream(path: str, request: Request):
@@ -729,25 +732,53 @@ async def initiate_upload(cookies: Dict[str, str], filename: str, content_type:
729
  print(f'Error initiating upload: {e}')
730
  raise
731
 
732
- async def upload_file(upload_url: str, file_content: bytes, content_type: str) -> bool:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
733
  try:
734
- response = requests.put(upload_url, data=file_content, headers={'Content-Type': content_type})
735
- return response.status_code == 200
736
  except Exception as e:
737
  print(f'Error uploading file: {e}')
738
  return False
739
 
740
- async def retry_upload(upload_url: str, file_content: bytes, content_type: str, max_retries: int = 5, delay: int = 1) -> bool:
741
- while True:
742
  try:
743
- success = await upload_file(upload_url, file_content, content_type)
744
  if success:
745
  return True
746
- print("Upload failed. Retrying...")
747
  except Exception as e:
748
- print(f"Error during upload: {e}")
749
 
750
- await asyncio.sleep(delay)
751
- delay = min(delay * 2, 60) # Exponential backoff, capped at 60 seconds
 
752
 
 
753
  return False
 
474
  const progressBar = createProgressBar(file.name);
475
  progressContainer.appendChild(progressBar);
476
 
477
+ const chunkSize = 1024 * 1024; // 1MB chunks
478
+ const totalChunks = Math.ceil(file.size / chunkSize);
479
+ let uploadedChunks = 0;
480
 
481
+ while (uploadedChunks < totalChunks) {
482
+ const start = uploadedChunks * chunkSize;
483
+ const end = Math.min(start + chunkSize, file.size);
484
+ const chunk = file.slice(start, end);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
485
 
486
+ const formData = new FormData();
487
+ formData.append('file', chunk, file.name);
488
+ formData.append('chunk', uploadedChunks.toString());
489
+ formData.append('totalChunks', totalChunks.toString());
490
 
491
+ try {
492
+ const response = await fetch('/upload', {
493
+ method: 'POST',
494
+ body: formData
 
 
495
  });
496
 
497
+ if (!response.ok) {
498
+ throw new Error(`HTTP error! status: ${response.status}`);
499
+ }
500
+
501
+ const result = await response.json();
502
+ if (result.success) {
503
+ uploadedChunks++;
504
+ updateProgress(progressBar.querySelector('.progress'), (uploadedChunks / totalChunks) * 100);
505
+
506
+ if (uploadedChunks === totalChunks) {
507
+ addResultLink(result.url, file.name);
508
+ resetUploadState();
509
+ break;
510
+ }
511
+ } else {
512
+ throw new Error(result.error || 'Upload failed');
513
+ }
514
  } catch (error) {
515
  console.error('Upload error:', error);
 
516
  await new Promise(resolve => setTimeout(resolve, 1000));
517
+ // The loop will continue, retrying the current chunk
518
  }
519
  }
520
  }
 
535
  return container;
536
  }
537
 
538
+ function updateProgress(progressBar, percentage) {
539
+ progressBar.style.width = percentage + '%';
 
 
 
540
  }
541
 
542
  function resetUploadState() {
 
609
  return HTML_CONTENT
610
 
611
  @app.post("/upload")
612
+ async def handle_upload(file: UploadFile = File(...), chunk: int = 0, totalChunks: int = 1):
613
  if not file.filename:
614
  return JSONResponse(content={"error": "No file selected."}, status_code=400)
615
 
 
617
  if 'csrftoken' not in cookies or 'sessionid' not in cookies:
618
  return JSONResponse(content={"error": "Failed to obtain necessary cookies"}, status_code=500)
619
 
620
+ if chunk == 0:
621
+ upload_result = await initiate_upload(cookies, file.filename, file.content_type)
622
+ if not upload_result or 'upload_url' not in upload_result:
623
+ return JSONResponse(content={"error": "Failed to initiate upload"}, status_code=500)
624
+ else:
625
+ upload_result = await get_upload_status(cookies, file.filename)
626
+ if not upload_result or 'upload_url' not in upload_result:
627
+ return JSONResponse(content={"error": "Failed to get upload status"}, status_code=500)
628
 
629
  file_content = await file.read()
630
+ upload_success = await retry_upload(upload_result['upload_url'], file_content, file.content_type, chunk, totalChunks)
631
  if not upload_success:
632
  return JSONResponse(content={"error": "File upload failed after multiple attempts"}, status_code=500)
633
 
634
+ if chunk == totalChunks - 1:
635
+ original_url = upload_result['serving_url']
636
+ mirrored_url = f"/rbxg/{original_url.split('/pbxt/')[1]}"
637
+ return JSONResponse(content={"success": True, "url": mirrored_url})
638
+ else:
639
+ return JSONResponse(content={"success": True})
640
 
641
  @app.get("/rbxg/{path:path}")
642
  async def handle_video_stream(path: str, request: Request):
 
732
  print(f'Error initiating upload: {e}')
733
  raise
734
 
735
+ async def get_upload_status(cookies: Dict[str, str], filename: str) -> Dict:
736
+ url = f'https://replicate.com/api/upload/{filename}'
737
+ try:
738
+ response = requests.get(url, cookies=cookies, headers={
739
+ 'X-CSRFToken': cookies.get('csrftoken'),
740
+ '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',
741
+ 'Referer': 'https://replicate.com/levelsio/neon-tokyo',
742
+ 'Origin': 'https://replicate.com',
743
+ 'Accept': '*/*',
744
+ 'Accept-Language': 'en-US,en;q=0.5',
745
+ 'Accept-Encoding': 'identity',
746
+ 'Sec-Fetch-Dest': 'empty',
747
+ 'Sec-Fetch-Mode': 'cors',
748
+ 'Sec-Fetch-Site': 'same-origin',
749
+ 'Sec-GPC': '1',
750
+ 'Priority': 'u=1, i'
751
+ })
752
+ return response.json()
753
+ except Exception as e:
754
+ print(f'Error getting upload status: {e}')
755
+ raise
756
+
757
+ async def upload_file(upload_url: str, file_content: bytes, content_type: str, chunk: int, totalChunks: int) -> bool:
758
+ headers = {
759
+ 'Content-Type': content_type,
760
+ 'Content-Range': f'bytes {chunk*len(file_content)}-{(chunk+1)*len(file_content)-1}/{totalChunks*len(file_content)}'
761
+ }
762
  try:
763
+ response = requests.put(upload_url, data=file_content, headers=headers)
764
+ return response.status_code in [200, 201, 204]
765
  except Exception as e:
766
  print(f'Error uploading file: {e}')
767
  return False
768
 
769
+ async def retry_upload(upload_url: str, file_content: bytes, content_type: str, chunk: int, totalChunks: int, max_retries: int = 5, delay: int = 1) -> bool:
770
+ for attempt in range(max_retries):
771
  try:
772
+ success = await upload_file(upload_url, file_content, content_type, chunk, totalChunks)
773
  if success:
774
  return True
775
+ print(f"Upload attempt {attempt + 1} failed. Retrying...")
776
  except Exception as e:
777
+ print(f"Error during upload attempt {attempt + 1}: {e}")
778
 
779
+ if attempt < max_retries - 1:
780
+ await asyncio.sleep(delay)
781
+ delay *= 2 # Exponential backoff
782
 
783
+ print("Upload failed after all retry attempts")
784
  return False