82 lines
2.2 KiB
Python
82 lines
2.2 KiB
Python
from datetime import datetime
|
|
from sqlalchemy import select
|
|
from sqlalchemy.orm import Session
|
|
from app.models import Item
|
|
from app.stages import is_valid_stage
|
|
|
|
DONE_STAGES = {"done", "logged_in_bookmark"}
|
|
|
|
|
|
def create_item(
|
|
session: Session,
|
|
*,
|
|
modality: str,
|
|
raw_content: str,
|
|
captured_at: datetime,
|
|
discord_message_id: str | None,
|
|
sender_id: str | None = None,
|
|
direction: str = "inbound",
|
|
) -> tuple[Item, bool]:
|
|
if discord_message_id is not None:
|
|
existing = session.scalar(
|
|
select(Item).where(Item.discord_message_id == discord_message_id)
|
|
)
|
|
if existing is not None:
|
|
return existing, False
|
|
|
|
item = Item(
|
|
modality=modality,
|
|
raw_content=raw_content,
|
|
captured_at=captured_at,
|
|
discord_message_id=discord_message_id,
|
|
sender_id=sender_id,
|
|
direction=direction,
|
|
stage="new",
|
|
)
|
|
session.add(item)
|
|
session.commit()
|
|
session.refresh(item)
|
|
return item, True
|
|
|
|
|
|
def list_items(
|
|
session: Session,
|
|
*,
|
|
stage: str | None = None,
|
|
modality: str | None = None,
|
|
include_done: bool = False,
|
|
) -> list[Item]:
|
|
stmt = select(Item)
|
|
if stage is not None:
|
|
stmt = stmt.where(Item.stage == stage)
|
|
if modality is not None:
|
|
stmt = stmt.where(Item.modality == modality)
|
|
if not include_done:
|
|
stmt = stmt.where(Item.stage.not_in(DONE_STAGES))
|
|
stmt = stmt.order_by(Item.captured_at.desc())
|
|
return list(session.scalars(stmt))
|
|
|
|
|
|
def get_item(session: Session, item_id: int) -> Item | None:
|
|
return session.get(Item, item_id)
|
|
|
|
|
|
def update_item(session: Session, item_id: int, **fields) -> Item | None:
|
|
item = session.get(Item, item_id)
|
|
if item is None:
|
|
return None
|
|
|
|
new_type = fields.get("type", item.type)
|
|
new_stage = fields.get("stage", item.stage)
|
|
new_direction = fields.get("direction", item.direction)
|
|
if "stage" in fields and not is_valid_stage(new_type, new_stage, new_direction):
|
|
raise ValueError(
|
|
f"'{new_stage}' is not a valid stage for type '{new_type}' direction '{new_direction}'"
|
|
)
|
|
|
|
for key, value in fields.items():
|
|
setattr(item, key, value)
|
|
|
|
session.commit()
|
|
session.refresh(item)
|
|
return item
|