Files
mealie/mealie/schema/recipe/recipe_timeline_events.py
2024-12-04 22:31:26 -06:00

85 lines
2.5 KiB
Python

from datetime import UTC, datetime
from enum import Enum
from pathlib import Path
from typing import Annotated
from pydantic import UUID4, ConfigDict, Field
from sqlalchemy.orm import joinedload
from sqlalchemy.orm.interfaces import LoaderOption
from mealie.core.config import get_app_dirs
from mealie.db.models.recipe.recipe_timeline import RecipeTimelineEvent
from mealie.db.models.users.users import User
from mealie.schema._mealie import MealieModel
from mealie.schema._mealie.mealie_model import UpdatedAtField
from mealie.schema.recipe.recipe import Recipe
from mealie.schema.response.pagination import PaginationBase
app_dirs = get_app_dirs()
class TimelineEventType(Enum):
system = "system"
info = "info"
comment = "comment"
class TimelineEventImage(Enum):
has_image = "has image"
does_not_have_image = "does not have image"
class RecipeTimelineEventIn(MealieModel):
recipe_id: UUID4
user_id: UUID4 | None = None
"""can be inferred in some contexts, so it's not required"""
subject: str
event_type: TimelineEventType
message: str | None = Field(None, alias="eventMessage")
image: Annotated[TimelineEventImage | None, Field(validate_default=True)] = TimelineEventImage.does_not_have_image
timestamp: datetime = datetime.now(UTC)
model_config = ConfigDict(use_enum_values=True)
class RecipeTimelineEventCreate(RecipeTimelineEventIn):
user_id: UUID4
class RecipeTimelineEventUpdate(MealieModel):
subject: str
message: str | None = Field(None, alias="eventMessage")
image: TimelineEventImage | None = None
model_config = ConfigDict(use_enum_values=True)
class RecipeTimelineEventOut(RecipeTimelineEventCreate):
id: UUID4
group_id: UUID4
household_id: UUID4
created_at: datetime
updated_at: datetime = UpdatedAtField(...)
model_config = ConfigDict(from_attributes=True)
@classmethod
def loader_options(cls) -> list[LoaderOption]:
return [
joinedload(RecipeTimelineEvent.recipe),
joinedload(RecipeTimelineEvent.user).load_only(User.household_id, User.group_id),
]
@classmethod
def image_dir_from_id(cls, recipe_id: UUID4 | str, timeline_event_id: UUID4 | str) -> Path:
return Recipe.timeline_image_dir_from_id(recipe_id, timeline_event_id)
@property
def image_dir(self) -> Path:
return self.image_dir_from_id(self.recipe_id, self.id)
class RecipeTimelineEventPagination(PaginationBase):
items: list[RecipeTimelineEventOut]