Rewrite using fastapi

This commit is contained in:
2025-09-29 22:44:17 +10:00
commit 4291c845d8
15 changed files with 621 additions and 0 deletions
View File
+101
View File
@@ -0,0 +1,101 @@
from math import ceil
from fastapi import FastAPI, Request
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from typing import Any
import logging
import subprocess
from recoll import recoll
from fastapi import BackgroundTasks
# from .config import settings
logger = logging.getLogger()
logging.basicConfig(level=logging.DEBUG)
DOC_FOLDER = "/mnt/docs"
STRIP_CHARS = len(DOC_FOLDER) + len("file:///")
class Recoll(object):
def __init__(self):
self._indexing = False
def reindex(self):
if self._indexing:
raise RuntimeError("Reindex already underway")
self._indexing = True
subprocess.call(["recollindex"])
self._indexing = False
repo = Recoll()
app = FastAPI()
app.mount("/static", StaticFiles(directory="app/static"))
app.mount("/docs", StaticFiles(directory=DOC_FOLDER))
app.mount(
"/icons",
StaticFiles(directory="/usr/share/icons/breeze/mimetypes/32", follow_symlink=True),
)
templates = Jinja2Templates(directory="app/templates")
@app.get("/")
def home(request: Request):
ctx = {"request": request}
return templates.TemplateResponse("home.html", context=ctx)
@app.get("/search")
def search_results(request: Request, q: str, count: int = 20, page: int = 1):
ctx: dict[str, Any] = {"request": request}
ctx["search"] = search(q, count, page)
return templates.TemplateResponse("search_results.html", context=ctx)
@app.get("/api/reindex")
async def get_reindex(tasks: BackgroundTasks) -> dict[str, str]:
tasks.add_task(repo.reindex)
return {"message": "Recoll index started"}
@app.get("/api/search")
def get_search(q: str, count: int = 20, page: int = 1) -> dict[str, str]:
return search(q, count, page)
def search(q: str, count: int, page: int):
db = recoll.connect()
query = db.query()
nres = query.execute(q)
result = {
"query": q,
"count": count,
"page": page,
"pages": ceil(nres / count),
"total": nres,
"xquery": query.getxquery(),
"results": [],
}
if page > result["pages"] or page < 1:
return result
query.scroll((page - 1) * count)
docs = query.fetchmany(count)
for doc in docs:
d = dict(doc)
d["snippets"] = query.getsnippets(doc, ctxwords=20)
d["fpath"] = d["url"][STRIP_CHARS:]
result["results"].append(d)
return result
@app.get("/api/info")
def get_info():
db = recoll.connect()
return dir(db)
+12
View File
@@ -0,0 +1,12 @@
from pydantic_settings import BaseSettings
from os.path import abspath
class Settings(BaseSettings):
app_name: str = "Squirrel"
items_per_user: int = 50
archive: str = "./archive"
settings = Settings()
settings.archive = abspath(settings.archive)
+9
View File
@@ -0,0 +1,9 @@
import uvicorn
def daemon(reload=False):
uvicorn.run("squirrel.api:app", host="0.0.0.0", port=8000, reload=reload)
if __name__ == "__main__":
daemon(True)