| from fastapi import FastAPI, HTTPException, Query, File, UploadFile |
| from fastapi.responses import PlainTextResponse, HTMLResponse |
| import subprocess |
| import os |
| import shutil |
|
|
| app = FastAPI() |
| print("--- NEW VERSION STARTING ---") |
| SECURITY_TOKEN = os.getenv("SECURITY_TOKEN") |
| @app.get("/") |
| def read_root(): |
| return {"status": "online", "message": "TermX API is running"} |
|
|
| @app.get("/termx", response_class=PlainTextResponse) |
| def run_command(cmd: str = Query(...), token: str = Query(...)): |
| if token != SECURITY_TOKEN: |
| raise HTTPException(status_code=403, detail="Invalid Token!") |
| try: |
| result = subprocess.run(cmd, shell=True, capture_output=True, text=True) |
| return result.stdout if result.stdout else result.stderr |
| except Exception as e: |
| return f"Error: {str(e)}" |
|
|
| |
| @app.post("/upload") |
| async def upload_file(token: str = Query(...), file: UploadFile = File(...)): |
| if token != SECURITY_TOKEN: |
| raise HTTPException(status_code=403, detail="Invalid Token!") |
| |
| try: |
| file_path = os.path.join(os.getcwd(), file.filename) |
| with open(file_path, "wb") as buffer: |
| shutil.copyfileobj(file.file, buffer) |
| |
| return {"message": f"Successfully uploaded {file.filename}"} |
| except Exception as e: |
| return {"error": str(e)} |
|
|
| |
| |
| |
|
|
| @app.get("/openweb", response_class=HTMLResponse) |
| def open_web(token: str = Query(...)): |
| if token != SECURITY_TOKEN: |
| raise HTTPException(status_code=403, detail="Invalid Token!") |
|
|
| return """<!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Modern File Upload</title> |
| |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600&display=swap" rel="stylesheet"> |
| <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> |
| |
| <style> |
| :root { |
| --primary: #6750A4; |
| --secondary: #625B71; |
| --bg: #f5f5f7; |
| --card: #ffffff; |
| --success: #2e7d32; |
| --error: #c62828; |
| } |
| |
| * { box-sizing: border-box; font-family: 'Inter', sans-serif; } |
| |
| body { |
| margin: 0; |
| background: var(--bg); |
| display: flex; |
| justify-content: center; |
| padding: 20px; |
| } |
| |
| .container { width: 100%; max-width: 500px; } |
| |
| .card { |
| background: var(--card); |
| border-radius: 20px; |
| padding: 20px; |
| box-shadow: 0 8px 20px rgba(0,0,0,0.08); |
| } |
| |
| h2 { |
| margin-top: 0; |
| color: var(--primary); |
| text-align: center; |
| } |
| |
| .upload-box { |
| border: 2px dashed var(--primary); |
| border-radius: 16px; |
| padding: 30px; |
| text-align: center; |
| cursor: pointer; |
| } |
| |
| .upload-box:hover { background: #f0ebff; } |
| |
| .upload-box i { |
| font-size: 48px; |
| color: var(--primary); |
| } |
| |
| .file-info { margin-top: 15px; } |
| |
| table { width: 100%; border-collapse: collapse; } |
| |
| td { |
| padding: 6px; |
| font-size: 14px; |
| } |
| |
| button { |
| width: 100%; |
| margin-top: 15px; |
| padding: 12px; |
| border: none; |
| border-radius: 12px; |
| background: var(--primary); |
| color: white; |
| font-size: 16px; |
| cursor: pointer; |
| } |
| |
| .progress { |
| margin-top: 10px; |
| height: 6px; |
| background: #ddd; |
| border-radius: 5px; |
| overflow: hidden; |
| } |
| |
| .progress-bar { |
| height: 100%; |
| width: 0%; |
| background: var(--primary); |
| } |
| |
| .status { |
| margin-top: 10px; |
| text-align: center; |
| } |
| |
| .success { color: var(--success); } |
| .error { color: var(--error); } |
| |
| @media (max-width: 600px) { |
| .card { padding: 15px; } |
| } |
| </style> |
| </head> |
| |
| <body> |
| |
| <div class="container"> |
| <div class="card"> |
| <h2>📁 File Upload</h2> |
| |
| <div class="upload-box" id="dropArea"> |
| <i class="material-icons">cloud_upload</i> |
| <p>Click or Drag file here</p> |
| <input type="file" id="fileInput" hidden> |
| </div> |
| |
| <div class="file-info" id="fileInfo"></div> |
| |
| <button onclick="uploadFile()">Upload File</button> |
| |
| <div class="progress"> |
| <div class="progress-bar" id="progressBar"></div> |
| </div> |
| |
| <div class="status" id="status"></div> |
| </div> |
| </div> |
| |
| <script> |
| const fileInput = document.getElementById("fileInput"); |
| const dropArea = document.getElementById("dropArea"); |
| const fileInfo = document.getElementById("fileInfo"); |
| let selectedFile = null; |
| |
| dropArea.addEventListener("click", () => fileInput.click()); |
| |
| fileInput.addEventListener("change", (e) => { |
| handleFile(e.target.files[0]); |
| }); |
| |
| dropArea.addEventListener("dragover", (e) => { |
| e.preventDefault(); |
| }); |
| |
| dropArea.addEventListener("drop", (e) => { |
| e.preventDefault(); |
| handleFile(e.dataTransfer.files[0]); |
| }); |
| |
| function handleFile(file) { |
| selectedFile = file; |
| |
| fileInfo.innerHTML = ` |
| <table> |
| <tr><td><b>Name:</b></td><td>${file.name}</td></tr> |
| <tr><td><b>Size:</b></td><td>${(file.size/1024).toFixed(2)} KB</td></tr> |
| <tr><td><b>Type:</b></td><td>${file.type}</td></tr> |
| </table> |
| `; |
| } |
| |
| function uploadFile() { |
| if (!selectedFile) { |
| alert("Select a file first!"); |
| return; |
| } |
| |
| const formData = new FormData(); |
| formData.append("file", selectedFile); |
| |
| const xhr = new XMLHttpRequest(); |
| xhr.open("POST", "/upload?token=MDMahadiHFOpenClawClawx2026", true); |
| |
| xhr.upload.onprogress = function(e) { |
| if (e.lengthComputable) { |
| let percent = (e.loaded / e.total) * 100; |
| document.getElementById("progressBar").style.width = percent + "%"; |
| } |
| }; |
| |
| xhr.onload = function() { |
| const status = document.getElementById("status"); |
| |
| if (xhr.status === 200) { |
| status.innerHTML = "✅ Upload successful!"; |
| status.className = "status success"; |
| } else { |
| status.innerHTML = "❌ Upload failed!"; |
| status.className = "status error"; |
| } |
| }; |
| |
| xhr.onerror = function() { |
| document.getElementById("status").innerHTML = "❌ Network error!"; |
| }; |
| |
| xhr.send(formData); |
| } |
| </script> |
| |
| </body> |
| </html>""" |