Spaces:
Sleeping
Sleeping
| 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=["*"]) | |
| def root(): | |
| return { | |
| "status": "vault-online", | |
| "browse": "/vault", | |
| "read": "/vault/{path}", | |
| "raw": "/raw/{path}", | |
| "tags": "/tags", | |
| "graph": "/graph" | |
| } | |
| 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) | |
| 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") | |
| 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) | |
| 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 | |
| } |