jspy / app.py
latterworks's picture
Update app.py
f5d45fc verified
from fastapi import FastAPI, HTTPException
from fastapi.responses import FileResponse
from fastapi.middleware.cors import CORSMiddleware
import os, mimetypes, hashlib, re
from collections import defaultdict
VAULT = "vault"
app = FastAPI()
app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"])
@app.get("/")
def root():
return {
"status": "vault-online",
"browse": "/vault",
"read": "/vault/{path}",
"raw": "/raw/{path}",
"tags": "/tags",
"graph": "/graph"
}
@app.get("/vault")
@app.get("/vault/{path:path}")
def vault(path: str = ""):
full = os.path.join(VAULT, path)
if not os.path.exists(full):
raise HTTPException(404)
if os.path.isdir(full):
return {
"path": path,
"entries": [{
"name": f,
"type": "dir" if os.path.isdir(os.path.join(full, f)) else "file",
"size": os.path.getsize(os.path.join(full, f)) if os.path.isfile(os.path.join(full, f)) else None,
"modified": os.path.getmtime(os.path.join(full, f)),
"hash": hashlib.md5(f.encode()).hexdigest()[:8]
} for f in sorted(os.listdir(full))]
}
if os.path.isfile(full):
try:
with open(full, "r", encoding="utf-8") as f:
return {"path": path, "content": f.read()}
except:
raise HTTPException(500)
raise HTTPException(400)
@app.get("/raw/{path:path}")
def raw(path: str):
full = os.path.join(VAULT, path)
if not os.path.isfile(full):
raise HTTPException(404)
mt, _ = mimetypes.guess_type(full)
return FileResponse(full, media_type=mt or "application/octet-stream")
@app.get("/tags")
def extract_tags():
tag_map = defaultdict(list)
for root, _, files in os.walk(VAULT):
for f in files:
if f.endswith(".md"):
path = os.path.join(root, f)
try:
with open(path, "r", encoding="utf-8") as file:
content = file.read()
tags = re.findall(r'(?<!\w)#([\w/-]+)', content)
for tag in tags:
tag_map[tag].append(os.path.relpath(path, VAULT))
except:
continue
return dict(tag_map)
@app.get("/graph")
def link_graph():
nodes = set()
edges = []
for root, _, files in os.walk(VAULT):
for f in files:
if f.endswith(".md"):
src_path = os.path.relpath(os.path.join(root, f), VAULT)
nodes.add(src_path)
try:
with open(os.path.join(root, f), "r", encoding="utf-8") as file:
content = file.read()
links = re.findall(r'\[\[([^\]]+)\]\]', content)
for link in links:
target_file = link if link.endswith(".md") else f"{link}.md"
edges.append({"from": src_path, "to": target_file})
nodes.add(target_file)
except:
continue
return {
"nodes": sorted(list(nodes)),
"edges": edges
}