R1 foundation - Phase 1 live build
This commit is contained in:
92
routers/capture.py
Normal file
92
routers/capture.py
Normal file
@@ -0,0 +1,92 @@
|
||||
"""Capture: quick text capture queue with conversion."""
|
||||
|
||||
from fastapi import APIRouter, Request, Form, Depends
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from fastapi.responses import RedirectResponse
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import text
|
||||
from typing import Optional
|
||||
|
||||
from core.database import get_db
|
||||
from core.base_repository import BaseRepository
|
||||
from core.sidebar import get_sidebar_data
|
||||
|
||||
router = APIRouter(prefix="/capture", tags=["capture"])
|
||||
templates = Jinja2Templates(directory="templates")
|
||||
|
||||
|
||||
@router.get("/")
|
||||
async def list_capture(request: Request, show: str = "unprocessed", db: AsyncSession = Depends(get_db)):
|
||||
sidebar = await get_sidebar_data(db)
|
||||
if show == "all":
|
||||
filters = {}
|
||||
else:
|
||||
filters = {"processed": False}
|
||||
|
||||
result = await db.execute(text("""
|
||||
SELECT * FROM capture WHERE is_deleted = false
|
||||
AND (:show_all OR processed = false)
|
||||
ORDER BY created_at DESC
|
||||
"""), {"show_all": show == "all"})
|
||||
items = [dict(r._mapping) for r in result]
|
||||
|
||||
return templates.TemplateResponse("capture.html", {
|
||||
"request": request, "sidebar": sidebar, "items": items,
|
||||
"show": show,
|
||||
"page_title": "Capture", "active_nav": "capture",
|
||||
})
|
||||
|
||||
|
||||
@router.post("/add")
|
||||
async def add_capture(
|
||||
request: Request,
|
||||
raw_text: str = Form(...),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
repo = BaseRepository("capture", db)
|
||||
# Multi-line: split into individual items
|
||||
lines = [l.strip() for l in raw_text.strip().split("\n") if l.strip()]
|
||||
for line in lines:
|
||||
await repo.create({"raw_text": line, "processed": False})
|
||||
return RedirectResponse(url="/capture", status_code=303)
|
||||
|
||||
|
||||
@router.post("/{capture_id}/to-task")
|
||||
async def convert_to_task(
|
||||
capture_id: str,
|
||||
request: Request,
|
||||
domain_id: str = Form(...),
|
||||
project_id: Optional[str] = Form(None),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
capture_repo = BaseRepository("capture", db)
|
||||
item = await capture_repo.get(capture_id)
|
||||
if not item:
|
||||
return RedirectResponse(url="/capture", status_code=303)
|
||||
|
||||
task_repo = BaseRepository("tasks", db)
|
||||
data = {"title": item["raw_text"], "domain_id": domain_id, "status": "open", "priority": 3}
|
||||
if project_id and project_id.strip():
|
||||
data["project_id"] = project_id
|
||||
task = await task_repo.create(data)
|
||||
|
||||
await capture_repo.update(capture_id, {
|
||||
"processed": True,
|
||||
"converted_to_type": "task",
|
||||
"converted_to_id": str(task["id"]),
|
||||
})
|
||||
return RedirectResponse(url="/capture", status_code=303)
|
||||
|
||||
|
||||
@router.post("/{capture_id}/dismiss")
|
||||
async def dismiss_capture(capture_id: str, db: AsyncSession = Depends(get_db)):
|
||||
repo = BaseRepository("capture", db)
|
||||
await repo.update(capture_id, {"processed": True})
|
||||
return RedirectResponse(url="/capture", status_code=303)
|
||||
|
||||
|
||||
@router.post("/{capture_id}/delete")
|
||||
async def delete_capture(capture_id: str, db: AsyncSession = Depends(get_db)):
|
||||
repo = BaseRepository("capture", db)
|
||||
await repo.soft_delete(capture_id)
|
||||
return RedirectResponse(url="/capture", status_code=303)
|
||||
Reference in New Issue
Block a user