Add file editing capability with CodeMirror 6 integration, loading indicator for searches, and clickable home logo
This commit is contained in:
@@ -195,6 +195,39 @@ async def api_file_download(vault_name: str, path: str = Query(..., description=
|
||||
)
|
||||
|
||||
|
||||
@app.put("/api/file/{vault_name}/save")
|
||||
async def api_file_save(vault_name: str, path: str = Query(..., description="Relative path to file"), body: dict = {}):
|
||||
"""Save file content."""
|
||||
vault_data = get_vault_data(vault_name)
|
||||
if not vault_data:
|
||||
raise HTTPException(status_code=404, detail=f"Vault '{vault_name}' not found")
|
||||
|
||||
vault_root = Path(vault_data["path"])
|
||||
file_path = vault_root / path
|
||||
|
||||
# Security: ensure path is within vault
|
||||
try:
|
||||
file_path.resolve().relative_to(vault_root.resolve())
|
||||
except ValueError:
|
||||
raise HTTPException(status_code=403, detail="Access denied: path outside vault")
|
||||
|
||||
if not file_path.exists():
|
||||
raise HTTPException(status_code=404, detail=f"File not found: {path}")
|
||||
|
||||
# Get content from body
|
||||
content = body.get('content', '')
|
||||
|
||||
try:
|
||||
file_path.write_text(content, encoding="utf-8")
|
||||
logger.info(f"File saved: {vault_name}/{path}")
|
||||
return {"status": "ok", "vault": vault_name, "path": path, "size": len(content)}
|
||||
except PermissionError:
|
||||
raise HTTPException(status_code=403, detail="Permission denied: vault may be read-only")
|
||||
except Exception as e:
|
||||
logger.error(f"Error saving file {vault_name}/{path}: {e}")
|
||||
raise HTTPException(status_code=500, detail=f"Error saving file: {str(e)}")
|
||||
|
||||
|
||||
@app.get("/api/file/{vault_name}")
|
||||
async def api_file(vault_name: str, path: str = Query(..., description="Relative path to file")):
|
||||
"""Return rendered HTML + metadata for a file."""
|
||||
|
||||
Reference in New Issue
Block a user