mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-01-02 23:21:21 -05:00
feat: support require_all property for cookbooks (#1130)
* add direction prop for icon position * add support for require_all properties on cookbook * update type annotations * add and - or filter support * update cookbook API * generate types * implement editor for additional options * update version number
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
from collections.abc import Generator
|
||||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy.orm.session import Session
|
||||
@@ -32,7 +34,7 @@ def create_session() -> Session:
|
||||
return SessionLocal()
|
||||
|
||||
|
||||
def generate_session() -> Session:
|
||||
def generate_session() -> Generator[Session, None, None]:
|
||||
global SessionLocal
|
||||
db = SessionLocal()
|
||||
try:
|
||||
|
||||
@@ -21,8 +21,13 @@ class CookBook(SqlAlchemyBase, BaseMixins):
|
||||
public = Column(Boolean, default=False)
|
||||
|
||||
categories = orm.relationship(Category, secondary=cookbooks_to_categories, single_parent=True)
|
||||
require_all_categories = Column(Boolean, default=True)
|
||||
|
||||
tags = orm.relationship(Tag, secondary=cookbooks_to_tags, single_parent=True)
|
||||
require_all_tags = Column(Boolean, default=True)
|
||||
|
||||
tools = orm.relationship(Tool, secondary=cookbooks_to_tools, single_parent=True)
|
||||
require_all_tools = Column(Boolean, default=True)
|
||||
|
||||
@auto_init()
|
||||
def __init__(self, **_) -> None:
|
||||
|
||||
@@ -20,7 +20,7 @@ from .note import Note
|
||||
from .nutrition import Nutrition
|
||||
from .settings import RecipeSettings
|
||||
from .shared import RecipeShareTokenModel
|
||||
from .tag import Tag, recipes_to_tags
|
||||
from .tag import recipes_to_tags
|
||||
from .tool import recipes_to_tools
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
|
||||
|
||||
# Mealie Specific
|
||||
settings = orm.relationship("RecipeSettings", uselist=False, cascade="all, delete-orphan")
|
||||
tags: list[Tag] = orm.relationship("Tag", secondary=recipes_to_tags, back_populates="recipes")
|
||||
tags = orm.relationship("Tag", secondary=recipes_to_tags, back_populates="recipes")
|
||||
notes: list[Note] = orm.relationship("Note", cascade="all, delete-orphan")
|
||||
rating = sa.Column(sa.Integer)
|
||||
org_url = sa.Column(sa.String)
|
||||
|
||||
@@ -130,6 +130,9 @@ class RepositoryRecipes(RepositoryGeneric[Recipe, RecipeModel]):
|
||||
categories: list[CategoryBase] | None = None,
|
||||
tags: list[TagBase] | None = None,
|
||||
tools: list[RecipeTool] | None = None,
|
||||
require_all_categories: bool = True,
|
||||
require_all_tags: bool = True,
|
||||
require_all_tools: bool = True,
|
||||
) -> list:
|
||||
fltr = [
|
||||
RecipeModel.group_id == self.group_id,
|
||||
@@ -137,15 +140,25 @@ class RepositoryRecipes(RepositoryGeneric[Recipe, RecipeModel]):
|
||||
|
||||
if categories:
|
||||
cat_ids = [x.id for x in categories]
|
||||
fltr.extend(RecipeModel.recipe_category.any(Category.id.is_(cat_id)) for cat_id in cat_ids)
|
||||
if require_all_categories:
|
||||
fltr.extend(RecipeModel.recipe_category.any(Category.id.is_(cat_id)) for cat_id in cat_ids)
|
||||
else:
|
||||
fltr.append(RecipeModel.recipe_category.any(Category.id.in_(cat_ids)))
|
||||
|
||||
if tags:
|
||||
tag_ids = [x.id for x in tags]
|
||||
fltr.extend(RecipeModel.tags.any(Tag.id.is_(tag_id)) for tag_id in tag_ids) # type:ignore
|
||||
if require_all_tags:
|
||||
fltr.extend(RecipeModel.tags.any(Tag.id.is_(tag_id)) for tag_id in tag_ids)
|
||||
else:
|
||||
fltr.append(RecipeModel.tags.any(Tag.id.in_(tag_ids)))
|
||||
|
||||
if tools:
|
||||
tool_ids = [x.id for x in tools]
|
||||
fltr.extend(RecipeModel.tools.any(Tool.id.is_(tool_id)) for tool_id in tool_ids)
|
||||
|
||||
if require_all_tools:
|
||||
fltr.extend(RecipeModel.tools.any(Tool.id.is_(tool_id)) for tool_id in tool_ids)
|
||||
else:
|
||||
fltr.append(RecipeModel.tools.any(Tool.id.in_(tool_ids)))
|
||||
|
||||
return fltr
|
||||
|
||||
@@ -154,8 +167,13 @@ class RepositoryRecipes(RepositoryGeneric[Recipe, RecipeModel]):
|
||||
categories: list[CategoryBase] | None = None,
|
||||
tags: list[TagBase] | None = None,
|
||||
tools: list[RecipeTool] | None = None,
|
||||
require_all_categories: bool = True,
|
||||
require_all_tags: bool = True,
|
||||
require_all_tools: bool = True,
|
||||
) -> list[Recipe]:
|
||||
fltr = self._category_tag_filters(categories, tags, tools)
|
||||
fltr = self._category_tag_filters(
|
||||
categories, tags, tools, require_all_categories, require_all_tags, require_all_tools
|
||||
)
|
||||
|
||||
return [self.schema.from_orm(x) for x in self.session.query(RecipeModel).filter(*fltr).all()]
|
||||
|
||||
|
||||
@@ -64,7 +64,12 @@ class GroupCookbookController(BaseUserController):
|
||||
return cookbook.cast(
|
||||
RecipeCookBook,
|
||||
recipes=self.repos.recipes.by_group(self.group_id).by_category_and_tags(
|
||||
cookbook.categories, cookbook.tags, cookbook.tools
|
||||
cookbook.categories,
|
||||
cookbook.tags,
|
||||
cookbook.tools,
|
||||
cookbook.require_all_categories,
|
||||
cookbook.require_all_tags,
|
||||
cookbook.require_all_tools,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@ class CreateCookBook(MealieModel):
|
||||
categories: list[CategoryBase] = []
|
||||
tags: list[TagBase] = []
|
||||
tools: list[RecipeTool] = []
|
||||
require_all_categories: bool = True
|
||||
require_all_tags: bool = True
|
||||
require_all_tools: bool = True
|
||||
|
||||
@validator("public", always=True, pre=True)
|
||||
def validate_public(public: bool | None, values: dict) -> bool: # type: ignore
|
||||
|
||||
Reference in New Issue
Block a user