Initial commit

This commit is contained in:
2026-06-30 18:30:24 +00:00
commit 67e0a90b15
54 changed files with 6184 additions and 0 deletions
+95
View File
@@ -0,0 +1,95 @@
from fastapi import FastAPI, UploadFile, File, HTTPException, Form
from fastapi.responses import JSONResponse, FileResponse
from fastapi.staticfiles import StaticFiles
import os, json, uuid, shutil, re
from datetime import datetime
PDF_DIR = "/files"
META = "/files/.metadata.json"
app = FastAPI()
def load_meta():
if os.path.exists(META):
with open(META) as f:
return json.load(f)
return {}
def save_meta(m):
with open(META, "w") as f:
json.dump(m, f, indent=2)
def safe_name(name):
return re.sub(r'[^\w\-. ]', '_', name)[:200]
@app.get("/api/list")
def list_pdfs():
meta = load_meta()
items = []
for fid, info in meta.items():
path = os.path.join(PDF_DIR, info["filename"])
if os.path.exists(path):
items.append({
"id": fid,
"title": info.get("title", info["filename"]),
"filename": info["filename"],
"tag": info.get("tag", ""),
"size": os.path.getsize(path),
"uploaded": info.get("uploaded", ""),
})
items.sort(key=lambda x: x["uploaded"], reverse=True)
return items
@app.post("/api/upload")
async def upload(file: UploadFile = File(...), title: str = Form(""), tag: str = Form("")):
if not file.filename.lower().endswith(".pdf"):
raise HTTPException(400, "PDFs only")
fid = uuid.uuid4().hex[:12]
fname = safe_name(file.filename)
path = os.path.join(PDF_DIR, f"{fid}_{fname}")
with open(path, "wb") as f:
shutil.copyfileobj(file.file, f)
meta = load_meta()
meta[fid] = {
"filename": f"{fid}_{fname}",
"title": title or fname.rsplit(".", 1)[0],
"tag": tag,
"uploaded": datetime.utcnow().isoformat(),
}
save_meta(meta)
return {"id": fid}
@app.delete("/api/delete/{fid}")
def delete(fid: str):
meta = load_meta()
if fid not in meta:
raise HTTPException(404)
path = os.path.join(PDF_DIR, meta[fid]["filename"])
if os.path.exists(path):
os.remove(path)
del meta[fid]
save_meta(meta)
return {"ok": True}
@app.get("/view/{fid}")
def view(fid: str):
meta = load_meta()
if fid not in meta:
raise HTTPException(404)
path = os.path.join(PDF_DIR, meta[fid]["filename"])
return FileResponse(path, media_type="application/pdf")
@app.patch("/api/update/{fid}")
async def update(fid: str, tag: str = Form(None), title: str = Form(None)):
meta = load_meta()
if fid not in meta:
raise HTTPException(404)
if tag is not None:
meta[fid]["tag"] = tag
if title is not None and title.strip():
meta[fid]["title"] = title.strip()
save_meta(meta)
return {"ok": True}
app.mount("/", StaticFiles(directory="/static", html=True), name="static")