feat: Query Filter Builder for Cookbooks and Meal Plans (#4346)

This commit is contained in:
Michael Genson
2024-10-17 10:35:39 -05:00
committed by GitHub
parent 2a9a6fa5e6
commit b8e62ab8dd
47 changed files with 2043 additions and 440 deletions

View File

@@ -3,7 +3,6 @@ from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException
from pydantic import UUID4
from mealie.repos.all_repositories import get_repositories
from mealie.routes._base import controller
from mealie.routes._base.base_controllers import BasePublicHouseholdExploreController
from mealie.schema.cookbook.cookbook import ReadCookBook, RecipeCookBook
@@ -59,15 +58,12 @@ class PublicCookbooksController(BasePublicHouseholdExploreController):
if not household or household.preferences.private_household:
raise NOT_FOUND_EXCEPTION
# limit recipes to only the household the cookbook belongs to
recipes_repo = get_repositories(
self.session, group_id=self.group_id, household_id=cookbook.household_id
).recipes
recipes = recipes_repo.page_all(
cross_household_recipes = self.cross_household_repos.recipes
recipes = cross_household_recipes.page_all(
PaginationQuery(
page=1,
per_page=-1,
query_filter="settings.public = TRUE",
query_filter="settings.public = TRUE AND household.preferences.privateHousehold = FALSE",
),
cookbook=cookbook,
)

View File

@@ -4,7 +4,6 @@ import orjson
from fastapi import APIRouter, Depends, HTTPException, Query, Request
from pydantic import UUID4
from mealie.repos.all_repositories import get_repositories
from mealie.routes._base import controller
from mealie.routes._base.base_controllers import BasePublicHouseholdExploreController
from mealie.routes.recipe.recipe_crud_routes import JSONBytes
@@ -40,7 +39,6 @@ class PublicRecipesController(BasePublicHouseholdExploreController):
households: list[UUID4 | str] | None = Query(None),
) -> PaginationBase[RecipeSummary]:
cookbook_data: ReadCookBook | None = None
recipes_repo = self.cross_household_recipes
if search_query.cookbook:
COOKBOOK_NOT_FOUND_EXCEPTION = HTTPException(404, "cookbook not found")
if isinstance(search_query.cookbook, UUID):
@@ -59,18 +57,13 @@ class PublicRecipesController(BasePublicHouseholdExploreController):
if not household or household.preferences.private_household:
raise COOKBOOK_NOT_FOUND_EXCEPTION
# filter recipes by the cookbook's household
recipes_repo = get_repositories(
self.session, group_id=self.group_id, household_id=cookbook_data.household_id
).recipes
public_filter = "(household.preferences.privateHousehold = FALSE AND settings.public = TRUE)"
if q.query_filter:
q.query_filter = f"({q.query_filter}) AND {public_filter}"
else:
q.query_filter = public_filter
pagination_response = recipes_repo.page_all(
pagination_response = self.cross_household_recipes.page_all(
pagination=q,
cookbook=cookbook_data,
categories=categories,

View File

@@ -109,17 +109,8 @@ class GroupCookbookController(BaseCrudController):
if cookbook is None:
raise HTTPException(status_code=404)
return cookbook.cast(
RecipeCookBook,
recipes=self.repos.recipes.by_category_and_tags(
cookbook.categories,
cookbook.tags,
cookbook.tools,
cookbook.require_all_categories,
cookbook.require_all_tags,
cookbook.require_all_tools,
),
)
recipe_pagination = self.repos.recipes.page_all(PaginationQuery(page=1, per_page=-1, cookbook=cookbook))
return cookbook.cast(RecipeCookBook, recipes=recipe_pagination.items)
@router.put("/{item_id}", response_model=ReadCookBook)
def update_one(self, item_id: str, data: CreateCookBook):

View File

@@ -12,7 +12,7 @@ from mealie.routes._base.mixins import HttpRepo
from mealie.schema import mapper
from mealie.schema.meal_plan import CreatePlanEntry, ReadPlanEntry, SavePlanEntry, UpdatePlanEntry
from mealie.schema.meal_plan.new_meal import CreateRandomEntry, PlanEntryPagination, PlanEntryType
from mealie.schema.meal_plan.plan_rules import PlanCategory, PlanHousehold, PlanRulesDay, PlanTag
from mealie.schema.meal_plan.plan_rules import PlanRulesDay
from mealie.schema.recipe.recipe import Recipe
from mealie.schema.response.pagination import PaginationQuery
from mealie.schema.response.responses import ErrorResponse
@@ -54,31 +54,15 @@ class GroupMealplanController(BaseCrudController):
rules = self.repos.group_meal_plan_rules.get_rules(PlanRulesDay.from_date(plan_date), entry_type.value)
cross_household_recipes = get_repositories(self.session, group_id=self.group_id, household_id=None).recipes
tags: list[PlanTag] = []
categories: list[PlanCategory] = []
households: list[PlanHousehold] = []
for rule in rules:
if rule.tags:
tags.extend(rule.tags)
if rule.categories:
categories.extend(rule.categories)
if rule.households:
households.extend(rule.households)
if not (tags or categories or households):
return cross_household_recipes.get_random(limit=limit)
category_ids = [category.id for category in categories] or None
tag_ids = [tag.id for tag in tags] or None
household_ids = [household.id for household in households] or None
qf_string = " AND ".join([f"({rule.query_filter_string})" for rule in rules if rule.query_filter_string])
recipes_data = cross_household_recipes.page_all(
pagination=PaginationQuery(
page=1, per_page=limit, order_by="random", pagination_seed=self.repo._random_seed()
),
categories=category_ids,
tags=tag_ids,
households=household_ids,
page=1,
per_page=limit,
query_filter=qf_string,
order_by="random",
pagination_seed=self.repo._random_seed(),
)
)
return recipes_data.items