Coverage for opt/mealie/lib/python3.12/site-packages/mealie/schema/meal_plan/plan_rules.py: 92%
65 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-11-25 15:32 +0000
« prev ^ index » next coverage.py v7.10.6, created at 2025-11-25 15:32 +0000
1import datetime 1a
2from enum import Enum 1a
3from typing import Annotated 1a
5import sqlalchemy as sa 1a
6from pydantic import UUID4, ConfigDict, Field, ValidationInfo, field_validator 1a
8from mealie.core.root_logger import get_logger 1a
9from mealie.db.models.recipe import RecipeModel 1a
10from mealie.schema._mealie import MealieModel 1a
11from mealie.schema.response.pagination import PaginationBase 1a
12from mealie.schema.response.query_filter import QueryFilterBuilder, QueryFilterJSON 1a
14logger = get_logger() 1a
17class PlanRulesDay(str, Enum): 1a
18 monday = "monday" 1a
19 tuesday = "tuesday" 1a
20 wednesday = "wednesday" 1a
21 thursday = "thursday" 1a
22 friday = "friday" 1a
23 saturday = "saturday" 1a
24 sunday = "sunday" 1a
25 unset = "unset" 1a
27 @staticmethod 1a
28 def from_date(date: datetime.date): 1a
29 """Returns the enum value for the date passed in"""
30 try: 1cdefghijkb
31 return PlanRulesDay[(date.strftime("%A").lower())] 1cdefghijkb
32 except KeyError:
33 return PlanRulesDay.unset
36class PlanRulesType(str, Enum): 1a
37 breakfast = "breakfast" 1a
38 lunch = "lunch" 1a
39 dinner = "dinner" 1a
40 side = "side" 1a
41 unset = "unset" 1a
44class PlanRulesCreate(MealieModel): 1a
45 day: PlanRulesDay = PlanRulesDay.unset 1a
46 entry_type: PlanRulesType = PlanRulesType.unset 1a
47 query_filter_string: str = "" 1a
49 @field_validator("query_filter_string") 1a
50 def validate_query_filter_string(cls, value: str) -> str: 1a
51 # The query filter builder does additional validations while building the
52 # database query, so we make sure constructing the query is successful
53 builder = QueryFilterBuilder(value) 1cdefghijkb
55 try: 1cdefghijkb
56 builder.filter_query(sa.select(RecipeModel), RecipeModel) 1cdefghijkb
57 except Exception as e:
58 raise ValueError("Invalid query filter string") from e
60 return value 1cdefghijkb
63class PlanRulesSave(PlanRulesCreate): 1a
64 group_id: UUID4 1a
65 household_id: UUID4 1a
68class PlanRulesOut(PlanRulesSave): 1a
69 id: UUID4 1a
70 query_filter: Annotated[QueryFilterJSON, Field(validate_default=True)] = None # type: ignore 1a
72 model_config = ConfigDict(from_attributes=True) 1a
74 @field_validator("query_filter_string") 1a
75 def validate_query_filter_string(value: str) -> str: 1a
76 # Skip validation since we are not updating the query filter string
77 return value 1cdefghijkb
79 @field_validator("query_filter", mode="before") 1a
80 def validate_query_filter(cls, _, info: ValidationInfo) -> QueryFilterJSON: 1a
81 try: 1cdefghijkb
82 query_filter_string: str = info.data.get("query_filter_string") or "" 1cdefghijkb
83 builder = QueryFilterBuilder(query_filter_string) 1cdefghijkb
84 return builder.as_json_model() 1cdefghijkb
85 except Exception:
86 logger.exception(f"Invalid query filter string: {query_filter_string}")
87 return QueryFilterJSON()
90class PlanRulesPagination(PaginationBase): 1a
91 items: list[PlanRulesOut] 1a