1
0
Fork 0
mirror of https://github.com/mealie-recipes/mealie.git synced 2025-08-06 22:15:22 +02:00

feat: (WIP) base-shoppinglist infra (#911)

* feat:  base-shoppinglist infra (WIP)

* add type checker

* implement controllers

* apply router fixes

* add checked section hide/animation

* add label support

* formatting

* fix overflow images

* add experimental banner

* fix #912 word break issue

* remove any type errors

* bump dependencies

* remove templates

* fix build errors

* bump node version

* fix template literal
This commit is contained in:
Hayden 2022-01-08 22:24:34 -09:00 committed by GitHub
parent 86c99b10a2
commit 6db1357064
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
66 changed files with 3455 additions and 1311 deletions

View file

@ -1 +1,2 @@
from .group_shopping_list import *
from .webhook import *

View file

@ -0,0 +1,65 @@
from typing import Optional
from fastapi_camelcase import CamelModel
from pydantic import UUID4
from mealie.schema.recipe.recipe_ingredient import IngredientFood, IngredientUnit
class ShoppingListItemCreate(CamelModel):
shopping_list_id: UUID4
checked: bool = False
position: int = 0
is_food: bool = False
note: Optional[str] = ""
quantity: float = 1
unit_id: int = None
unit: IngredientUnit = None
food_id: int = None
food: IngredientFood = None
recipe_id: Optional[int] = None
label_id: Optional[UUID4] = None
class ShoppingListItemOut(ShoppingListItemCreate):
id: UUID4
label: "Optional[MultiPurposeLabelSummary]" = None
class Config:
orm_mode = True
class ShoppingListCreate(CamelModel):
"""
Create Shopping List
"""
name: str = None
class ShoppingListSave(ShoppingListCreate):
group_id: UUID4
class ShoppingListSummary(ShoppingListSave):
id: UUID4
class Config:
orm_mode = True
class ShoppingListUpdate(ShoppingListSummary):
list_items: list[ShoppingListItemOut] = []
class ShoppingListOut(ShoppingListUpdate):
class Config:
orm_mode = True
from mealie.schema.labels import MultiPurposeLabelSummary
ShoppingListItemOut.update_forward_refs()

View file

@ -0,0 +1,36 @@
from fastapi_camelcase import CamelModel
from pydantic import UUID4
from mealie.schema.recipe import IngredientFood
class MultiPurposeLabelCreate(CamelModel):
name: str
class MultiPurposeLabelSave(MultiPurposeLabelCreate):
group_id: UUID4
class MultiPurposeLabelUpdate(MultiPurposeLabelSave):
id: UUID4
class MultiPurposeLabelSummary(MultiPurposeLabelUpdate):
pass
class Config:
orm_mode = True
class MultiPurposeLabelOut(MultiPurposeLabelUpdate):
shopping_list_items: "list[ShoppingListItemOut]" = []
foods: list[IngredientFood] = []
class Config:
orm_mode = True
from mealie.schema.group.group_shopping_list import ShoppingListItemOut
MultiPurposeLabelOut.update_forward_refs()

View file

@ -1,4 +1,4 @@
from typing import Generic, TypeVar
from typing import TypeVar
from pydantic import BaseModel
@ -6,7 +6,7 @@ T = TypeVar("T", bound=BaseModel)
U = TypeVar("U", bound=BaseModel)
def mapper(source: U, dest: T, **kwargs) -> Generic[T]:
def mapper(source: U, dest: T, **_) -> T:
"""
Map a source model to a destination model. Only top-level fields are mapped.
"""
@ -16,3 +16,9 @@ def mapper(source: U, dest: T, **kwargs) -> Generic[T]:
setattr(dest, field, getattr(source, field))
return dest
def cast(source: U, dest: T, **kwargs) -> T:
create_data = {field: getattr(source, field) for field in source.__fields__ if field in dest.__fields__}
create_data.update(kwargs or {})
return dest(**create_data)

6
mealie/schema/query.py Normal file
View file

@ -0,0 +1,6 @@
from fastapi_camelcase import CamelModel
class GetAll(CamelModel):
start: int = 0
limit: int = 999

View file

@ -1,3 +1,5 @@
from __future__ import annotations
import datetime
from pathlib import Path
from typing import Any, Optional
@ -92,32 +94,32 @@ class RecipeSummary(CamelModel):
orm_mode = True
@validator("tags", always=True, pre=True)
def validate_tags(cats: list[Any]):
def validate_tags(cats: list[Any]): # type: ignore
if isinstance(cats, list) and cats and isinstance(cats[0], str):
return [RecipeTag(name=c, slug=slugify(c)) for c in cats]
return cats
@validator("recipe_category", always=True, pre=True)
def validate_categories(cats: list[Any]):
def validate_categories(cats: list[Any]): # type: ignore
if isinstance(cats, list) and cats and isinstance(cats[0], str):
return [RecipeCategory(name=c, slug=slugify(c)) for c in cats]
return cats
@validator("group_id", always=True, pre=True)
def validate_group_id(group_id: list[Any]):
def validate_group_id(group_id: Any):
if isinstance(group_id, int):
return uuid4()
return group_id
@validator("user_id", always=True, pre=True)
def validate_user_id(user_id: list[Any]):
def validate_user_id(user_id: Any):
if isinstance(user_id, int):
return uuid4()
return user_id
class Recipe(RecipeSummary):
recipe_ingredient: Optional[list[RecipeIngredient]] = []
recipe_ingredient: list[RecipeIngredient] = []
recipe_instructions: Optional[list[RecipeStep]] = []
nutrition: Optional[Nutrition]
@ -155,7 +157,7 @@ class Recipe(RecipeSummary):
orm_mode = True
@classmethod
def getter_dict(_cls, name_orm: RecipeModel):
def getter_dict(cls, name_orm: RecipeModel):
return {
**GetterDict(name_orm),
# "recipe_ingredient": [x.note for x in name_orm.recipe_ingredient],

View file

@ -1,7 +1,17 @@
from typing import Optional
from pydantic import BaseModel
class ErrorResponse(BaseModel):
message: str
error: bool = True
exception: str = None
exception: Optional[str] = None
@classmethod
def respond(cls, message: str, exception: Optional[str] = None) -> dict:
"""
This method is an helper to create an obect and convert to a dictionary
in the same call, for use while providing details to a HTTPException
"""
return cls(message=message, exception=exception).dict()

View file

@ -13,7 +13,6 @@ from mealie.db.models.users import User
from mealie.schema.group.group_preferences import ReadGroupPreferences
from mealie.schema.recipe import RecipeSummary
from ..meal_plan import ShoppingListOut
from ..recipe import CategoryBase
settings = get_app_settings()
@ -148,7 +147,6 @@ class UpdateGroup(GroupBase):
class GroupInDB(UpdateGroup):
users: Optional[list[UserOut]]
shopping_lists: Optional[list[ShoppingListOut]]
preferences: Optional[ReadGroupPreferences] = None
class Config: