Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -4,6 +4,7 @@ import requests
|
|
4 |
import time
|
5 |
import asyncio
|
6 |
from typing import Dict
|
|
|
7 |
|
8 |
app = FastAPI()
|
9 |
|
@@ -435,7 +436,7 @@ HTML_CONTENT = """
|
|
435 |
overflow: auto;
|
436 |
}
|
437 |
|
438 |
-
|
439 |
margin: 5% auto;
|
440 |
padding: 20px;
|
441 |
width: 90%;
|
@@ -535,7 +536,7 @@ HTML_CONTENT = """
|
|
535 |
<h1>Radd PRO Uploader</h1>
|
536 |
<form id="uploadForm">
|
537 |
<div id="dropZone" class="drop-zone">
|
538 |
-
<input type="file" name="file" id="file" class="file-input" accept="
|
539 |
<label for="file" class="btn">Choose File</label>
|
540 |
<p>or drag and drop file here/paste image</p>
|
541 |
</div>
|
@@ -546,7 +547,7 @@ HTML_CONTENT = """
|
|
546 |
</form>
|
547 |
<div class="result-container" id="resultContainer"></div>
|
548 |
<div class="file-types">
|
549 |
-
|
550 |
</div>
|
551 |
<div class="history-btn-container">
|
552 |
<button id="historyBtn" class="history-btn">View Upload History</button>
|
@@ -706,8 +707,8 @@ HTML_CONTENT = """
|
|
706 |
if (xhr.status === 200) {
|
707 |
const response = JSON.parse(xhr.responseText);
|
708 |
if (response.url) {
|
709 |
-
addResultLink(response.url, file.name);
|
710 |
-
saveToHistory(file.name, response.url);
|
711 |
resetUploadState();
|
712 |
return;
|
713 |
} else {
|
@@ -768,7 +769,7 @@ HTML_CONTENT = """
|
|
768 |
loadingSpinner.style.display = 'none';
|
769 |
}
|
770 |
|
771 |
-
function addResultLink(url, fileName) {
|
772 |
const linkContainer = document.createElement('div');
|
773 |
linkContainer.style.marginBottom = '10px';
|
774 |
|
@@ -777,6 +778,7 @@ HTML_CONTENT = """
|
|
777 |
link.textContent = `View ${fileName}`;
|
778 |
link.className = 'result-link';
|
779 |
link.target = '_blank';
|
|
|
780 |
|
781 |
linkContainer.appendChild(link);
|
782 |
|
@@ -793,7 +795,7 @@ HTML_CONTENT = """
|
|
793 |
};
|
794 |
buttonsContainer.appendChild(copyBtn);
|
795 |
|
796 |
-
if (
|
797 |
const embedBtn = document.createElement('button');
|
798 |
embedBtn.textContent = 'Embed Video for Discord';
|
799 |
embedBtn.className = 'small-btn embed-btn';
|
@@ -821,9 +823,9 @@ HTML_CONTENT = """
|
|
821 |
alert('Embed link copied to clipboard!');
|
822 |
}
|
823 |
|
824 |
-
function saveToHistory(fileName, url) {
|
825 |
let history = JSON.parse(localStorage.getItem('uploadHistory')) || [];
|
826 |
-
history.unshift({ fileName, url, timestamp: new Date().toISOString() });
|
827 |
if (history.length > 500) history = history.slice(0, 500);
|
828 |
localStorage.setItem('uploadHistory', JSON.stringify(history));
|
829 |
}
|
@@ -853,7 +855,7 @@ HTML_CONTENT = """
|
|
853 |
};
|
854 |
actionsContainer.appendChild(copyBtn);
|
855 |
|
856 |
-
|
857 |
openBtn.textContent = 'Open';
|
858 |
openBtn.className = 'small-btn';
|
859 |
openBtn.onclick = () => {
|
@@ -865,11 +867,11 @@ HTML_CONTENT = """
|
|
865 |
quickOpenBtn.textContent = 'Quick Open';
|
866 |
quickOpenBtn.className = 'small-btn';
|
867 |
quickOpenBtn.onclick = () => {
|
868 |
-
quickOpen(item.url, item.fileName);
|
869 |
};
|
870 |
actionsContainer.appendChild(quickOpenBtn);
|
871 |
|
872 |
-
|
873 |
const embedBtn = document.createElement('button');
|
874 |
embedBtn.textContent = 'Embed';
|
875 |
embedBtn.className = 'small-btn';
|
@@ -886,30 +888,30 @@ HTML_CONTENT = """
|
|
886 |
historyModal.style.display = "block";
|
887 |
}
|
888 |
|
889 |
-
function quickOpen(url, fileName) {
|
890 |
quickOpenContent.innerHTML = '';
|
891 |
const fullUrl = window.location.origin + url;
|
892 |
|
893 |
-
if (
|
894 |
const img = document.createElement('img');
|
895 |
img.src = fullUrl;
|
896 |
img.alt = fileName;
|
897 |
quickOpenContent.appendChild(img);
|
898 |
-
} else if (
|
899 |
const video = document.createElement('video');
|
900 |
video.src = fullUrl;
|
901 |
video.controls = true;
|
902 |
quickOpenContent.appendChild(video);
|
903 |
-
} else if (
|
904 |
const audio = document.createElement('audio');
|
905 |
audio.src = fullUrl;
|
906 |
audio.controls = true;
|
907 |
quickOpenContent.appendChild(audio);
|
908 |
-
} else if (
|
909 |
const iframe = document.createElement('iframe');
|
910 |
iframe.src = fullUrl;
|
911 |
quickOpenContent.appendChild(iframe);
|
912 |
-
} else if (
|
913 |
fetch(fullUrl)
|
914 |
.then(response => response.text())
|
915 |
.then(text => {
|
@@ -922,6 +924,7 @@ HTML_CONTENT = """
|
|
922 |
link.href = fullUrl;
|
923 |
link.textContent = 'Download ' + fileName;
|
924 |
link.target = '_blank';
|
|
|
925 |
quickOpenContent.appendChild(link);
|
926 |
}
|
927 |
|
@@ -945,22 +948,25 @@ async def handle_upload(file: UploadFile = File(...)):
|
|
945 |
if 'csrftoken' not in cookies or 'sessionid' not in cookies:
|
946 |
return JSONResponse(content={"error": "Failed"}, status_code=500)
|
947 |
|
948 |
-
|
|
|
|
|
|
|
949 |
if not upload_result or 'upload_url' not in upload_result:
|
950 |
return JSONResponse(content={"error": "Failed to upload"}, status_code=500)
|
951 |
|
952 |
file_content = await file.read()
|
953 |
-
upload_success = await retry_upload(upload_result['upload_url'], file_content,
|
954 |
if not upload_success:
|
955 |
return JSONResponse(content={"error": "FAILED GOD MAN AFTER alot of attempts"}, status_code=500)
|
956 |
|
957 |
original_url = upload_result['serving_url']
|
958 |
mirrored_url = f"/rbxg/{original_url.split('/pbxt/')[1]}"
|
959 |
|
960 |
-
return JSONResponse(content={"url": mirrored_url})
|
961 |
|
962 |
@app.get("/rbxg/{path:path}")
|
963 |
-
async def
|
964 |
original_url = f'https://replicate.delivery/pbxt/{path}'
|
965 |
range_header = request.headers.get('Range')
|
966 |
|
@@ -1074,4 +1080,4 @@ async def retry_upload(upload_url: str, file_content: bytes, content_type: str,
|
|
1074 |
await asyncio.sleep(delay)
|
1075 |
delay = min(delay * 2, 60)
|
1076 |
|
1077 |
-
return False
|
|
|
4 |
import time
|
5 |
import asyncio
|
6 |
from typing import Dict
|
7 |
+
import os
|
8 |
|
9 |
app = FastAPI()
|
10 |
|
|
|
436 |
overflow: auto;
|
437 |
}
|
438 |
|
439 |
+
.quick-open-content {
|
440 |
margin: 5% auto;
|
441 |
padding: 20px;
|
442 |
width: 90%;
|
|
|
536 |
<h1>Radd PRO Uploader</h1>
|
537 |
<form id="uploadForm">
|
538 |
<div id="dropZone" class="drop-zone">
|
539 |
+
<input type="file" name="file" id="file" class="file-input" accept="*" required>
|
540 |
<label for="file" class="btn">Choose File</label>
|
541 |
<p>or drag and drop file here/paste image</p>
|
542 |
</div>
|
|
|
547 |
</form>
|
548 |
<div class="result-container" id="resultContainer"></div>
|
549 |
<div class="file-types">
|
550 |
+
All file types are supported
|
551 |
</div>
|
552 |
<div class="history-btn-container">
|
553 |
<button id="historyBtn" class="history-btn">View Upload History</button>
|
|
|
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 {
|
|
|
769 |
loadingSpinner.style.display = 'none';
|
770 |
}
|
771 |
|
772 |
+
function addResultLink(url, fileName, originalExtension) {
|
773 |
const linkContainer = document.createElement('div');
|
774 |
linkContainer.style.marginBottom = '10px';
|
775 |
|
|
|
778 |
link.textContent = `View ${fileName}`;
|
779 |
link.className = 'result-link';
|
780 |
link.target = '_blank';
|
781 |
+
link.download = `${fileName.split('.')[0]}.${originalExtension}`;
|
782 |
|
783 |
linkContainer.appendChild(link);
|
784 |
|
|
|
795 |
};
|
796 |
buttonsContainer.appendChild(copyBtn);
|
797 |
|
798 |
+
if (originalExtension.toLowerCase() === 'mp4') {
|
799 |
const embedBtn = document.createElement('button');
|
800 |
embedBtn.textContent = 'Embed Video for Discord';
|
801 |
embedBtn.className = 'small-btn embed-btn';
|
|
|
823 |
alert('Embed link copied to clipboard!');
|
824 |
}
|
825 |
|
826 |
+
function saveToHistory(fileName, url, originalExtension) {
|
827 |
let history = JSON.parse(localStorage.getItem('uploadHistory')) || [];
|
828 |
+
history.unshift({ fileName, url, originalExtension, timestamp: new Date().toISOString() });
|
829 |
if (history.length > 500) history = history.slice(0, 500);
|
830 |
localStorage.setItem('uploadHistory', JSON.stringify(history));
|
831 |
}
|
|
|
855 |
};
|
856 |
actionsContainer.appendChild(copyBtn);
|
857 |
|
858 |
+
const openBtn = document.createElement('button');
|
859 |
openBtn.textContent = 'Open';
|
860 |
openBtn.className = 'small-btn';
|
861 |
openBtn.onclick = () => {
|
|
|
867 |
quickOpenBtn.textContent = 'Quick Open';
|
868 |
quickOpenBtn.className = 'small-btn';
|
869 |
quickOpenBtn.onclick = () => {
|
870 |
+
quickOpen(item.url, item.fileName, item.originalExtension);
|
871 |
};
|
872 |
actionsContainer.appendChild(quickOpenBtn);
|
873 |
|
874 |
+
if (item.originalExtension.toLowerCase() === 'mp4') {
|
875 |
const embedBtn = document.createElement('button');
|
876 |
embedBtn.textContent = 'Embed';
|
877 |
embedBtn.className = 'small-btn';
|
|
|
888 |
historyModal.style.display = "block";
|
889 |
}
|
890 |
|
891 |
+
function quickOpen(url, fileName, originalExtension) {
|
892 |
quickOpenContent.innerHTML = '';
|
893 |
const fullUrl = window.location.origin + url;
|
894 |
|
895 |
+
if (['jpeg', 'jpg', 'gif', 'png'].includes(originalExtension.toLowerCase())) {
|
896 |
const img = document.createElement('img');
|
897 |
img.src = fullUrl;
|
898 |
img.alt = fileName;
|
899 |
quickOpenContent.appendChild(img);
|
900 |
+
} else if (originalExtension.toLowerCase() === 'mp4') {
|
901 |
const video = document.createElement('video');
|
902 |
video.src = fullUrl;
|
903 |
video.controls = true;
|
904 |
quickOpenContent.appendChild(video);
|
905 |
+
} else if (originalExtension.toLowerCase() === 'mp3') {
|
906 |
const audio = document.createElement('audio');
|
907 |
audio.src = fullUrl;
|
908 |
audio.controls = true;
|
909 |
quickOpenContent.appendChild(audio);
|
910 |
+
} else if (originalExtension.toLowerCase() === 'pdf') {
|
911 |
const iframe = document.createElement('iframe');
|
912 |
iframe.src = fullUrl;
|
913 |
quickOpenContent.appendChild(iframe);
|
914 |
+
} else if (originalExtension.toLowerCase() === 'txt') {
|
915 |
fetch(fullUrl)
|
916 |
.then(response => response.text())
|
917 |
.then(text => {
|
|
|
924 |
link.href = fullUrl;
|
925 |
link.textContent = 'Download ' + fileName;
|
926 |
link.target = '_blank';
|
927 |
+
link.download = `${fileName.split('.')[0]}.${originalExtension}`;
|
928 |
quickOpenContent.appendChild(link);
|
929 |
}
|
930 |
|
|
|
948 |
if 'csrftoken' not in cookies or 'sessionid' not in cookies:
|
949 |
return JSONResponse(content={"error": "Failed"}, status_code=500)
|
950 |
|
951 |
+
original_extension = os.path.splitext(file.filename)[1][1:]
|
952 |
+
temp_filename = f"{file.filename}.png"
|
953 |
+
|
954 |
+
upload_result = await initiate_upload(cookies, temp_filename, "image/png")
|
955 |
if not upload_result or 'upload_url' not in upload_result:
|
956 |
return JSONResponse(content={"error": "Failed to upload"}, status_code=500)
|
957 |
|
958 |
file_content = await file.read()
|
959 |
+
upload_success = await retry_upload(upload_result['upload_url'], file_content, "image/png")
|
960 |
if not upload_success:
|
961 |
return JSONResponse(content={"error": "FAILED GOD MAN AFTER alot of attempts"}, status_code=500)
|
962 |
|
963 |
original_url = upload_result['serving_url']
|
964 |
mirrored_url = f"/rbxg/{original_url.split('/pbxt/')[1]}"
|
965 |
|
966 |
+
return JSONResponse(content={"url": mirrored_url, "originalExtension": original_extension})
|
967 |
|
968 |
@app.get("/rbxg/{path:path}")
|
969 |
+
async def handle_file_stream(path: str, request: Request):
|
970 |
original_url = f'https://replicate.delivery/pbxt/{path}'
|
971 |
range_header = request.headers.get('Range')
|
972 |
|
|
|
1080 |
await asyncio.sleep(delay)
|
1081 |
delay = min(delay * 2, 60)
|
1082 |
|
1083 |
+
return False
|