Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
|
@@ -6,7 +6,6 @@ import asyncio
|
|
| 6 |
from typing import Dict
|
| 7 |
import os
|
| 8 |
import mimetypes
|
| 9 |
-
import uuid
|
| 10 |
|
| 11 |
app = FastAPI()
|
| 12 |
|
|
@@ -426,7 +425,7 @@ HTML_CONTENT = """
|
|
| 426 |
gap: 5px;
|
| 427 |
}
|
| 428 |
|
| 429 |
-
|
| 430 |
display: none;
|
| 431 |
position: fixed;
|
| 432 |
z-index: 4;
|
|
@@ -446,7 +445,7 @@ HTML_CONTENT = """
|
|
| 446 |
text-align: center;
|
| 447 |
}
|
| 448 |
|
| 449 |
-
|
| 450 |
.quick-open-content video,
|
| 451 |
.quick-open-content audio {
|
| 452 |
max-width: 100%;
|
|
@@ -538,12 +537,12 @@ HTML_CONTENT = """
|
|
| 538 |
<h1>Radd PRO Uploader</h1>
|
| 539 |
<form id="uploadForm">
|
| 540 |
<div id="dropZone" class="drop-zone">
|
| 541 |
-
<input type="file" name="file" id="file" class="file-input" accept="*" required
|
| 542 |
-
<label for="file" class="btn">Choose
|
| 543 |
-
<p>or drag and drop
|
| 544 |
</div>
|
| 545 |
<div class="file-name" id="fileName"></div>
|
| 546 |
-
<button type="submit" id="uploadBtn" class="btn" style="display: none; margin-top: 1rem;">Upload
|
| 547 |
<div class="progress-container" id="progressContainer"></div>
|
| 548 |
<div class="loading-spinner" id="loadingSpinner"></div>
|
| 549 |
</form>
|
|
@@ -603,15 +602,12 @@ HTML_CONTENT = """
|
|
| 603 |
const historyList = document.getElementById('historyList');
|
| 604 |
const quickOpenContent = document.getElementById('quickOpenContent');
|
| 605 |
|
| 606 |
-
let pastedFiles = [];
|
| 607 |
-
|
| 608 |
fileInput.addEventListener('change', handleFileSelect);
|
| 609 |
|
| 610 |
uploadForm.addEventListener('submit', (e) => {
|
| 611 |
e.preventDefault();
|
| 612 |
-
|
| 613 |
-
|
| 614 |
-
uploadFiles(filesToUpload);
|
| 615 |
}
|
| 616 |
});
|
| 617 |
|
|
@@ -635,22 +631,12 @@ HTML_CONTENT = """
|
|
| 635 |
for (let i = 0; i < items.length; i++) {
|
| 636 |
if (items[i].kind === 'file') {
|
| 637 |
const file = items[i].getAsFile();
|
| 638 |
-
|
| 639 |
-
|
| 640 |
-
pastedFiles.push(renamedFile);
|
| 641 |
}
|
| 642 |
}
|
| 643 |
-
if (pastedFiles.length > 0) {
|
| 644 |
-
updateFileNameDisplay();
|
| 645 |
-
uploadBtn.style.display = 'inline-block';
|
| 646 |
-
}
|
| 647 |
});
|
| 648 |
|
| 649 |
-
function updateFileNameDisplay() {
|
| 650 |
-
const fileNames = pastedFiles.map(file => file.name).join(', ');
|
| 651 |
-
fileName.textContent = fileNames;
|
| 652 |
-
}
|
| 653 |
-
|
| 654 |
span[0].onclick = function() {
|
| 655 |
modal.style.display = "none";
|
| 656 |
}
|
|
@@ -688,14 +674,17 @@ HTML_CONTENT = """
|
|
| 688 |
|
| 689 |
function handleFileSelect(e) {
|
| 690 |
if (e.target.files && e.target.files.length > 0) {
|
| 691 |
-
const
|
| 692 |
-
fileName.textContent =
|
| 693 |
uploadBtn.style.display = 'inline-block';
|
| 694 |
-
|
|
|
|
|
|
|
|
|
|
| 695 |
}
|
| 696 |
}
|
| 697 |
|
| 698 |
-
async function
|
| 699 |
progressContainer.innerHTML = '';
|
| 700 |
progressContainer.style.display = 'block';
|
| 701 |
loadingSpinner.style.display = 'block';
|
|
@@ -703,37 +692,51 @@ HTML_CONTENT = """
|
|
| 703 |
resultContainer.innerHTML = '';
|
| 704 |
resultContainer.style.display = 'none';
|
| 705 |
|
| 706 |
-
|
| 707 |
-
|
| 708 |
-
progressContainer.appendChild(progressBar);
|
| 709 |
|
| 710 |
-
|
| 711 |
-
|
| 712 |
|
|
|
|
| 713 |
try {
|
| 714 |
-
const
|
| 715 |
-
|
| 716 |
-
|
| 717 |
-
|
| 718 |
-
|
| 719 |
-
|
| 720 |
-
|
| 721 |
-
|
| 722 |
-
|
| 723 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 724 |
} else {
|
| 725 |
-
throw new Error(
|
| 726 |
}
|
| 727 |
-
}
|
| 728 |
-
|
| 729 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 730 |
} catch (error) {
|
| 731 |
console.error('Upload error:', error);
|
| 732 |
-
|
| 733 |
}
|
| 734 |
}
|
| 735 |
-
|
| 736 |
-
resetUploadState();
|
| 737 |
}
|
| 738 |
|
| 739 |
function createProgressBar(fileName) {
|
|
@@ -752,13 +755,19 @@ HTML_CONTENT = """
|
|
| 752 |
return container;
|
| 753 |
}
|
| 754 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 755 |
function resetUploadState() {
|
| 756 |
fileInput.value = '';
|
| 757 |
fileName.textContent = '';
|
| 758 |
uploadBtn.style.display = 'none';
|
| 759 |
uploadBtn.disabled = false;
|
| 760 |
loadingSpinner.style.display = 'none';
|
| 761 |
-
pastedFiles = [];
|
| 762 |
}
|
| 763 |
|
| 764 |
function addResultLink(url, fileName, originalExtension) {
|
|
@@ -863,7 +872,7 @@ HTML_CONTENT = """
|
|
| 863 |
};
|
| 864 |
actionsContainer.appendChild(openBtn);
|
| 865 |
|
| 866 |
-
|
| 867 |
const embedBtn = document.createElement('button');
|
| 868 |
embedBtn.textContent = 'Embed';
|
| 869 |
embedBtn.className = 'small-btn';
|
|
@@ -880,7 +889,7 @@ HTML_CONTENT = """
|
|
| 880 |
historyModal.style.display = "block";
|
| 881 |
}
|
| 882 |
|
| 883 |
-
|
| 884 |
quickOpenContent.innerHTML = '';
|
| 885 |
const fullUrl = window.location.origin + url;
|
| 886 |
|
|
@@ -920,7 +929,7 @@ HTML_CONTENT = """
|
|
| 920 |
quickOpenContent.appendChild(link);
|
| 921 |
}
|
| 922 |
|
| 923 |
-
|
| 924 |
}
|
| 925 |
</script>
|
| 926 |
</body>
|
|
@@ -938,7 +947,7 @@ async def handle_upload(file: UploadFile = File(...)):
|
|
| 938 |
|
| 939 |
cookies = await get_cookies()
|
| 940 |
if 'csrftoken' not in cookies or 'sessionid' not in cookies:
|
| 941 |
-
return JSONResponse(content={"error": "Failed
|
| 942 |
|
| 943 |
original_extension = os.path.splitext(file.filename)[1][1:]
|
| 944 |
supported_types = ['mp4', 'png', 'jpg', 'jpeg', 'gif', 'mp3', 'pdf', 'txt']
|
|
@@ -952,12 +961,12 @@ async def handle_upload(file: UploadFile = File(...)):
|
|
| 952 |
|
| 953 |
upload_result = await initiate_upload(cookies, temp_filename, content_type)
|
| 954 |
if not upload_result or 'upload_url' not in upload_result:
|
| 955 |
-
return JSONResponse(content={"error": "Failed to
|
| 956 |
|
| 957 |
file_content = await file.read()
|
| 958 |
upload_success = await retry_upload(upload_result['upload_url'], file_content, content_type)
|
| 959 |
if not upload_success:
|
| 960 |
-
return JSONResponse(content={"error": "
|
| 961 |
|
| 962 |
original_url = upload_result['serving_url']
|
| 963 |
mirrored_url = f"/rbxg/{original_url.split('/pbxt/')[1]}"
|
|
@@ -1078,7 +1087,7 @@ async def upload_file(upload_url: str, file_content: bytes, content_type: str) -
|
|
| 1078 |
return False
|
| 1079 |
|
| 1080 |
async def retry_upload(upload_url: str, file_content: bytes, content_type: str, max_retries: int = 5, delay: int = 1) -> bool:
|
| 1081 |
-
|
| 1082 |
try:
|
| 1083 |
success = await upload_file(upload_url, file_content, content_type)
|
| 1084 |
if success:
|
|
@@ -1090,4 +1099,4 @@ async def retry_upload(upload_url: str, file_content: bytes, content_type: str,
|
|
| 1090 |
await asyncio.sleep(delay)
|
| 1091 |
delay = min(delay * 2, 60)
|
| 1092 |
|
| 1093 |
-
return False
|
|
|
|
| 6 |
from typing import Dict
|
| 7 |
import os
|
| 8 |
import mimetypes
|
|
|
|
| 9 |
|
| 10 |
app = FastAPI()
|
| 11 |
|
|
|
|
| 425 |
gap: 5px;
|
| 426 |
}
|
| 427 |
|
| 428 |
+
.quick-open-modal {
|
| 429 |
display: none;
|
| 430 |
position: fixed;
|
| 431 |
z-index: 4;
|
|
|
|
| 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%;
|
|
|
|
| 537 |
<h1>Radd PRO Uploader</h1>
|
| 538 |
<form id="uploadForm">
|
| 539 |
<div id="dropZone" class="drop-zone">
|
| 540 |
+
<input type="file" name="file" id="file" class="file-input" accept="*" required>
|
| 541 |
+
<label for="file" class="btn">Choose File</label>
|
| 542 |
+
<p>or drag and drop file here/paste image</p>
|
| 543 |
</div>
|
| 544 |
<div class="file-name" id="fileName"></div>
|
| 545 |
+
<button type="submit" id="uploadBtn" class="btn" style="display: none; margin-top: 1rem;">Upload File</button>
|
| 546 |
<div class="progress-container" id="progressContainer"></div>
|
| 547 |
<div class="loading-spinner" id="loadingSpinner"></div>
|
| 548 |
</form>
|
|
|
|
| 602 |
const historyList = document.getElementById('historyList');
|
| 603 |
const quickOpenContent = document.getElementById('quickOpenContent');
|
| 604 |
|
|
|
|
|
|
|
| 605 |
fileInput.addEventListener('change', handleFileSelect);
|
| 606 |
|
| 607 |
uploadForm.addEventListener('submit', (e) => {
|
| 608 |
e.preventDefault();
|
| 609 |
+
if (fileInput.files.length > 0) {
|
| 610 |
+
uploadFile(fileInput.files[0]);
|
|
|
|
| 611 |
}
|
| 612 |
});
|
| 613 |
|
|
|
|
| 631 |
for (let i = 0; i < items.length; i++) {
|
| 632 |
if (items[i].kind === 'file') {
|
| 633 |
const file = items[i].getAsFile();
|
| 634 |
+
handleFileSelect({ target: { files: [file] } });
|
| 635 |
+
break;
|
|
|
|
| 636 |
}
|
| 637 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 638 |
});
|
| 639 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 640 |
span[0].onclick = function() {
|
| 641 |
modal.style.display = "none";
|
| 642 |
}
|
|
|
|
| 674 |
|
| 675 |
function handleFileSelect(e) {
|
| 676 |
if (e.target.files && e.target.files.length > 0) {
|
| 677 |
+
const file = e.target.files[0];
|
| 678 |
+
fileName.textContent = file.name;
|
| 679 |
uploadBtn.style.display = 'inline-block';
|
| 680 |
+
|
| 681 |
+
const dataTransfer = new DataTransfer();
|
| 682 |
+
dataTransfer.items.add(file);
|
| 683 |
+
fileInput.files = dataTransfer.files;
|
| 684 |
}
|
| 685 |
}
|
| 686 |
|
| 687 |
+
async function uploadFile(file) {
|
| 688 |
progressContainer.innerHTML = '';
|
| 689 |
progressContainer.style.display = 'block';
|
| 690 |
loadingSpinner.style.display = 'block';
|
|
|
|
| 692 |
resultContainer.innerHTML = '';
|
| 693 |
resultContainer.style.display = 'none';
|
| 694 |
|
| 695 |
+
const progressBar = createProgressBar(file.name);
|
| 696 |
+
progressContainer.appendChild(progressBar);
|
|
|
|
| 697 |
|
| 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() {
|
| 766 |
fileInput.value = '';
|
| 767 |
fileName.textContent = '';
|
| 768 |
uploadBtn.style.display = 'none';
|
| 769 |
uploadBtn.disabled = false;
|
| 770 |
loadingSpinner.style.display = 'none';
|
|
|
|
| 771 |
}
|
| 772 |
|
| 773 |
function addResultLink(url, fileName, originalExtension) {
|
|
|
|
| 872 |
};
|
| 873 |
actionsContainer.appendChild(openBtn);
|
| 874 |
|
| 875 |
+
if (item.originalExtension.toLowerCase() === 'mp4') {
|
| 876 |
const embedBtn = document.createElement('button');
|
| 877 |
embedBtn.textContent = 'Embed';
|
| 878 |
embedBtn.className = 'small-btn';
|
|
|
|
| 889 |
historyModal.style.display = "block";
|
| 890 |
}
|
| 891 |
|
| 892 |
+
function quickOpen(url, fileName, originalExtension) {
|
| 893 |
quickOpenContent.innerHTML = '';
|
| 894 |
const fullUrl = window.location.origin + url;
|
| 895 |
|
|
|
|
| 929 |
quickOpenContent.appendChild(link);
|
| 930 |
}
|
| 931 |
|
| 932 |
+
quickOpenModal.style.display = "block";
|
| 933 |
}
|
| 934 |
</script>
|
| 935 |
</body>
|
|
|
|
| 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 |
|
| 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"/rbxg/{original_url.split('/pbxt/')[1]}"
|
|
|
|
| 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:
|
|
|
|
| 1099 |
await asyncio.sleep(delay)
|
| 1100 |
delay = min(delay * 2, 60)
|
| 1101 |
|
| 1102 |
+
return False
|