Spaces:
Build error
Build error
Download app.py from wilooper/temp_share: direct link, hf CLI and curl.
- Browser
- Download file 6.44 kB
-
https://huggingface.co/spaces/wilooper/temp_share/resolve/main/app.py
- Command line
-
hf download hf://spaces/wilooper/temp_share/app.py
-
curl -L -o app.py https://huggingface.co/spaces/wilooper/temp_share/resolve/main/app.py
6.44 kB
| import os | |
| import uuid | |
| import time | |
| import shutil | |
| import asyncio | |
| from contextlib import asynccontextmanager | |
| from fastapi import FastAPI, UploadFile, File, Form, HTTPException | |
| from fastapi.responses import FileResponse, HTMLResponse | |
| # Configuration | |
| UPLOAD_DIR = "temp_storage" | |
| PORT = 7860 | |
| os.makedirs(UPLOAD_DIR, exist_ok=True) | |
| # Background task to clean up expired files | |
| async def cleanup_task(): | |
| while True: | |
| now = time.time() | |
| if os.path.exists(UPLOAD_DIR): | |
| for subdir in os.listdir(UPLOAD_DIR): | |
| path = os.path.join(UPLOAD_DIR, subdir) | |
| if os.path.isdir(path): | |
| meta_path = os.path.join(path, "expiry.txt") | |
| if os.path.exists(meta_path): | |
| with open(meta_path, "r") as f: | |
| expiry_time = float(f.read()) | |
| if now > expiry_time: | |
| shutil.rmtree(path) | |
| print(f"[*] Expired and deleted: {subdir}") | |
| await asyncio.sleep(60) | |
| # Lifespan handler (Replaces on_event) | |
| async def lifespan(app: FastAPI): | |
| # Startup logic | |
| loop = asyncio.get_event_loop() | |
| task = loop.create_task(cleanup_task()) | |
| yield | |
| # Shutdown logic | |
| task.cancel() | |
| app = FastAPI(lifespan=lifespan) | |
| async def upload_file( | |
| file: UploadFile = File(...), | |
| expiry_hours: float = Form(2.0), | |
| base_url: str = Form(...) | |
| ): | |
| # Enforce constraints: max 24 hours | |
| expiry_hours = min(max(expiry_hours, 0.1), 24.0) | |
| file_id = str(uuid.uuid4()) | |
| save_path = os.path.join(UPLOAD_DIR, file_id) | |
| os.makedirs(save_path, exist_ok=True) | |
| file_location = os.path.join(save_path, file.filename) | |
| with open(file_location, "wb+") as file_object: | |
| shutil.copyfileobj(file.file, file_object) | |
| # Store expiry timestamp | |
| expiry_timestamp = time.time() + (expiry_hours * 3600) | |
| with open(os.path.join(save_path, "expiry.txt"), "w") as f: | |
| f.write(str(expiry_timestamp)) | |
| # Generate direct link (TinyURL removed) | |
| direct_link = f"{base_url.rstrip('/')}/download/{file_id}/{file.filename}" | |
| return { | |
| "status": "success", | |
| "link": direct_link, | |
| "expires_in_hours": expiry_hours | |
| } | |
| async def download_file(uid: str, filename: str): | |
| file_path = os.path.join(UPLOAD_DIR, uid, filename) | |
| if os.path.exists(file_path): | |
| return FileResponse(file_path) | |
| raise HTTPException(status_code=404, detail="File not found or expired.") | |
| async def main_page(): | |
| return """ | |
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <title>File Tunnel</title> | |
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |
| <style> | |
| body { font-family: -apple-system, sans-serif; display: flex; flex-direction: column; align-items: center; padding: 20px; background: #f4f4f9; } | |
| .card { background: white; padding: 2rem; border-radius: 12px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); width: 100%; max-width: 400px; } | |
| input, button { width: 100%; margin: 10px 0; padding: 10px; border-radius: 6px; border: 1px solid #ccc; box-sizing: border-box; } | |
| button { background: #007bff; color: white; border: none; cursor: pointer; font-weight: bold; } | |
| #progress-container { width: 100%; background: #eee; border-radius: 10px; display: none; margin: 15px 0; } | |
| #progress-bar { width: 0%; height: 10px; background: #28a745; border-radius: 10px; transition: width 0.2s; } | |
| #result { margin-top: 15px; word-break: break-all; padding: 10px; background: #e9ecef; border-radius: 6px; display: none; } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="card"> | |
| <h2>File Tunnel</h2> | |
| <input type="file" id="fileInput"> | |
| <label>Expiry (Hours, max 24):</label> | |
| <input type="number" id="expiryInput" value="2" step="0.5" max="24"> | |
| <button onclick="uploadFile()" id="uploadBtn">Generate Link</button> | |
| <div id="progress-container"> | |
| <div id="progress-bar"></div> | |
| </div> | |
| <div id="result"></div> | |
| </div> | |
| <script> | |
| function uploadFile() { | |
| const fileInput = document.getElementById('fileInput'); | |
| const expiryInput = document.getElementById('expiryInput'); | |
| const resultDiv = document.getElementById('result'); | |
| const progContainer = document.getElementById('progress-container'); | |
| const progBar = document.getElementById('progress-bar'); | |
| const btn = document.getElementById('uploadBtn'); | |
| if (!fileInput.files[0]) return alert("Select a file first!"); | |
| const formData = new FormData(); | |
| formData.append("file", fileInput.files[0]); | |
| formData.append("expiry_hours", expiryInput.value); | |
| formData.append("base_url", window.location.origin); | |
| const xhr = new XMLHttpRequest(); | |
| xhr.open("POST", "/upload", true); | |
| progContainer.style.display = "block"; | |
| resultDiv.style.display = "none"; | |
| btn.disabled = true; | |
| xhr.upload.onprogress = (e) => { | |
| if (e.lengthComputable) { | |
| const percent = (e.loaded / e.total) * 100; | |
| progBar.style.width = percent + "%"; | |
| } | |
| }; | |
| xhr.onload = () => { | |
| btn.disabled = false; | |
| const res = JSON.parse(xhr.responseText); | |
| if (xhr.status === 200) { | |
| resultDiv.style.display = "block"; | |
| resultDiv.innerHTML = `<strong>Link Generated:</strong><br><a href="${res.link}" target="_blank">${res.link}</a><br><br><small>Expires in ${res.expires_in_hours}h</small>`; | |
| } else { | |
| alert("Upload failed."); | |
| } | |
| }; | |
| xhr.send(formData); | |
| } | |
| </script> | |
| </body> | |
| </html> | |
| """ | |
| if __name__ == "__main__": | |
| import uvicorn | |
| uvicorn.run(app, host="0.0.0.0", port=7860) | |