TermX / app.py
userbymahadi's picture
Update app.py
7d4ca5f verified
Raw
History Blame Contribute Delete
5.87 kB
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)}
# =========================
# ✅ NEW FUNCTION (ADDED)
# =========================
@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>"""