mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-12-28 21:15:26 -05:00
85 lines
2.5 KiB
Python
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]
|