added first draft of upload interface
This commit is contained in:
@@ -0,0 +1,19 @@
|
|||||||
|
# app/frontend.py (new file or inline in main.py)
|
||||||
|
from fastapi import APIRouter
|
||||||
|
from fastapi.responses import FileResponse
|
||||||
|
from fastapi.staticfiles import StaticFiles
|
||||||
|
import os
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
# 1) Serve the folder that contains index.html, etc.
|
||||||
|
# e.g. "frontend" is relative to your project root
|
||||||
|
frontend_folder = os.path.join(os.path.dirname(__file__), "..", "frontend")
|
||||||
|
|
||||||
|
# If you just want to serve the entire folder as static:
|
||||||
|
router.mount("/static", StaticFiles(directory=frontend_folder), name="static")
|
||||||
|
|
||||||
|
# 2) For the root route ("/"), return the index.html
|
||||||
|
@router.get("/ui", response_class=FileResponse)
|
||||||
|
def serve_ui():
|
||||||
|
return os.path.join(frontend_folder, "index.html")
|
||||||
@@ -8,6 +8,7 @@ from app.tasks.upload_to_dropbox import upload_to_dropbox
|
|||||||
from app.tasks.upload_to_paperless import upload_to_paperless
|
from app.tasks.upload_to_paperless import upload_to_paperless
|
||||||
from app.tasks.upload_to_nextcloud import upload_to_nextcloud
|
from app.tasks.upload_to_nextcloud import upload_to_nextcloud
|
||||||
from app.tasks.send_to_all import send_to_all_destinations
|
from app.tasks.send_to_all import send_to_all_destinations
|
||||||
|
from app.frontend import router as frontend_router
|
||||||
|
|
||||||
app = FastAPI(title="Document Processing API")
|
app = FastAPI(title="Document Processing API")
|
||||||
|
|
||||||
@@ -111,3 +112,5 @@ def process_all_pdfs_in_workdir():
|
|||||||
"pdf_files": pdf_files,
|
"pdf_files": pdf_files,
|
||||||
"task_ids": task_ids
|
"task_ids": task_ids
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.include_router(frontend_router)
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
# In main.py or a new dedicated file, e.g. app/routes_ui.py
|
||||||
|
from fastapi import APIRouter, UploadFile, File, HTTPException
|
||||||
|
from app.tasks.upload_to_s3 import upload_to_s3
|
||||||
|
import os
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
@router.post("/ui-upload")
|
||||||
|
async def ui_upload(file: UploadFile = File(...)):
|
||||||
|
# You can store this file in your 'workdir' (like how /process does) or a tmp dir
|
||||||
|
workdir = "/workdir"
|
||||||
|
target_path = os.path.join(workdir, file.filename)
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(target_path, "wb") as f:
|
||||||
|
content = await file.read()
|
||||||
|
f.write(content)
|
||||||
|
except Exception as e:
|
||||||
|
raise HTTPException(status_code=500, detail=f"Failed to save file: {e}")
|
||||||
|
|
||||||
|
# Now you can call your existing Celery flow:
|
||||||
|
task = upload_to_s3.delay(target_path)
|
||||||
|
return {"task_id": task.id, "status": "queued"}
|
||||||
|
|
||||||
|
# Then include this in your main app as well:
|
||||||
|
# app.include_router(router)
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
<!-- File: frontend/index.html -->
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>Document Processor - Upload</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
|
||||||
|
<script>
|
||||||
|
// Optional: Additional JS for drag-and-drop, or you can keep it inline.
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body class="bg-gray-50 h-screen flex flex-col items-center justify-center">
|
||||||
|
<h1 class="text-3xl font-bold mb-8">Upload a File</h1>
|
||||||
|
|
||||||
|
<div
|
||||||
|
id="dropZone"
|
||||||
|
class="border-4 border-dashed border-gray-300 rounded-lg p-8 bg-white text-center w-1/2"
|
||||||
|
ondrop="handleDrop(event)"
|
||||||
|
ondragover="handleDragOver(event)"
|
||||||
|
>
|
||||||
|
<p class="text-gray-500">
|
||||||
|
Drag & drop a file here, or click to select a file.
|
||||||
|
</p>
|
||||||
|
<input
|
||||||
|
id="fileInput"
|
||||||
|
type="file"
|
||||||
|
class="hidden"
|
||||||
|
onchange="handleFileSelect(event)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="statusMessage" class="mt-4 text-gray-700"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const dropZone = document.getElementById("dropZone");
|
||||||
|
const fileInput = document.getElementById("fileInput");
|
||||||
|
const statusMessage = document.getElementById("statusMessage");
|
||||||
|
|
||||||
|
dropZone.addEventListener("click", () => {
|
||||||
|
fileInput.click();
|
||||||
|
});
|
||||||
|
|
||||||
|
function handleDragOver(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.dataTransfer.dropEffect = "copy";
|
||||||
|
dropZone.classList.add("bg-gray-100");
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDrop(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
dropZone.classList.remove("bg-gray-100");
|
||||||
|
if (e.dataTransfer.files.length) {
|
||||||
|
uploadFile(e.dataTransfer.files[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleFileSelect(e) {
|
||||||
|
if (e.target.files.length) {
|
||||||
|
uploadFile(e.target.files[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function uploadFile(file) {
|
||||||
|
statusMessage.textContent = `Uploading ${file.name}...`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// We'll POST the file to /upload
|
||||||
|
let formData = new FormData();
|
||||||
|
formData.append("file", file);
|
||||||
|
|
||||||
|
const response = await fetch("/ui-upload", {
|
||||||
|
method: "POST",
|
||||||
|
body: formData,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Upload failed with status ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
statusMessage.textContent = `File ${file.name} uploaded. Task ID: ${result.task_id}`;
|
||||||
|
} catch (err) {
|
||||||
|
statusMessage.textContent = `Error: ${err}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user