Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -1,9 +1,11 @@
|
|
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 |
|
@@ -424,13 +426,13 @@ HTML_CONTENT = """
|
|
424 |
font-size: 0.7rem;
|
425 |
}
|
426 |
|
427 |
-
|
428 |
width: 95%;
|
429 |
margin: 5% auto;
|
430 |
padding: 15px;
|
431 |
}
|
432 |
|
433 |
-
|
434 |
flex-direction: column;
|
435 |
align-items: flex-start;
|
436 |
}
|
@@ -514,6 +516,7 @@ HTML_CONTENT = """
|
|
514 |
</div>
|
515 |
</div>
|
516 |
|
|
|
517 |
<script>
|
518 |
const fileInput = document.getElementById('file');
|
519 |
const fileName = document.getElementById('fileName');
|
@@ -763,8 +766,9 @@ HTML_CONTENT = """
|
|
763 |
copyBtn.textContent = 'Copy Link';
|
764 |
copyBtn.className = 'small-btn';
|
765 |
copyBtn.onclick = () => {
|
766 |
-
|
767 |
-
|
|
|
768 |
});
|
769 |
};
|
770 |
actionsContainer.appendChild(copyBtn);
|
@@ -773,7 +777,8 @@ HTML_CONTENT = """
|
|
773 |
openBtn.textContent = 'Open';
|
774 |
openBtn.className = 'small-btn';
|
775 |
openBtn.onclick = () => {
|
776 |
-
|
|
|
777 |
};
|
778 |
actionsContainer.appendChild(openBtn);
|
779 |
|
@@ -782,23 +787,13 @@ HTML_CONTENT = """
|
|
782 |
embedBtn.textContent = 'Embed';
|
783 |
embedBtn.className = 'small-btn';
|
784 |
embedBtn.onclick = () => {
|
785 |
-
|
|
|
786 |
historyModal.style.display = "none";
|
787 |
};
|
788 |
actionsContainer.appendChild(embedBtn);
|
789 |
}
|
790 |
|
791 |
-
const encryptBtn = document.createElement('button');
|
792 |
-
encryptBtn.textContent = 'Encrypt';
|
793 |
-
encryptBtn.className = 'small-btn';
|
794 |
-
encryptBtn.onclick = () => {
|
795 |
-
const encryptedUrl = encryptUrl(item.url);
|
796 |
-
navigator.clipboard.writeText(encryptedUrl).then(() => {
|
797 |
-
alert('Encrypted link copied to clipboard!');
|
798 |
-
});
|
799 |
-
};
|
800 |
-
actionsContainer.appendChild(encryptBtn);
|
801 |
-
|
802 |
historyItem.appendChild(actionsContainer);
|
803 |
historyList.appendChild(historyItem);
|
804 |
});
|
@@ -820,7 +815,6 @@ HTML_CONTENT = """
|
|
820 |
return CryptoJS.SHA256(fingerprint).toString();
|
821 |
}
|
822 |
</script>
|
823 |
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
|
824 |
</body>
|
825 |
</html>
|
826 |
"""
|
@@ -914,6 +908,15 @@ async def embed_video(url: str, thumbnail: str):
|
|
914 |
'''
|
915 |
return HTMLResponse(content=html)
|
916 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
917 |
async def get_cookies() -> Dict[str, str]:
|
918 |
try:
|
919 |
response = requests.get('https://replicate.com/levelsio/neon-tokyo', headers={
|
@@ -968,3 +971,21 @@ async def retry_upload(upload_url: str, file_content: bytes, content_type: str,
|
|
968 |
delay = min(delay * 2, 60) # Exponential backoff, capped at 60 seconds
|
969 |
|
970 |
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import FastAPI, File, UploadFile, Request, HTTPException
|
2 |
+
from fastapi.responses import HTMLResponse, JSONResponse, StreamingResponse, RedirectResponse
|
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 |
|
|
|
426 |
font-size: 0.7rem;
|
427 |
}
|
428 |
|
429 |
+
.modal-content, .history-modal-content {
|
430 |
width: 95%;
|
431 |
margin: 5% auto;
|
432 |
padding: 15px;
|
433 |
}
|
434 |
|
435 |
+
.history-item {
|
436 |
flex-direction: column;
|
437 |
align-items: flex-start;
|
438 |
}
|
|
|
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 |
copyBtn.textContent = 'Copy Link';
|
767 |
copyBtn.className = 'small-btn';
|
768 |
copyBtn.onclick = () => {
|
769 |
+
const encryptedUrl = encryptUrl(window.location.origin + item.url);
|
770 |
+
navigator.clipboard.writeText(encryptedUrl).then(() => {
|
771 |
+
alert('Encrypted link copied to clipboard!');
|
772 |
});
|
773 |
};
|
774 |
actionsContainer.appendChild(copyBtn);
|
|
|
777 |
openBtn.textContent = 'Open';
|
778 |
openBtn.className = 'small-btn';
|
779 |
openBtn.onclick = () => {
|
780 |
+
const encryptedUrl = encryptUrl(window.location.origin + item.url);
|
781 |
+
window.open(encryptedUrl, '_blank');
|
782 |
};
|
783 |
actionsContainer.appendChild(openBtn);
|
784 |
|
|
|
787 |
embedBtn.textContent = 'Embed';
|
788 |
embedBtn.className = 'small-btn';
|
789 |
embedBtn.onclick = () => {
|
790 |
+
const encryptedUrl = encryptUrl(window.location.origin + item.url);
|
791 |
+
showEmbedModal(encryptedUrl);
|
792 |
historyModal.style.display = "none";
|
793 |
};
|
794 |
actionsContainer.appendChild(embedBtn);
|
795 |
}
|
796 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
797 |
historyItem.appendChild(actionsContainer);
|
798 |
historyList.appendChild(historyItem);
|
799 |
});
|
|
|
815 |
return CryptoJS.SHA256(fingerprint).toString();
|
816 |
}
|
817 |
</script>
|
|
|
818 |
</body>
|
819 |
</html>
|
820 |
"""
|
|
|
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={
|
|
|
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)
|