previews on home
This commit is contained in:
@@ -11,6 +11,9 @@ from backend.database import get_user_id
|
||||
|
||||
TAG_RE = re.compile(r"#[A-Za-z0-9_-]+")
|
||||
|
||||
ATTACH_RE = re.compile(r"/api/attachments/([^/\s]+)/([A-Za-z0-9._-]+)")
|
||||
IMAGE_EXT_RE = re.compile(r"\.(png|jpe?g|gif|webp|svg|avif|bmp|ico|heic)$", re.IGNORECASE)
|
||||
|
||||
|
||||
def extract_tags(text: str) -> list[str]:
|
||||
seen: list[str] = []
|
||||
@@ -35,6 +38,16 @@ def extract_title(text: str) -> str:
|
||||
return "Untitled"
|
||||
|
||||
|
||||
def note_attachments(body: str) -> tuple[int, str | None]:
|
||||
count = 0
|
||||
preview = None
|
||||
for m in ATTACH_RE.finditer(body):
|
||||
count += 1
|
||||
if preview is None and IMAGE_EXT_RE.search(m.group(2)):
|
||||
preview = f"/api/attachments/{m.group(1)}/{m.group(2)}"
|
||||
return count, preview
|
||||
|
||||
|
||||
def note_path(username: str, note_id: str) -> str:
|
||||
return f"{username}/{note_id}.md"
|
||||
|
||||
@@ -231,15 +244,15 @@ async def list_notes(username: str, limit: int = 100) -> list[dict]:
|
||||
async with aiosqlite.connect(settings.database_path) as db:
|
||||
db.row_factory = aiosqlite.Row
|
||||
rows = await db.execute(
|
||||
"SELECT n.id, n.title, n.updated_at, n.created_at, u.name AS username"
|
||||
"SELECT n.id, n.title, n.updated_at, n.created_at, n.path,"
|
||||
" u.name AS username"
|
||||
" FROM notes n JOIN users u ON u.id = n.user_id"
|
||||
" WHERE n.deleted_at IS NULL AND u.name = ?"
|
||||
" ORDER BY n.updated_at DESC LIMIT ?",
|
||||
(username, limit),
|
||||
)
|
||||
notes = [dict(r) for r in await rows.fetchall()]
|
||||
for note in notes:
|
||||
note["tags"] = await get_note_tags(note["id"])
|
||||
await _attach_meta(notes)
|
||||
return notes
|
||||
|
||||
|
||||
@@ -247,15 +260,15 @@ async def list_recent(username: str, limit: int = 30) -> list[dict]:
|
||||
async with aiosqlite.connect(settings.database_path) as db:
|
||||
db.row_factory = aiosqlite.Row
|
||||
rows = await db.execute(
|
||||
"SELECT n.id, n.title, n.updated_at, n.created_at, u.name AS username"
|
||||
"SELECT n.id, n.title, n.updated_at, n.created_at, n.path,"
|
||||
" u.name AS username"
|
||||
" FROM notes n JOIN users u ON u.id = n.user_id"
|
||||
" WHERE n.deleted_at IS NULL AND u.name IN (?, ?)"
|
||||
" ORDER BY n.updated_at DESC LIMIT ?",
|
||||
(username, settings.common_space, limit),
|
||||
)
|
||||
notes = [dict(r) for r in await rows.fetchall()]
|
||||
for note in notes:
|
||||
note["tags"] = await get_note_tags(note["id"])
|
||||
await _attach_meta(notes)
|
||||
return notes
|
||||
|
||||
|
||||
@@ -270,6 +283,19 @@ async def get_note_tags(note_id: str) -> list[str]:
|
||||
return [r["name"] for r in await rows.fetchall()]
|
||||
|
||||
|
||||
async def _attach_meta(notes: list[dict]) -> None:
|
||||
for note in notes:
|
||||
note["tags"] = await get_note_tags(note["id"])
|
||||
try:
|
||||
body = await read_note_file(note["path"])
|
||||
count, preview = note_attachments(body)
|
||||
except FileNotFoundError:
|
||||
count, preview = 0, None
|
||||
note["attachments"] = count
|
||||
note["image"] = preview
|
||||
note.pop("path", None)
|
||||
|
||||
|
||||
async def tag_counts() -> list[dict]:
|
||||
async with aiosqlite.connect(settings.database_path) as db:
|
||||
db.row_factory = aiosqlite.Row
|
||||
|
||||
Reference in New Issue
Block a user