feat: Recipe Finder (aka Cocktail Builder) (#4542)

This commit is contained in:
Michael Genson
2024-12-03 07:27:41 -06:00
committed by GitHub
parent d26e29d1c5
commit 4e0cf985bc
28 changed files with 1959 additions and 151 deletions

View File

@@ -16,7 +16,13 @@ from sqlalchemy.sql import sqltypes
from mealie.core.root_logger import get_logger
from mealie.db.models._model_base import SqlAlchemyBase
from mealie.schema._mealie import MealieModel
from mealie.schema.response.pagination import OrderByNullPosition, OrderDirection, PaginationBase, PaginationQuery
from mealie.schema.response.pagination import (
OrderByNullPosition,
OrderDirection,
PaginationBase,
PaginationQuery,
RequestQuery,
)
from mealie.schema.response.query_filter import QueryFilterBuilder
from mealie.schema.response.query_search import SearchFilter
@@ -404,11 +410,11 @@ class RepositoryGeneric(Generic[Schema, Model]):
return query.order_by(order_attr)
def add_order_by_to_query(self, query: Select, pagination: PaginationQuery) -> Select:
if not pagination.order_by:
def add_order_by_to_query(self, query: Select, request_query: RequestQuery) -> Select:
if not request_query.order_by:
return query
elif pagination.order_by == "random":
elif request_query.order_by == "random":
# randomize outside of database, since not all db's can set random seeds
# this solution is db-independent & stable to paging
temp_query = query.with_only_columns(self.model.id)
@@ -417,14 +423,14 @@ class RepositoryGeneric(Generic[Schema, Model]):
return query
order = list(range(len(allids)))
random.seed(pagination.pagination_seed)
random.seed(request_query.pagination_seed)
random.shuffle(order)
random_dict = dict(zip(allids, order, strict=True))
case_stmt = case(random_dict, value=self.model.id)
return query.order_by(case_stmt)
else:
for order_by_val in pagination.order_by.split(","):
for order_by_val in request_query.order_by.split(","):
try:
order_by_val = order_by_val.strip()
if ":" in order_by_val:
@@ -432,20 +438,20 @@ class RepositoryGeneric(Generic[Schema, Model]):
order_dir = OrderDirection(order_dir_val)
else:
order_by = order_by_val
order_dir = pagination.order_direction
order_dir = request_query.order_direction
_, order_attr, query = QueryFilterBuilder.get_model_and_model_attr_from_attr_string(
order_by, self.model, query=query
)
query = self.add_order_attr_to_query(
query, order_attr, order_dir, pagination.order_by_null_position
query, order_attr, order_dir, request_query.order_by_null_position
)
except ValueError as e:
raise HTTPException(
status_code=400,
detail=f'Invalid order_by statement "{pagination.order_by}": "{order_by_val}" is invalid',
detail=f'Invalid order_by statement "{request_query.order_by}": "{order_by_val}" is invalid',
) from e
return query