129 lines
4.1 KiB
Python
129 lines
4.1 KiB
Python
from datetime import datetime, timezone
|
|
from typing import Any
|
|
from zoneinfo import ZoneInfo
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
from pydantic import BaseModel, Field
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.auth.deps import get_current_user
|
|
from app.db.base import get_db
|
|
from app.db.models import User
|
|
from app.homelab.context import resolve_timezone
|
|
from app.reminders_scoped.service import RemindersService
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
class ReminderCreate(BaseModel):
|
|
title: str = Field(min_length=1, max_length=255)
|
|
due_at: str = Field(description="ISO datetime, например 2027-05-12T12:16:00")
|
|
notes: str = ""
|
|
all_day: bool = False
|
|
recurrence: str = "none"
|
|
|
|
|
|
class ReminderUpdate(BaseModel):
|
|
title: str | None = Field(default=None, min_length=1, max_length=255)
|
|
due_at: str | None = None
|
|
notes: str | None = None
|
|
all_day: bool | None = None
|
|
recurrence: str | None = None
|
|
enabled: bool | None = None
|
|
|
|
|
|
@router.get("")
|
|
def get_snapshot(db: Session = Depends(get_db), user: User = Depends(get_current_user)) -> dict[str, Any]:
|
|
return RemindersService(db, user.id).snapshot()
|
|
|
|
|
|
@router.get("/upcoming")
|
|
def list_upcoming(
|
|
limit: int = Query(30, ge=1, le=100),
|
|
db: Session = Depends(get_db),
|
|
user: User = Depends(get_current_user),
|
|
) -> list[dict[str, Any]]:
|
|
return RemindersService(db, user.id).list_upcoming(limit=limit)
|
|
|
|
|
|
@router.get("/calendar")
|
|
def calendar(
|
|
year: int = Query(..., ge=2000, le=2100),
|
|
month: int = Query(..., ge=1, le=12),
|
|
db: Session = Depends(get_db),
|
|
user: User = Depends(get_current_user),
|
|
) -> dict[str, Any]:
|
|
tz_name = resolve_timezone(db, user.id)
|
|
try:
|
|
tz = ZoneInfo(tz_name)
|
|
except Exception:
|
|
tz = ZoneInfo("Europe/Moscow")
|
|
|
|
start = datetime(year, month, 1, tzinfo=tz)
|
|
if month == 12:
|
|
end = datetime(year + 1, 1, 1, tzinfo=tz)
|
|
else:
|
|
end = datetime(year, month + 1, 1, tzinfo=tz)
|
|
|
|
service = RemindersService(db, user.id)
|
|
items = service.list_in_range(
|
|
date_from=start.astimezone(timezone.utc),
|
|
date_to=end.astimezone(timezone.utc),
|
|
)
|
|
return {
|
|
"year": year,
|
|
"month": month,
|
|
"timezone": tz_name,
|
|
"reminders": items,
|
|
}
|
|
|
|
|
|
@router.post("")
|
|
def create_reminder(payload: ReminderCreate, db: Session = Depends(get_db), user: User = Depends(get_current_user)) -> dict[str, Any]:
|
|
try:
|
|
return RemindersService(db, user.id).create(
|
|
title=payload.title,
|
|
due_at=payload.due_at,
|
|
notes=payload.notes,
|
|
all_day=payload.all_day,
|
|
recurrence=payload.recurrence,
|
|
)
|
|
except ValueError as exc:
|
|
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
|
|
|
|
|
@router.patch("/{reminder_id}")
|
|
def update_reminder(
|
|
reminder_id: int,
|
|
payload: ReminderUpdate,
|
|
db: Session = Depends(get_db), user: User = Depends(get_current_user),
|
|
) -> dict[str, Any]:
|
|
try:
|
|
return RemindersService(db, user.id).update(
|
|
reminder_id,
|
|
title=payload.title,
|
|
due_at=payload.due_at,
|
|
notes=payload.notes,
|
|
all_day=payload.all_day,
|
|
recurrence=payload.recurrence,
|
|
enabled=payload.enabled,
|
|
)
|
|
except ValueError as exc:
|
|
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
|
|
|
|
|
@router.delete("/{reminder_id}")
|
|
def delete_reminder(reminder_id: int, db: Session = Depends(get_db), user: User = Depends(get_current_user)) -> dict[str, Any]:
|
|
try:
|
|
return RemindersService(db, user.id).delete(reminder_id)
|
|
except ValueError as exc:
|
|
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
|
|
|
|
|
@router.post("/{reminder_id}/complete")
|
|
def complete_reminder(reminder_id: int, db: Session = Depends(get_db), user: User = Depends(get_current_user)) -> dict[str, Any]:
|
|
try:
|
|
return RemindersService(db, user.id).complete(reminder_id)
|
|
except ValueError as exc:
|
|
raise HTTPException(status_code=404, detail=str(exc)) from exc
|