47 lines
1.6 KiB
Python
47 lines
1.6 KiB
Python
from fastapi import FastAPI, UploadFile, File, HTTPException
|
|
import os, subprocess, re
|
|
from datetime import datetime
|
|
|
|
ZIM_DIR = "/zims"
|
|
app = FastAPI()
|
|
|
|
def safe(name):
|
|
return re.sub(r'[^\w\-. ]', '_', name)[:200]
|
|
|
|
@app.post("/api/upload")
|
|
async def upload(file: UploadFile = File(...)):
|
|
if not file.filename.lower().endswith(".zim"):
|
|
raise HTTPException(400, "ZIMs only")
|
|
fname = safe(file.filename)
|
|
path = os.path.join(ZIM_DIR, fname)
|
|
with open(path, "wb") as f:
|
|
while True:
|
|
chunk = await file.read(8 * 1024 * 1024)
|
|
if not chunk: break
|
|
f.write(chunk)
|
|
return {"ok": True, "filename": fname, "size": os.path.getsize(path)}
|
|
|
|
@app.delete("/api/delete/{filename}")
|
|
def delete(filename: str):
|
|
fn = safe(filename)
|
|
path = os.path.join(ZIM_DIR, fn)
|
|
if not os.path.exists(path):
|
|
# Try to find a file that starts with the base name (handles date-stripped catalog names)
|
|
base = fn[:-4] if fn.endswith('.zim') else fn
|
|
matches = [f for f in os.listdir(ZIM_DIR) if f.startswith(base) and f.endswith('.zim')]
|
|
if not matches:
|
|
raise HTTPException(404, f"No file matching {fn} or {base}*.zim")
|
|
if len(matches) > 1:
|
|
raise HTTPException(409, f"Multiple matches: {matches}")
|
|
path = os.path.join(ZIM_DIR, matches[0])
|
|
os.remove(path)
|
|
return {"ok": True, "deleted": os.path.basename(path)}
|
|
|
|
@app.post("/api/reload")
|
|
def reload_kiwix():
|
|
try:
|
|
subprocess.run(["docker", "restart", "kiwix"], check=True, capture_output=True, timeout=60)
|
|
return {"ok": True}
|
|
except Exception as e:
|
|
raise HTTPException(500, str(e))
|