2021-08-22 16:08:37 -08:00
|
|
|
from random import randint
|
2021-10-02 22:07:29 -08:00
|
|
|
from typing import Any
|
2022-02-07 19:03:11 -09:00
|
|
|
from uuid import UUID
|
2021-10-02 22:07:29 -08:00
|
|
|
|
2022-02-07 19:03:11 -09:00
|
|
|
from sqlalchemy import and_, func
|
2021-10-02 22:07:29 -08:00
|
|
|
from sqlalchemy.orm import joinedload
|
2021-08-22 16:08:37 -08:00
|
|
|
|
2022-02-07 19:03:11 -09:00
|
|
|
from mealie.db.models.recipe.category import Category
|
2021-11-08 21:12:13 -09:00
|
|
|
from mealie.db.models.recipe.ingredient import RecipeIngredient
|
2021-08-22 16:08:37 -08:00
|
|
|
from mealie.db.models.recipe.recipe import RecipeModel
|
|
|
|
from mealie.db.models.recipe.settings import RecipeSettings
|
2022-02-07 19:03:11 -09:00
|
|
|
from mealie.db.models.recipe.tag import Tag
|
2021-08-27 20:27:20 -08:00
|
|
|
from mealie.schema.recipe import Recipe
|
2022-02-07 19:03:11 -09:00
|
|
|
from mealie.schema.recipe.recipe import RecipeCategory, RecipeTag
|
2021-08-22 16:08:37 -08:00
|
|
|
|
2021-12-18 20:52:36 -09:00
|
|
|
from .repository_generic import RepositoryGeneric
|
2021-08-22 16:08:37 -08:00
|
|
|
|
|
|
|
|
2021-12-18 20:52:36 -09:00
|
|
|
class RepositoryRecipes(RepositoryGeneric[Recipe, RecipeModel]):
|
2022-02-07 19:03:11 -09:00
|
|
|
def by_group(self, group_id: UUID) -> "RepositoryRecipes":
|
|
|
|
return super().by_group(group_id)
|
|
|
|
|
2021-09-19 15:31:34 -08:00
|
|
|
def get_all_public(self, limit: int = None, order_by: str = None, start=0, override_schema=None):
|
2021-08-22 16:08:37 -08:00
|
|
|
eff_schema = override_schema or self.schema
|
|
|
|
|
|
|
|
if order_by:
|
|
|
|
order_attr = getattr(self.sql_model, str(order_by))
|
|
|
|
|
|
|
|
return [
|
|
|
|
eff_schema.from_orm(x)
|
2021-09-19 15:31:34 -08:00
|
|
|
for x in self.session.query(self.sql_model)
|
2021-08-22 16:08:37 -08:00
|
|
|
.join(RecipeSettings)
|
|
|
|
.filter(RecipeSettings.public == True) # noqa: 711
|
|
|
|
.order_by(order_attr.desc())
|
|
|
|
.offset(start)
|
|
|
|
.limit(limit)
|
|
|
|
.all()
|
|
|
|
]
|
|
|
|
|
|
|
|
return [
|
|
|
|
eff_schema.from_orm(x)
|
2021-09-19 15:31:34 -08:00
|
|
|
for x in self.session.query(self.sql_model)
|
2021-08-22 16:08:37 -08:00
|
|
|
.join(RecipeSettings)
|
|
|
|
.filter(RecipeSettings.public == True) # noqa: 711
|
|
|
|
.offset(start)
|
|
|
|
.limit(limit)
|
|
|
|
.all()
|
|
|
|
]
|
|
|
|
|
2021-09-19 15:31:34 -08:00
|
|
|
def update_image(self, slug: str, _: str = None) -> str:
|
|
|
|
entry: RecipeModel = self._query_one(match_value=slug)
|
2021-08-22 16:08:37 -08:00
|
|
|
entry.image = randint(0, 255)
|
2021-09-19 15:31:34 -08:00
|
|
|
self.session.commit()
|
2021-08-22 16:08:37 -08:00
|
|
|
|
|
|
|
return entry.image
|
|
|
|
|
2021-09-19 15:31:34 -08:00
|
|
|
def count_uncategorized(self, count=True, override_schema=None) -> int:
|
2021-08-22 16:08:37 -08:00
|
|
|
return self._count_attribute(
|
|
|
|
attribute_name=RecipeModel.recipe_category,
|
|
|
|
attr_match=None,
|
|
|
|
count=count,
|
|
|
|
override_schema=override_schema,
|
|
|
|
)
|
|
|
|
|
2021-09-19 15:31:34 -08:00
|
|
|
def count_untagged(self, count=True, override_schema=None) -> int:
|
2021-08-22 16:08:37 -08:00
|
|
|
return self._count_attribute(
|
2021-09-19 15:31:34 -08:00
|
|
|
attribute_name=RecipeModel.tags,
|
|
|
|
attr_match=None,
|
|
|
|
count=count,
|
|
|
|
override_schema=override_schema,
|
2021-08-22 16:08:37 -08:00
|
|
|
)
|
2021-10-02 22:07:29 -08:00
|
|
|
|
2021-12-04 14:18:46 -09:00
|
|
|
def summary(self, group_id, start=0, limit=99999, load_foods=False) -> Any:
|
|
|
|
args = [
|
|
|
|
joinedload(RecipeModel.recipe_category),
|
|
|
|
joinedload(RecipeModel.tags),
|
|
|
|
joinedload(RecipeModel.tools),
|
|
|
|
]
|
|
|
|
|
|
|
|
if load_foods:
|
|
|
|
args.append(joinedload(RecipeModel.recipe_ingredient).options(joinedload(RecipeIngredient.food)))
|
|
|
|
|
2021-10-02 22:07:29 -08:00
|
|
|
return (
|
|
|
|
self.session.query(RecipeModel)
|
2021-12-04 14:18:46 -09:00
|
|
|
.options(*args)
|
2021-10-02 22:07:29 -08:00
|
|
|
.filter(RecipeModel.group_id == group_id)
|
|
|
|
.offset(start)
|
|
|
|
.limit(limit)
|
|
|
|
.all()
|
|
|
|
)
|
2022-02-07 19:03:11 -09:00
|
|
|
|
|
|
|
def get_by_categories(self, categories: list[RecipeCategory]) -> list[Recipe]:
|
|
|
|
"""
|
|
|
|
get_by_categories returns all the Recipes that contain every category provided in the list
|
|
|
|
"""
|
|
|
|
|
|
|
|
ids = [x.id for x in categories]
|
|
|
|
|
|
|
|
return [
|
|
|
|
self.schema.from_orm(x)
|
|
|
|
for x in self.session.query(RecipeModel)
|
|
|
|
.join(RecipeModel.recipe_category)
|
|
|
|
.filter(RecipeModel.recipe_category.any(Category.id.in_(ids)))
|
|
|
|
.all()
|
|
|
|
]
|
|
|
|
|
|
|
|
def get_random_by_categories_and_tags(self, categories: list[RecipeCategory], tags: list[RecipeTag]) -> Recipe:
|
|
|
|
"""
|
|
|
|
get_random_by_categories returns a single random Recipe that contains every category provided
|
|
|
|
in the list. This uses a function built in to Postgres and SQLite to get a random row limited
|
|
|
|
to 1 entry.
|
|
|
|
"""
|
|
|
|
|
|
|
|
# See Also:
|
|
|
|
# - https://stackoverflow.com/questions/60805/getting-random-row-through-sqlalchemy
|
|
|
|
|
|
|
|
filters = [
|
|
|
|
RecipeModel.group_id == self.group_id,
|
|
|
|
]
|
|
|
|
|
|
|
|
if categories:
|
|
|
|
cat_ids = [x.id for x in categories]
|
|
|
|
for cat_id in cat_ids:
|
|
|
|
filters.append(RecipeModel.recipe_category.any(Category.id.is_(cat_id)))
|
|
|
|
|
|
|
|
if tags:
|
|
|
|
tag_ids = [x.id for x in tags]
|
|
|
|
for tag_id in tag_ids:
|
|
|
|
filters.append(RecipeModel.tags.any(Tag.id.is_(tag_id)))
|
|
|
|
|
|
|
|
return [
|
|
|
|
self.schema.from_orm(x)
|
|
|
|
for x in self.session.query(RecipeModel)
|
|
|
|
.filter(and_(*filters))
|
|
|
|
.order_by(func.random()) # Postgres and SQLite specific
|
|
|
|
.limit(1)
|
|
|
|
]
|
|
|
|
|
|
|
|
def get_random(self, limit=1) -> list[Recipe]:
|
|
|
|
return [
|
|
|
|
self.schema.from_orm(x)
|
|
|
|
for x in self.session.query(RecipeModel)
|
|
|
|
.filter(RecipeModel.group_id == self.group_id)
|
|
|
|
.order_by(func.random()) # Postgres and SQLite specific
|
|
|
|
.limit(limit)
|
|
|
|
]
|