mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-12-30 13:50:42 -05:00
feat: Filter Recipes By Household (and a ton of bug fixes) (#4207)
Co-authored-by: Kuchenpirat <24235032+Kuchenpirat@users.noreply.github.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
from abc import ABC
|
||||
from logging import Logger
|
||||
|
||||
from fastapi import Depends
|
||||
from fastapi import Depends, HTTPException
|
||||
from pydantic import UUID4, ConfigDict
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
@@ -97,6 +97,12 @@ class BasePublicGroupExploreController(BasePublicController):
|
||||
def group_id(self) -> UUID4 | None | NotSet:
|
||||
return self.group.id
|
||||
|
||||
def get_public_household(self, household_slug_or_id: str | UUID4) -> HouseholdInDB:
|
||||
household = self.repos.households.get_by_slug_or_id(household_slug_or_id)
|
||||
if not household or household.preferences.private_household:
|
||||
raise HTTPException(404, "household not found")
|
||||
return household
|
||||
|
||||
def get_explore_url_path(self, endpoint: str) -> str:
|
||||
if endpoint.startswith("/"):
|
||||
endpoint = endpoint[1:]
|
||||
|
||||
@@ -3,6 +3,7 @@ from fastapi import APIRouter
|
||||
from . import (
|
||||
controller_public_cookbooks,
|
||||
controller_public_foods,
|
||||
controller_public_households,
|
||||
controller_public_organizers,
|
||||
controller_public_recipes,
|
||||
)
|
||||
@@ -11,6 +12,7 @@ router = APIRouter(prefix="/explore/groups/{group_slug}")
|
||||
|
||||
# group
|
||||
router.include_router(controller_public_foods.router, tags=["Explore: Foods"])
|
||||
router.include_router(controller_public_households.router, tags=["Explore: Households"])
|
||||
router.include_router(controller_public_organizers.categories_router, tags=["Explore: Categories"])
|
||||
router.include_router(controller_public_organizers.tags_router, tags=["Explore: Tags"])
|
||||
router.include_router(controller_public_organizers.tools_router, tags=["Explore: Tools"])
|
||||
|
||||
35
mealie/routes/explore/controller_public_households.py
Normal file
35
mealie/routes/explore/controller_public_households.py
Normal file
@@ -0,0 +1,35 @@
|
||||
from fastapi import APIRouter, Depends
|
||||
|
||||
from mealie.routes._base import controller
|
||||
from mealie.routes._base.base_controllers import BasePublicGroupExploreController
|
||||
from mealie.schema.household.household import HouseholdSummary
|
||||
from mealie.schema.make_dependable import make_dependable
|
||||
from mealie.schema.response.pagination import PaginationBase, PaginationQuery
|
||||
|
||||
router = APIRouter(prefix="/households")
|
||||
|
||||
|
||||
@controller(router)
|
||||
class PublicHouseholdsController(BasePublicGroupExploreController):
|
||||
@property
|
||||
def households(self):
|
||||
return self.repos.households
|
||||
|
||||
@router.get("", response_model=PaginationBase[HouseholdSummary])
|
||||
def get_all(
|
||||
self, q: PaginationQuery = Depends(make_dependable(PaginationQuery))
|
||||
) -> PaginationBase[HouseholdSummary]:
|
||||
public_filter = "(preferences.private_household = FALSE)"
|
||||
if q.query_filter:
|
||||
q.query_filter = f"({q.query_filter}) AND {public_filter}"
|
||||
else:
|
||||
q.query_filter = public_filter
|
||||
|
||||
response = self.households.page_all(pagination=q, override=HouseholdSummary)
|
||||
response.set_pagination_guides(self.get_explore_url_path(router.url_path_for("get_all")), q.model_dump())
|
||||
return response
|
||||
|
||||
@router.get("/{household_slug}", response_model=HouseholdSummary)
|
||||
def get_household(self, household_slug: str) -> HouseholdSummary:
|
||||
household = self.get_public_household(household_slug)
|
||||
return household.cast(HouseholdSummary)
|
||||
@@ -37,6 +37,7 @@ class PublicRecipesController(BasePublicHouseholdExploreController):
|
||||
tags: list[UUID4 | str] | None = Query(None),
|
||||
tools: list[UUID4 | str] | None = Query(None),
|
||||
foods: list[UUID4 | str] | None = Query(None),
|
||||
households: list[UUID4 | str] | None = Query(None),
|
||||
) -> PaginationBase[RecipeSummary]:
|
||||
cookbook_data: ReadCookBook | None = None
|
||||
recipes_repo = self.cross_household_recipes
|
||||
@@ -76,6 +77,7 @@ class PublicRecipesController(BasePublicHouseholdExploreController):
|
||||
tags=tags,
|
||||
tools=tools,
|
||||
foods=foods,
|
||||
households=households,
|
||||
require_all_categories=search_query.require_all_categories,
|
||||
require_all_tags=search_query.require_all_tags,
|
||||
require_all_tools=search_query.require_all_tools,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from fastapi import APIRouter
|
||||
|
||||
from . import (
|
||||
controller_group_households,
|
||||
controller_group_reports,
|
||||
controller_group_self_service,
|
||||
controller_labels,
|
||||
@@ -10,6 +11,7 @@ from . import (
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
router.include_router(controller_group_households.router)
|
||||
router.include_router(controller_group_self_service.router)
|
||||
router.include_router(controller_migrations.router)
|
||||
router.include_router(controller_group_reports.router)
|
||||
|
||||
27
mealie/routes/groups/controller_group_households.py
Normal file
27
mealie/routes/groups/controller_group_households.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from fastapi import Depends, HTTPException
|
||||
|
||||
from mealie.routes._base.base_controllers import BaseUserController
|
||||
from mealie.routes._base.controller import controller
|
||||
from mealie.routes._base.routers import UserAPIRouter
|
||||
from mealie.schema.household.household import HouseholdSummary
|
||||
from mealie.schema.response.pagination import PaginationBase, PaginationQuery
|
||||
|
||||
router = UserAPIRouter(prefix="/groups/households", tags=["Groups: Households"])
|
||||
|
||||
|
||||
@controller(router)
|
||||
class GroupHouseholdsController(BaseUserController):
|
||||
@router.get("", response_model=PaginationBase[HouseholdSummary])
|
||||
def get_all_households(self, q: PaginationQuery = Depends(PaginationQuery)):
|
||||
response = self.repos.households.page_all(pagination=q, override=HouseholdSummary)
|
||||
|
||||
response.set_pagination_guides(router.url_path_for("get_all_households"), q.model_dump())
|
||||
return response
|
||||
|
||||
@router.get("/{household_slug}", response_model=HouseholdSummary)
|
||||
def get_one_household(self, household_slug: str):
|
||||
household = self.repos.households.get_by_slug_or_id(household_slug)
|
||||
|
||||
if not household:
|
||||
raise HTTPException(status_code=404, detail="Household not found")
|
||||
return household.cast(HouseholdSummary)
|
||||
@@ -1,6 +1,6 @@
|
||||
from functools import cached_property
|
||||
|
||||
from fastapi import HTTPException, Query
|
||||
from fastapi import Query
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.routes._base.base_controllers import BaseUserController
|
||||
@@ -8,9 +8,7 @@ from mealie.routes._base.controller import controller
|
||||
from mealie.routes._base.routers import UserAPIRouter
|
||||
from mealie.schema.group.group_preferences import ReadGroupPreferences, UpdateGroupPreferences
|
||||
from mealie.schema.group.group_statistics import GroupStorage
|
||||
from mealie.schema.household.household import HouseholdSummary
|
||||
from mealie.schema.response.pagination import PaginationQuery
|
||||
from mealie.schema.response.responses import ErrorResponse
|
||||
from mealie.schema.user.user import GroupSummary, UserSummary
|
||||
from mealie.services.group_services.group_service import GroupService
|
||||
|
||||
@@ -36,23 +34,6 @@ class GroupSelfServiceController(BaseUserController):
|
||||
private_users = self.repos.users.page_all(PaginationQuery(page=1, per_page=-1, query_filter=query_filter)).items
|
||||
return [user.cast(UserSummary) for user in private_users]
|
||||
|
||||
@router.get("/households", response_model=list[HouseholdSummary])
|
||||
def get_group_households(self):
|
||||
"""Returns all households belonging to the current group"""
|
||||
|
||||
households = self.repos.households.page_all(PaginationQuery(page=1, per_page=-1)).items
|
||||
return [household.cast(HouseholdSummary) for household in households]
|
||||
|
||||
@router.get("/households/{slug}", response_model=HouseholdSummary)
|
||||
def get_group_household(self, slug: str):
|
||||
"""Returns a single household belonging to the current group"""
|
||||
|
||||
household = self.repos.households.get_by_slug_or_id(slug)
|
||||
if not household:
|
||||
raise HTTPException(status_code=404, detail=ErrorResponse.respond(message="No Entry Found"))
|
||||
|
||||
return household.cast(HouseholdSummary)
|
||||
|
||||
@router.get("/preferences", response_model=ReadGroupPreferences)
|
||||
def get_group_preferences(self):
|
||||
return self.group.preferences
|
||||
|
||||
@@ -320,6 +320,7 @@ class RecipeController(BaseRecipeController):
|
||||
tags: list[UUID4 | str] | None = Query(None),
|
||||
tools: list[UUID4 | str] | None = Query(None),
|
||||
foods: list[UUID4 | str] | None = Query(None),
|
||||
households: list[UUID4 | str] | None = Query(None),
|
||||
):
|
||||
cookbook_data: ReadCookBook | None = None
|
||||
if search_query.cookbook:
|
||||
@@ -345,6 +346,7 @@ class RecipeController(BaseRecipeController):
|
||||
tags=tags,
|
||||
tools=tools,
|
||||
foods=foods,
|
||||
households=households,
|
||||
require_all_categories=search_query.require_all_categories,
|
||||
require_all_tags=search_query.require_all_tags,
|
||||
require_all_tools=search_query.require_all_tools,
|
||||
|
||||
Reference in New Issue
Block a user