Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -1,11 +1,9 @@
|
|
1 |
-
from fastapi import FastAPI, File, UploadFile, Request
|
2 |
-
from fastapi.responses import HTMLResponse, JSONResponse, StreamingResponse
|
3 |
import requests
|
4 |
import time
|
5 |
import asyncio
|
6 |
from typing import Dict
|
7 |
-
from cryptography.fernet import Fernet
|
8 |
-
import base64
|
9 |
|
10 |
app = FastAPI()
|
11 |
|
@@ -266,6 +264,7 @@ HTML_CONTENT = """
|
|
266 |
margin-top: 10px;
|
267 |
}
|
268 |
|
|
|
269 |
.file-types {
|
270 |
margin-top: 2rem;
|
271 |
font-size: 0.8rem;
|
@@ -426,7 +425,7 @@ HTML_CONTENT = """
|
|
426 |
font-size: 0.7rem;
|
427 |
}
|
428 |
|
429 |
-
|
430 |
width: 95%;
|
431 |
margin: 5% auto;
|
432 |
padding: 15px;
|
@@ -446,7 +445,7 @@ HTML_CONTENT = """
|
|
446 |
font-size: 0.9rem;
|
447 |
}
|
448 |
|
449 |
-
|
450 |
padding: 15px;
|
451 |
}
|
452 |
|
@@ -516,7 +515,6 @@ HTML_CONTENT = """
|
|
516 |
</div>
|
517 |
</div>
|
518 |
|
519 |
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
|
520 |
<script>
|
521 |
const fileInput = document.getElementById('file');
|
522 |
const fileName = document.getElementById('fileName');
|
@@ -766,9 +764,8 @@ HTML_CONTENT = """
|
|
766 |
copyBtn.textContent = 'Copy Link';
|
767 |
copyBtn.className = 'small-btn';
|
768 |
copyBtn.onclick = () => {
|
769 |
-
|
770 |
-
|
771 |
-
alert('Encrypted link copied to clipboard!');
|
772 |
});
|
773 |
};
|
774 |
actionsContainer.appendChild(copyBtn);
|
@@ -777,8 +774,7 @@ HTML_CONTENT = """
|
|
777 |
openBtn.textContent = 'Open';
|
778 |
openBtn.className = 'small-btn';
|
779 |
openBtn.onclick = () => {
|
780 |
-
|
781 |
-
window.open(encryptedUrl, '_blank');
|
782 |
};
|
783 |
actionsContainer.appendChild(openBtn);
|
784 |
|
@@ -787,8 +783,7 @@ HTML_CONTENT = """
|
|
787 |
embedBtn.textContent = 'Embed';
|
788 |
embedBtn.className = 'small-btn';
|
789 |
embedBtn.onclick = () => {
|
790 |
-
|
791 |
-
showEmbedModal(encryptedUrl);
|
792 |
historyModal.style.display = "none";
|
793 |
};
|
794 |
actionsContainer.appendChild(embedBtn);
|
@@ -799,21 +794,6 @@ HTML_CONTENT = """
|
|
799 |
});
|
800 |
historyModal.style.display = "block";
|
801 |
}
|
802 |
-
|
803 |
-
function encryptUrl(url) {
|
804 |
-
const key = generateBrowserFingerprint();
|
805 |
-
const encrypted = CryptoJS.AES.encrypt(url, key).toString();
|
806 |
-
return `${window.location.origin}/decrypt?data=${encodeURIComponent(encrypted)}`;
|
807 |
-
}
|
808 |
-
|
809 |
-
function generateBrowserFingerprint() {
|
810 |
-
const userAgent = navigator.userAgent;
|
811 |
-
const screenResolution = `${screen.width}x${screen.height}`;
|
812 |
-
const colorDepth = screen.colorDepth;
|
813 |
-
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
814 |
-
const fingerprint = `${userAgent}|${screenResolution}|${colorDepth}|${timezone}`;
|
815 |
-
return CryptoJS.SHA256(fingerprint).toString();
|
816 |
-
}
|
817 |
</script>
|
818 |
</body>
|
819 |
</html>
|
@@ -908,15 +888,6 @@ async def embed_video(url: str, thumbnail: str):
|
|
908 |
'''
|
909 |
return HTMLResponse(content=html)
|
910 |
|
911 |
-
@app.get("/decrypt")
|
912 |
-
async def decrypt_url(data: str, request: Request):
|
913 |
-
try:
|
914 |
-
key = generate_browser_fingerprint(request)
|
915 |
-
decrypted = decrypt_data(data, key)
|
916 |
-
return RedirectResponse(url=decrypted)
|
917 |
-
except Exception as e:
|
918 |
-
raise HTTPException(status_code=400, detail="Invalid or expired link")
|
919 |
-
|
920 |
async def get_cookies() -> Dict[str, str]:
|
921 |
try:
|
922 |
response = requests.get('https://replicate.com/levelsio/neon-tokyo', headers={
|
@@ -970,22 +941,4 @@ async def retry_upload(upload_url: str, file_content: bytes, content_type: str,
|
|
970 |
await asyncio.sleep(delay)
|
971 |
delay = min(delay * 2, 60) # Exponential backoff, capped at 60 seconds
|
972 |
|
973 |
-
return False
|
974 |
-
|
975 |
-
def generate_browser_fingerprint(request: Request) -> str:
|
976 |
-
user_agent = request.headers.get("User-Agent", "")
|
977 |
-
forwarded_for = request.headers.get("X-Forwarded-For", "")
|
978 |
-
fingerprint = f"{user_agent}|{forwarded_for}"
|
979 |
-
return base64.urlsafe_b64encode(fingerprint.encode()).decode()
|
980 |
-
|
981 |
-
def decrypt_data(encrypted_data: str, key: str) -> str:
|
982 |
-
try:
|
983 |
-
fernet = Fernet(key)
|
984 |
-
decrypted = fernet.decrypt(encrypted_data.encode()).decode()
|
985 |
-
return decrypted
|
986 |
-
except Exception as e:
|
987 |
-
raise ValueError("Decryption failed")
|
988 |
-
|
989 |
-
if __name__ == "__main__":
|
990 |
-
import uvicorn
|
991 |
-
uvicorn.run(app, host="0.0.0.0", port=8000)
|
|
|
1 |
+
from fastapi import FastAPI, File, UploadFile, Request
|
2 |
+
from fastapi.responses import HTMLResponse, JSONResponse, StreamingResponse
|
3 |
import requests
|
4 |
import time
|
5 |
import asyncio
|
6 |
from typing import Dict
|
|
|
|
|
7 |
|
8 |
app = FastAPI()
|
9 |
|
|
|
264 |
margin-top: 10px;
|
265 |
}
|
266 |
|
267 |
+
/* File Types */
|
268 |
.file-types {
|
269 |
margin-top: 2rem;
|
270 |
font-size: 0.8rem;
|
|
|
425 |
font-size: 0.7rem;
|
426 |
}
|
427 |
|
428 |
+
.modal-content, .history-modal-content {
|
429 |
width: 95%;
|
430 |
margin: 5% auto;
|
431 |
padding: 15px;
|
|
|
445 |
font-size: 0.9rem;
|
446 |
}
|
447 |
|
448 |
+
.drop-zone {
|
449 |
padding: 15px;
|
450 |
}
|
451 |
|
|
|
515 |
</div>
|
516 |
</div>
|
517 |
|
|
|
518 |
<script>
|
519 |
const fileInput = document.getElementById('file');
|
520 |
const fileName = document.getElementById('fileName');
|
|
|
764 |
copyBtn.textContent = 'Copy Link';
|
765 |
copyBtn.className = 'small-btn';
|
766 |
copyBtn.onclick = () => {
|
767 |
+
navigator.clipboard.writeText(window.location.origin + item.url).then(() => {
|
768 |
+
alert('Link copied to clipboard!');
|
|
|
769 |
});
|
770 |
};
|
771 |
actionsContainer.appendChild(copyBtn);
|
|
|
774 |
openBtn.textContent = 'Open';
|
775 |
openBtn.className = 'small-btn';
|
776 |
openBtn.onclick = () => {
|
777 |
+
window.open(window.location.origin + item.url, '_blank');
|
|
|
778 |
};
|
779 |
actionsContainer.appendChild(openBtn);
|
780 |
|
|
|
783 |
embedBtn.textContent = 'Embed';
|
784 |
embedBtn.className = 'small-btn';
|
785 |
embedBtn.onclick = () => {
|
786 |
+
showEmbedModal(item.url);
|
|
|
787 |
historyModal.style.display = "none";
|
788 |
};
|
789 |
actionsContainer.appendChild(embedBtn);
|
|
|
794 |
});
|
795 |
historyModal.style.display = "block";
|
796 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
797 |
</script>
|
798 |
</body>
|
799 |
</html>
|
|
|
888 |
'''
|
889 |
return HTMLResponse(content=html)
|
890 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
891 |
async def get_cookies() -> Dict[str, str]:
|
892 |
try:
|
893 |
response = requests.get('https://replicate.com/levelsio/neon-tokyo', headers={
|
|
|
941 |
await asyncio.sleep(delay)
|
942 |
delay = min(delay * 2, 60) # Exponential backoff, capped at 60 seconds
|
943 |
|
944 |
+
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|