mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-07-09 03:04:54 -04:00
refactor(backend): ♻️ Split Recipe Schema Code
This commit is contained in:
parent
5ba337ab11
commit
0675c570ce
@ -1,4 +1,4 @@
|
|||||||
from mealie.schema.recipe.units_and_foods import CreateIngredientUnit
|
from mealie.schema.recipe import CreateIngredientUnit
|
||||||
from sqlalchemy.orm.session import Session
|
from sqlalchemy.orm.session import Session
|
||||||
|
|
||||||
from ..data_access_layer import DatabaseAccessLayer
|
from ..data_access_layer import DatabaseAccessLayer
|
||||||
|
@ -5,7 +5,7 @@ from mealie.db.database import db
|
|||||||
from mealie.db.db_setup import generate_session
|
from mealie.db.db_setup import generate_session
|
||||||
from mealie.routes.deps import get_current_user
|
from mealie.routes.deps import get_current_user
|
||||||
from mealie.routes.routers import UserAPIRouter
|
from mealie.routes.routers import UserAPIRouter
|
||||||
from mealie.schema.recipe import CommentIn, CommentOut, CommentSaveToDB
|
from mealie.schema.recipe import CommentOut, CreateComment, SaveComment
|
||||||
from mealie.schema.user import UserInDB
|
from mealie.schema.user import UserInDB
|
||||||
from sqlalchemy.orm.session import Session
|
from sqlalchemy.orm.session import Session
|
||||||
|
|
||||||
@ -15,20 +15,20 @@ router = UserAPIRouter()
|
|||||||
@router.post("/{slug}/comments")
|
@router.post("/{slug}/comments")
|
||||||
async def create_comment(
|
async def create_comment(
|
||||||
slug: str,
|
slug: str,
|
||||||
new_comment: CommentIn,
|
new_comment: CreateComment,
|
||||||
session: Session = Depends(generate_session),
|
session: Session = Depends(generate_session),
|
||||||
current_user: UserInDB = Depends(get_current_user),
|
current_user: UserInDB = Depends(get_current_user),
|
||||||
):
|
):
|
||||||
""" Create comment in the Database """
|
""" Create comment in the Database """
|
||||||
|
|
||||||
new_comment = CommentSaveToDB(user=current_user.id, text=new_comment.text, recipe_slug=slug)
|
new_comment = SaveComment(user=current_user.id, text=new_comment.text, recipe_slug=slug)
|
||||||
return db.comments.create(session, new_comment)
|
return db.comments.create(session, new_comment)
|
||||||
|
|
||||||
|
|
||||||
@router.put("/{slug}/comments/{id}")
|
@router.put("/{slug}/comments/{id}")
|
||||||
async def update_comment(
|
async def update_comment(
|
||||||
id: int,
|
id: int,
|
||||||
new_comment: CommentIn,
|
new_comment: CreateComment,
|
||||||
session: Session = Depends(generate_session),
|
session: Session = Depends(generate_session),
|
||||||
current_user: UserInDB = Depends(get_current_user),
|
current_user: UserInDB = Depends(get_current_user),
|
||||||
):
|
):
|
||||||
|
@ -5,7 +5,7 @@ from fastapi.datastructures import UploadFile
|
|||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.db.db_setup import generate_session
|
from mealie.db.db_setup import generate_session
|
||||||
from mealie.routes.routers import UserAPIRouter
|
from mealie.routes.routers import UserAPIRouter
|
||||||
from mealie.schema.recipe import Recipe, RecipeAsset, RecipeURLIn
|
from mealie.schema.recipe import CreateRecipeByURL, Recipe, RecipeAsset
|
||||||
from mealie.services.image.image import scrape_image, write_image
|
from mealie.services.image.image import scrape_image, write_image
|
||||||
from slugify import slugify
|
from slugify import slugify
|
||||||
from sqlalchemy.orm.session import Session
|
from sqlalchemy.orm.session import Session
|
||||||
@ -16,7 +16,7 @@ user_router = UserAPIRouter()
|
|||||||
@user_router.post("/{recipe_slug}/image")
|
@user_router.post("/{recipe_slug}/image")
|
||||||
def scrape_image_url(
|
def scrape_image_url(
|
||||||
recipe_slug: str,
|
recipe_slug: str,
|
||||||
url: RecipeURLIn,
|
url: CreateRecipeByURL,
|
||||||
):
|
):
|
||||||
""" Removes an existing image and replaces it with the incoming file. """
|
""" Removes an existing image and replaces it with the incoming file. """
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ from mealie.db.database import db
|
|||||||
from mealie.db.db_setup import generate_session
|
from mealie.db.db_setup import generate_session
|
||||||
from mealie.routes.deps import get_current_user, is_logged_in, temporary_zip_path
|
from mealie.routes.deps import get_current_user, is_logged_in, temporary_zip_path
|
||||||
from mealie.routes.routers import UserAPIRouter
|
from mealie.routes.routers import UserAPIRouter
|
||||||
from mealie.schema.recipe import Recipe, RecipeImageTypes, RecipeURLIn
|
from mealie.schema.recipe import CreateRecipeByURL, Recipe, RecipeImageTypes
|
||||||
from mealie.schema.recipe.recipe import CreateRecipe
|
from mealie.schema.recipe.recipe import CreateRecipe
|
||||||
from mealie.schema.user import UserInDB
|
from mealie.schema.user import UserInDB
|
||||||
from mealie.services.events import create_recipe_event
|
from mealie.services.events import create_recipe_event
|
||||||
@ -51,14 +51,14 @@ def create_from_name(
|
|||||||
|
|
||||||
|
|
||||||
@user_router.post("/test-scrape-url")
|
@user_router.post("/test-scrape-url")
|
||||||
def test_parse_recipe_url(url: RecipeURLIn):
|
def test_parse_recipe_url(url: CreateRecipeByURL):
|
||||||
return scrape_url(url.url)
|
return scrape_url(url.url)
|
||||||
|
|
||||||
|
|
||||||
@user_router.post("/create-url", status_code=201, response_model=str)
|
@user_router.post("/create-url", status_code=201, response_model=str)
|
||||||
def parse_recipe_url(
|
def parse_recipe_url(
|
||||||
background_tasks: BackgroundTasks,
|
background_tasks: BackgroundTasks,
|
||||||
url: RecipeURLIn,
|
url: CreateRecipeByURL,
|
||||||
session: Session = Depends(generate_session),
|
session: Session = Depends(generate_session),
|
||||||
current_user: UserInDB = Depends(get_current_user),
|
current_user: UserInDB = Depends(get_current_user),
|
||||||
):
|
):
|
||||||
|
@ -2,7 +2,7 @@ from fastapi import Depends, status
|
|||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.db.db_setup import Session, generate_session
|
from mealie.db.db_setup import Session, generate_session
|
||||||
from mealie.routes.routers import UserAPIRouter
|
from mealie.routes.routers import UserAPIRouter
|
||||||
from mealie.schema.recipe.units_and_foods import CreateIngredientFood, IngredientFood
|
from mealie.schema.recipe import CreateIngredientFood, IngredientFood
|
||||||
|
|
||||||
router = UserAPIRouter()
|
router = UserAPIRouter()
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ from fastapi import Depends, status
|
|||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.db.db_setup import Session, generate_session
|
from mealie.db.db_setup import Session, generate_session
|
||||||
from mealie.routes.routers import UserAPIRouter
|
from mealie.routes.routers import UserAPIRouter
|
||||||
from mealie.schema.recipe.units_and_foods import CreateIngredientUnit, IngredientUnit
|
from mealie.schema.recipe import CreateIngredientUnit, IngredientUnit
|
||||||
|
|
||||||
router = UserAPIRouter()
|
router = UserAPIRouter()
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ from fastapi_camelcase import CamelModel
|
|||||||
from pydantic import validator
|
from pydantic import validator
|
||||||
from slugify import slugify
|
from slugify import slugify
|
||||||
|
|
||||||
from ..recipe.category import CategoryBase, RecipeCategoryResponse
|
from ..recipe.recipe_category import CategoryBase, RecipeCategoryResponse
|
||||||
|
|
||||||
|
|
||||||
class SiteSettings(CamelModel):
|
class SiteSettings(CamelModel):
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
from .category import *
|
|
||||||
from .comments import *
|
|
||||||
from .helpers import *
|
|
||||||
from .recipe import *
|
from .recipe import *
|
||||||
|
from .recipe_category import *
|
||||||
|
from .recipe_comments import *
|
||||||
|
from .recipe_image_types import *
|
||||||
|
from .recipe_ingredient import *
|
||||||
|
from .request_helpers import *
|
||||||
|
@ -1,91 +1,34 @@
|
|||||||
import datetime
|
import datetime
|
||||||
from enum import Enum
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Optional
|
from typing import Any, Optional
|
||||||
|
|
||||||
from fastapi_camelcase import CamelModel
|
from fastapi_camelcase import CamelModel
|
||||||
from mealie.core.config import app_dirs, settings
|
from mealie.core.config import app_dirs
|
||||||
from mealie.db.models.recipe.recipe import RecipeModel
|
from mealie.db.models.recipe.recipe import RecipeModel
|
||||||
from pydantic import BaseModel, Field, validator
|
from pydantic import BaseModel, Field, validator
|
||||||
from pydantic.utils import GetterDict
|
from pydantic.utils import GetterDict
|
||||||
from slugify import slugify
|
from slugify import slugify
|
||||||
|
|
||||||
from .comments import CommentOut
|
from .recipe_asset import RecipeAsset
|
||||||
from .units_and_foods import IngredientFood, IngredientUnit
|
from .recipe_comments import CommentOut
|
||||||
|
from .recipe_ingredient import RecipeIngredient
|
||||||
|
from .recipe_notes import RecipeNote
|
||||||
|
from .recipe_nutrition import Nutrition
|
||||||
|
from .recipe_settings import RecipeSettings
|
||||||
|
from .recipe_step import RecipeStep
|
||||||
|
|
||||||
|
|
||||||
|
class CreateRecipeByURL(BaseModel):
|
||||||
|
url: str
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
schema_extra = {"example": {"url": "https://myfavoriterecipes.com/recipes"}}
|
||||||
|
|
||||||
|
|
||||||
class CreateRecipe(CamelModel):
|
class CreateRecipe(CamelModel):
|
||||||
name: str
|
name: str
|
||||||
|
|
||||||
|
|
||||||
class RecipeImageTypes(str, Enum):
|
|
||||||
original = "original.webp"
|
|
||||||
min = "min-original.webp"
|
|
||||||
tiny = "tiny-original.webp"
|
|
||||||
|
|
||||||
|
|
||||||
class RecipeSettings(CamelModel):
|
|
||||||
public: bool = settings.RECIPE_PUBLIC
|
|
||||||
show_nutrition: bool = settings.RECIPE_SHOW_NUTRITION
|
|
||||||
show_assets: bool = settings.RECIPE_SHOW_ASSETS
|
|
||||||
landscape_view: bool = settings.RECIPE_LANDSCAPE_VIEW
|
|
||||||
disable_comments: bool = settings.RECIPE_DISABLE_COMMENTS
|
|
||||||
disable_amount: bool = settings.RECIPE_DISABLE_AMOUNT
|
|
||||||
|
|
||||||
class Config:
|
|
||||||
orm_mode = True
|
|
||||||
|
|
||||||
|
|
||||||
class RecipeNote(BaseModel):
|
|
||||||
title: str
|
|
||||||
text: str
|
|
||||||
|
|
||||||
class Config:
|
|
||||||
orm_mode = True
|
|
||||||
|
|
||||||
|
|
||||||
class RecipeStep(CamelModel):
|
|
||||||
title: Optional[str] = ""
|
|
||||||
text: str
|
|
||||||
|
|
||||||
class Config:
|
|
||||||
orm_mode = True
|
|
||||||
|
|
||||||
|
|
||||||
class RecipeAsset(CamelModel):
|
|
||||||
name: str
|
|
||||||
icon: str
|
|
||||||
file_name: Optional[str]
|
|
||||||
|
|
||||||
class Config:
|
|
||||||
orm_mode = True
|
|
||||||
|
|
||||||
|
|
||||||
class Nutrition(CamelModel):
|
|
||||||
calories: Optional[str]
|
|
||||||
fat_content: Optional[str]
|
|
||||||
protein_content: Optional[str]
|
|
||||||
carbohydrate_content: Optional[str]
|
|
||||||
fiber_content: Optional[str]
|
|
||||||
sodium_content: Optional[str]
|
|
||||||
sugar_content: Optional[str]
|
|
||||||
|
|
||||||
class Config:
|
|
||||||
orm_mode = True
|
|
||||||
|
|
||||||
|
|
||||||
class RecipeIngredient(CamelModel):
|
|
||||||
title: Optional[str]
|
|
||||||
note: Optional[str]
|
|
||||||
unit: Optional[IngredientUnit]
|
|
||||||
food: Optional[IngredientFood]
|
|
||||||
disable_amount: bool = True
|
|
||||||
quantity: int = 1
|
|
||||||
|
|
||||||
class Config:
|
|
||||||
orm_mode = True
|
|
||||||
|
|
||||||
|
|
||||||
class RecipeSummary(CamelModel):
|
class RecipeSummary(CamelModel):
|
||||||
id: Optional[int]
|
id: Optional[int]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
@ -196,15 +139,10 @@ class Recipe(RecipeSummary):
|
|||||||
|
|
||||||
@validator("slug", always=True, pre=True)
|
@validator("slug", always=True, pre=True)
|
||||||
def validate_slug(slug: str, values):
|
def validate_slug(slug: str, values):
|
||||||
if not values["name"]:
|
if not values.get("name"):
|
||||||
return slug
|
return slug
|
||||||
name: str = values["name"]
|
|
||||||
calc_slug: str = slugify(name)
|
|
||||||
|
|
||||||
if slug != calc_slug:
|
return slugify(values["name"])
|
||||||
slug = calc_slug
|
|
||||||
|
|
||||||
return slug
|
|
||||||
|
|
||||||
@validator("recipe_ingredient", always=True, pre=True)
|
@validator("recipe_ingredient", always=True, pre=True)
|
||||||
def validate_ingredients(recipe_ingredient, values):
|
def validate_ingredients(recipe_ingredient, values):
|
||||||
@ -215,28 +153,3 @@ class Recipe(RecipeSummary):
|
|||||||
return [RecipeIngredient(note=x) for x in recipe_ingredient]
|
return [RecipeIngredient(note=x) for x in recipe_ingredient]
|
||||||
|
|
||||||
return recipe_ingredient
|
return recipe_ingredient
|
||||||
|
|
||||||
|
|
||||||
class AllRecipeRequest(BaseModel):
|
|
||||||
properties: list[str]
|
|
||||||
limit: Optional[int]
|
|
||||||
|
|
||||||
class Config:
|
|
||||||
schema_extra = {
|
|
||||||
"example": {
|
|
||||||
"properties": ["name", "slug", "image"],
|
|
||||||
"limit": 100,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class RecipeURLIn(BaseModel):
|
|
||||||
url: str
|
|
||||||
|
|
||||||
class Config:
|
|
||||||
schema_extra = {"example": {"url": "https://myfavoriterecipes.com/recipes"}}
|
|
||||||
|
|
||||||
|
|
||||||
class SlugResponse(BaseModel):
|
|
||||||
class Config:
|
|
||||||
schema_extra = {"example": "adult-mac-and-cheese"}
|
|
||||||
|
12
mealie/schema/recipe/recipe_asset.py
Normal file
12
mealie/schema/recipe/recipe_asset.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from fastapi_camelcase import CamelModel
|
||||||
|
|
||||||
|
|
||||||
|
class RecipeAsset(CamelModel):
|
||||||
|
name: str
|
||||||
|
icon: str
|
||||||
|
file_name: Optional[str]
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
44
mealie/schema/recipe/recipe_comments.py
Normal file
44
mealie/schema/recipe/recipe_comments.py
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from fastapi_camelcase import CamelModel
|
||||||
|
from pydantic.utils import GetterDict
|
||||||
|
|
||||||
|
|
||||||
|
class UserBase(CamelModel):
|
||||||
|
id: int
|
||||||
|
username: Optional[str]
|
||||||
|
admin: bool
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
||||||
|
|
||||||
|
|
||||||
|
class CreateComment(CamelModel):
|
||||||
|
text: str
|
||||||
|
|
||||||
|
|
||||||
|
class SaveComment(CreateComment):
|
||||||
|
recipe_slug: str
|
||||||
|
user: int
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
||||||
|
|
||||||
|
|
||||||
|
class CommentOut(CreateComment):
|
||||||
|
id: int
|
||||||
|
uuid: str
|
||||||
|
recipe_slug: str
|
||||||
|
date_added: datetime
|
||||||
|
user: UserBase
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def getter_dict(_cls, name_orm):
|
||||||
|
return {
|
||||||
|
**GetterDict(name_orm),
|
||||||
|
"recipe_slug": name_orm.recipe.slug,
|
||||||
|
}
|
7
mealie/schema/recipe/recipe_image_types.py
Normal file
7
mealie/schema/recipe/recipe_image_types.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class RecipeImageTypes(str, Enum):
|
||||||
|
original = "original.webp"
|
||||||
|
min = "min-original.webp"
|
||||||
|
tiny = "tiny-original.webp"
|
39
mealie/schema/recipe/recipe_ingredient.py
Normal file
39
mealie/schema/recipe/recipe_ingredient.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
from typing import Optional, Union
|
||||||
|
|
||||||
|
from fastapi_camelcase import CamelModel
|
||||||
|
|
||||||
|
|
||||||
|
class CreateIngredientFood(CamelModel):
|
||||||
|
name: str
|
||||||
|
description: str = ""
|
||||||
|
|
||||||
|
|
||||||
|
class CreateIngredientUnit(CreateIngredientFood):
|
||||||
|
fraction: bool = True
|
||||||
|
abbreviation: str = ""
|
||||||
|
|
||||||
|
|
||||||
|
class IngredientFood(CreateIngredientFood):
|
||||||
|
id: int
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
||||||
|
|
||||||
|
|
||||||
|
class IngredientUnit(CreateIngredientUnit):
|
||||||
|
id: int
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
||||||
|
|
||||||
|
|
||||||
|
class RecipeIngredient(CamelModel):
|
||||||
|
title: Optional[str]
|
||||||
|
note: Optional[str]
|
||||||
|
unit: Optional[Union[CreateIngredientUnit, IngredientUnit]]
|
||||||
|
food: Optional[Union[CreateIngredientFood, IngredientFood]]
|
||||||
|
disable_amount: bool = True
|
||||||
|
quantity: float = 1
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
9
mealie/schema/recipe/recipe_notes.py
Normal file
9
mealie/schema/recipe/recipe_notes.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
|
class RecipeNote(BaseModel):
|
||||||
|
title: str
|
||||||
|
text: str
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
16
mealie/schema/recipe/recipe_nutrition.py
Normal file
16
mealie/schema/recipe/recipe_nutrition.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from fastapi_camelcase import CamelModel
|
||||||
|
|
||||||
|
|
||||||
|
class Nutrition(CamelModel):
|
||||||
|
calories: Optional[str]
|
||||||
|
fat_content: Optional[str]
|
||||||
|
protein_content: Optional[str]
|
||||||
|
carbohydrate_content: Optional[str]
|
||||||
|
fiber_content: Optional[str]
|
||||||
|
sodium_content: Optional[str]
|
||||||
|
sugar_content: Optional[str]
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
14
mealie/schema/recipe/recipe_settings.py
Normal file
14
mealie/schema/recipe/recipe_settings.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
from fastapi_camelcase import CamelModel
|
||||||
|
from mealie.core.config import settings
|
||||||
|
|
||||||
|
|
||||||
|
class RecipeSettings(CamelModel):
|
||||||
|
public: bool = settings.RECIPE_PUBLIC
|
||||||
|
show_nutrition: bool = settings.RECIPE_SHOW_NUTRITION
|
||||||
|
show_assets: bool = settings.RECIPE_SHOW_ASSETS
|
||||||
|
landscape_view: bool = settings.RECIPE_LANDSCAPE_VIEW
|
||||||
|
disable_comments: bool = settings.RECIPE_DISABLE_COMMENTS
|
||||||
|
disable_amount: bool = settings.RECIPE_DISABLE_AMOUNT
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
11
mealie/schema/recipe/recipe_step.py
Normal file
11
mealie/schema/recipe/recipe_step.py
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from fastapi_camelcase import CamelModel
|
||||||
|
|
||||||
|
|
||||||
|
class RecipeStep(CamelModel):
|
||||||
|
title: Optional[str] = ""
|
||||||
|
text: str
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
13
mealie/schema/recipe/request_helpers.py
Normal file
13
mealie/schema/recipe/request_helpers.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from fastapi_camelcase import CamelModel
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
# TODO: Should these exist?!?!?!?!?
|
||||||
|
|
||||||
|
|
||||||
|
class RecipeSlug(CamelModel):
|
||||||
|
slug: str
|
||||||
|
|
||||||
|
|
||||||
|
class SlugResponse(BaseModel):
|
||||||
|
class Config:
|
||||||
|
schema_extra = {"example": "adult-mac-and-cheese"}
|
4
mealie/schema/recipe_old/__init__.py
Normal file
4
mealie/schema/recipe_old/__init__.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
from .category import *
|
||||||
|
from .comments import *
|
||||||
|
from .helpers import *
|
||||||
|
from .recipe import *
|
48
mealie/schema/recipe_old/category.py
Normal file
48
mealie/schema/recipe_old/category.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
from typing import List, Optional
|
||||||
|
|
||||||
|
from fastapi_camelcase import CamelModel
|
||||||
|
from pydantic.utils import GetterDict
|
||||||
|
|
||||||
|
|
||||||
|
class CategoryIn(CamelModel):
|
||||||
|
name: str
|
||||||
|
|
||||||
|
|
||||||
|
class CategoryBase(CategoryIn):
|
||||||
|
id: int
|
||||||
|
slug: str
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def getter_dict(_cls, name_orm):
|
||||||
|
return {
|
||||||
|
**GetterDict(name_orm),
|
||||||
|
"total_recipes": len(name_orm.recipes),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class RecipeCategoryResponse(CategoryBase):
|
||||||
|
recipes: Optional[List["Recipe"]]
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
schema_extra = {"example": {"id": 1, "name": "dinner", "recipes": [{}]}}
|
||||||
|
|
||||||
|
|
||||||
|
class TagIn(CategoryIn):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TagBase(CategoryBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class RecipeTagResponse(RecipeCategoryResponse):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
from .recipe import Recipe
|
||||||
|
|
||||||
|
RecipeCategoryResponse.update_forward_refs()
|
||||||
|
RecipeTagResponse.update_forward_refs()
|
242
mealie/schema/recipe_old/recipe.py
Normal file
242
mealie/schema/recipe_old/recipe.py
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
import datetime
|
||||||
|
from enum import Enum
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Any, Optional
|
||||||
|
|
||||||
|
from fastapi_camelcase import CamelModel
|
||||||
|
from mealie.core.config import app_dirs, settings
|
||||||
|
from mealie.db.models.recipe.recipe import RecipeModel
|
||||||
|
from pydantic import BaseModel, Field, validator
|
||||||
|
from pydantic.utils import GetterDict
|
||||||
|
from slugify import slugify
|
||||||
|
|
||||||
|
from .comments import CommentOut
|
||||||
|
from .units_and_foods import IngredientFood, IngredientUnit
|
||||||
|
|
||||||
|
|
||||||
|
class CreateRecipe(CamelModel):
|
||||||
|
name: str
|
||||||
|
|
||||||
|
|
||||||
|
class RecipeImageTypes(str, Enum):
|
||||||
|
original = "original.webp"
|
||||||
|
min = "min-original.webp"
|
||||||
|
tiny = "tiny-original.webp"
|
||||||
|
|
||||||
|
|
||||||
|
class RecipeSettings(CamelModel):
|
||||||
|
public: bool = settings.RECIPE_PUBLIC
|
||||||
|
show_nutrition: bool = settings.RECIPE_SHOW_NUTRITION
|
||||||
|
show_assets: bool = settings.RECIPE_SHOW_ASSETS
|
||||||
|
landscape_view: bool = settings.RECIPE_LANDSCAPE_VIEW
|
||||||
|
disable_comments: bool = settings.RECIPE_DISABLE_COMMENTS
|
||||||
|
disable_amount: bool = settings.RECIPE_DISABLE_AMOUNT
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
||||||
|
|
||||||
|
|
||||||
|
class RecipeNote(BaseModel):
|
||||||
|
title: str
|
||||||
|
text: str
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
||||||
|
|
||||||
|
|
||||||
|
class RecipeStep(CamelModel):
|
||||||
|
title: Optional[str] = ""
|
||||||
|
text: str
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
||||||
|
|
||||||
|
|
||||||
|
class RecipeAsset(CamelModel):
|
||||||
|
name: str
|
||||||
|
icon: str
|
||||||
|
file_name: Optional[str]
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
||||||
|
|
||||||
|
|
||||||
|
class Nutrition(CamelModel):
|
||||||
|
calories: Optional[str]
|
||||||
|
fat_content: Optional[str]
|
||||||
|
protein_content: Optional[str]
|
||||||
|
carbohydrate_content: Optional[str]
|
||||||
|
fiber_content: Optional[str]
|
||||||
|
sodium_content: Optional[str]
|
||||||
|
sugar_content: Optional[str]
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
||||||
|
|
||||||
|
|
||||||
|
class RecipeIngredient(CamelModel):
|
||||||
|
title: Optional[str]
|
||||||
|
note: Optional[str]
|
||||||
|
unit: Optional[IngredientUnit]
|
||||||
|
food: Optional[IngredientFood]
|
||||||
|
disable_amount: bool = True
|
||||||
|
quantity: int = 1
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
||||||
|
|
||||||
|
|
||||||
|
class RecipeSummary(CamelModel):
|
||||||
|
id: Optional[int]
|
||||||
|
name: Optional[str]
|
||||||
|
slug: str = ""
|
||||||
|
image: Optional[Any]
|
||||||
|
|
||||||
|
description: Optional[str]
|
||||||
|
recipe_category: Optional[list[str]] = []
|
||||||
|
tags: Optional[list[str]] = []
|
||||||
|
rating: Optional[int]
|
||||||
|
|
||||||
|
date_added: Optional[datetime.date]
|
||||||
|
date_updated: Optional[datetime.datetime]
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def getter_dict(_cls, name_orm: RecipeModel):
|
||||||
|
return {
|
||||||
|
**GetterDict(name_orm),
|
||||||
|
"recipe_category": [x.name for x in name_orm.recipe_category],
|
||||||
|
"tags": [x.name for x in name_orm.tags],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Recipe(RecipeSummary):
|
||||||
|
recipe_yield: Optional[str]
|
||||||
|
recipe_ingredient: Optional[list[RecipeIngredient]] = []
|
||||||
|
recipe_instructions: Optional[list[RecipeStep]] = []
|
||||||
|
nutrition: Optional[Nutrition]
|
||||||
|
tools: Optional[list[str]] = []
|
||||||
|
|
||||||
|
total_time: Optional[str] = None
|
||||||
|
prep_time: Optional[str] = None
|
||||||
|
perform_time: Optional[str] = None
|
||||||
|
|
||||||
|
# Mealie Specific
|
||||||
|
settings: Optional[RecipeSettings] = RecipeSettings()
|
||||||
|
assets: Optional[list[RecipeAsset]] = []
|
||||||
|
notes: Optional[list[RecipeNote]] = []
|
||||||
|
org_url: Optional[str] = Field(None, alias="orgURL")
|
||||||
|
extras: Optional[dict] = {}
|
||||||
|
|
||||||
|
comments: Optional[list[CommentOut]] = []
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def directory_from_slug(slug) -> Path:
|
||||||
|
return app_dirs.RECIPE_DATA_DIR.joinpath(slug)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def directory(self) -> Path:
|
||||||
|
dir = app_dirs.RECIPE_DATA_DIR.joinpath(self.slug)
|
||||||
|
dir.mkdir(exist_ok=True, parents=True)
|
||||||
|
return dir
|
||||||
|
|
||||||
|
@property
|
||||||
|
def asset_dir(self) -> Path:
|
||||||
|
dir = self.directory.joinpath("assets")
|
||||||
|
dir.mkdir(exist_ok=True, parents=True)
|
||||||
|
return dir
|
||||||
|
|
||||||
|
@property
|
||||||
|
def image_dir(self) -> Path:
|
||||||
|
dir = self.directory.joinpath("images")
|
||||||
|
dir.mkdir(exist_ok=True, parents=True)
|
||||||
|
return dir
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def getter_dict(_cls, name_orm: RecipeModel):
|
||||||
|
return {
|
||||||
|
**GetterDict(name_orm),
|
||||||
|
# "recipe_ingredient": [x.note for x in name_orm.recipe_ingredient],
|
||||||
|
"recipe_category": [x.name for x in name_orm.recipe_category],
|
||||||
|
"tags": [x.name for x in name_orm.tags],
|
||||||
|
"tools": [x.tool for x in name_orm.tools],
|
||||||
|
"extras": {x.key_name: x.value for x in name_orm.extras},
|
||||||
|
}
|
||||||
|
|
||||||
|
schema_extra = {
|
||||||
|
"example": {
|
||||||
|
"name": "Chicken and Rice With Leeks and Salsa Verde",
|
||||||
|
"description": "This one-skillet dinner gets deep oniony flavor from lots of leeks cooked down to jammy tenderness.",
|
||||||
|
"image": "chicken-and-rice-with-leeks-and-salsa-verde.jpg",
|
||||||
|
"recipe_yield": "4 Servings",
|
||||||
|
"recipe_ingredient": [
|
||||||
|
"1 1/2 lb. skinless, boneless chicken thighs (4-8 depending on size)",
|
||||||
|
"Kosher salt, freshly ground pepper",
|
||||||
|
"3 Tbsp. unsalted butter, divided",
|
||||||
|
],
|
||||||
|
"recipe_instructions": [
|
||||||
|
{
|
||||||
|
"text": "Season chicken with salt and pepper.",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"slug": "chicken-and-rice-with-leeks-and-salsa-verde",
|
||||||
|
"tags": ["favorite", "yummy!"],
|
||||||
|
"recipe_category": ["Dinner", "Pasta"],
|
||||||
|
"notes": [{"title": "Watch Out!", "text": "Prep the day before!"}],
|
||||||
|
"org_url": "https://www.bonappetit.com/recipe/chicken-and-rice-with-leeks-and-salsa-verde",
|
||||||
|
"rating": 3,
|
||||||
|
"extras": {"message": "Don't forget to defrost the chicken!"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@validator("slug", always=True, pre=True)
|
||||||
|
def validate_slug(slug: str, values):
|
||||||
|
if not values["name"]:
|
||||||
|
return slug
|
||||||
|
name: str = values["name"]
|
||||||
|
calc_slug: str = slugify(name)
|
||||||
|
|
||||||
|
if slug != calc_slug:
|
||||||
|
slug = calc_slug
|
||||||
|
|
||||||
|
return slug
|
||||||
|
|
||||||
|
@validator("recipe_ingredient", always=True, pre=True)
|
||||||
|
def validate_ingredients(recipe_ingredient, values):
|
||||||
|
if not recipe_ingredient or not isinstance(recipe_ingredient, list):
|
||||||
|
return recipe_ingredient
|
||||||
|
|
||||||
|
if all(isinstance(elem, str) for elem in recipe_ingredient):
|
||||||
|
return [RecipeIngredient(note=x) for x in recipe_ingredient]
|
||||||
|
|
||||||
|
return recipe_ingredient
|
||||||
|
|
||||||
|
|
||||||
|
class AllRecipeRequest(BaseModel):
|
||||||
|
properties: list[str]
|
||||||
|
limit: Optional[int]
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
schema_extra = {
|
||||||
|
"example": {
|
||||||
|
"properties": ["name", "slug", "image"],
|
||||||
|
"limit": 100,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class RecipeURLIn(BaseModel):
|
||||||
|
url: str
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
schema_extra = {"example": {"url": "https://myfavoriterecipes.com/recipes"}}
|
||||||
|
|
||||||
|
|
||||||
|
class SlugResponse(BaseModel):
|
||||||
|
class Config:
|
||||||
|
schema_extra = {"example": "adult-mac-and-cheese"}
|
Loading…
x
Reference in New Issue
Block a user