Merge branch 'mealie-next' into feat/filter-shopping-lists

This commit is contained in:
Michael Genson
2024-03-06 09:11:58 -06:00
committed by GitHub
11 changed files with 278 additions and 176 deletions

View File

@@ -35,12 +35,10 @@ class Group(SqlAlchemyBase, BaseMixins):
name: Mapped[str] = mapped_column(sa.String, index=True, nullable=False, unique=True)
slug: Mapped[str | None] = mapped_column(sa.String, index=True, unique=True)
users: Mapped[list["User"]] = orm.relationship("User", back_populates="group")
categories: Mapped[Category] = orm.relationship(
Category, secondary=group_to_categories, single_parent=True, uselist=True
)
categories: Mapped[list[Category]] = orm.relationship(Category, secondary=group_to_categories, single_parent=True)
invite_tokens: Mapped[list[GroupInviteToken]] = orm.relationship(
GroupInviteToken, back_populates="group", cascade="all, delete-orphan", uselist=True
GroupInviteToken, back_populates="group", cascade="all, delete-orphan"
)
preferences: Mapped[GroupPreferencesModel] = orm.relationship(
GroupPreferencesModel,
@@ -51,7 +49,7 @@ class Group(SqlAlchemyBase, BaseMixins):
)
# Recipes
recipes: Mapped[list["RecipeModel"]] = orm.relationship("RecipeModel", back_populates="group", uselist=True)
recipes: Mapped[list["RecipeModel"]] = orm.relationship("RecipeModel", back_populates="group")
# CRUD From Others
common_args = {

View File

@@ -30,8 +30,8 @@ class GroupMealPlanRules(BaseMixins, SqlAlchemyBase):
String, nullable=False, default=""
) # "breakfast", "lunch", "dinner", "side"
categories: Mapped[Category] = orm.relationship(Category, secondary=plan_rules_to_categories, uselist=True)
tags: Mapped[list[Tag]] = orm.relationship(Tag, secondary=plan_rules_to_tags, uselist=True)
categories: Mapped[list[Category]] = orm.relationship(Category, secondary=plan_rules_to_categories)
tags: Mapped[list[Tag]] = orm.relationship(Tag, secondary=plan_rules_to_tags)
@auto_init()
def __init__(self, **_) -> None:

View File

@@ -127,14 +127,14 @@ class ShoppingList(SqlAlchemyBase, BaseMixins):
user: Mapped["User"] = orm.relationship("User", back_populates="shopping_lists")
name: Mapped[str | None] = mapped_column(String)
list_items: Mapped[ShoppingListItem] = orm.relationship(
list_items: Mapped[list[ShoppingListItem]] = orm.relationship(
ShoppingListItem,
cascade="all, delete, delete-orphan",
order_by="ShoppingListItem.position",
collection_class=ordering_list("position"),
)
recipe_references: Mapped[ShoppingListRecipeReference] = orm.relationship(
recipe_references: Mapped[list[ShoppingListRecipeReference]] = orm.relationship(
ShoppingListRecipeReference, cascade="all, delete, delete-orphan"
)
label_settings: Mapped[list["ShoppingListMultiPurposeLabel"]] = orm.relationship(

View File

@@ -49,7 +49,7 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
user_id: Mapped[GUID | None] = mapped_column(GUID, sa.ForeignKey("users.id", use_alter=True), index=True)
user: Mapped["User"] = orm.relationship("User", uselist=False, foreign_keys=[user_id])
meal_entries: Mapped["GroupMealPlan"] = orm.relationship(
meal_entries: Mapped[list["GroupMealPlan"]] = orm.relationship(
"GroupMealPlan", back_populates="recipe", cascade="all, delete-orphan"
)
@@ -72,7 +72,7 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
recipe_yield: Mapped[str | None] = mapped_column(sa.String)
recipeCuisine: Mapped[str | None] = mapped_column(sa.String)
assets: Mapped[RecipeAsset] = orm.relationship("RecipeAsset", cascade="all, delete-orphan")
assets: Mapped[list[RecipeAsset]] = orm.relationship("RecipeAsset", cascade="all, delete-orphan")
nutrition: Mapped[Nutrition] = orm.relationship("Nutrition", uselist=False, cascade="all, delete-orphan")
recipe_category: Mapped[list["Category"]] = orm.relationship(
"Category", secondary=recipes_to_categories, back_populates="recipes"

View File

@@ -226,10 +226,14 @@ class ShoppingListUpdate(ShoppingListSave):
class ShoppingListOut(ShoppingListUpdate):
recipe_references: list[ShoppingListRecipeRefOut]
label_settings: list[ShoppingListMultiPurposeLabelOut]
recipe_references: list[ShoppingListRecipeRefOut] = []
label_settings: list[ShoppingListMultiPurposeLabelOut] = []
model_config = ConfigDict(from_attributes=True)
@field_validator("recipe_references", "label_settings", mode="before")
def default_none_to_empty_list(cls, v):
return v or []
@classmethod
def loader_options(cls) -> list[LoaderOption]:
return [

View File

@@ -14,6 +14,7 @@ from mealie.schema.reports.reports import (
ReportCategory,
ReportCreate,
ReportEntryCreate,
ReportEntryOut,
ReportOut,
ReportSummary,
ReportSummaryStatus,
@@ -91,6 +92,7 @@ class BaseMigrator(BaseService):
is_success = True
is_failure = True
new_entries: list[ReportEntryOut] = []
for entry in self.report_entries:
if is_failure and entry.success:
is_failure = False
@@ -98,7 +100,7 @@ class BaseMigrator(BaseService):
if is_success and not entry.success:
is_success = False
self.db.group_report_entries.create(entry)
new_entries.append(self.db.group_report_entries.create(entry))
if is_success:
self.report.status = ReportSummaryStatus.success
@@ -109,6 +111,7 @@ class BaseMigrator(BaseService):
if not is_success and not is_failure:
self.report.status = ReportSummaryStatus.partial
self.report.entries = new_entries
self.db.group_reports.update(self.report.id, self.report)
def migrate(self, report_name: str) -> ReportSummary:

View File

@@ -5,6 +5,7 @@ import zipfile
from pathlib import Path
from mealie.schema.recipe.recipe import Recipe
from mealie.schema.reports.reports import ReportEntryCreate
from ._migration_base import BaseMigrator
from .utils.migration_alias import MigrationAlias
@@ -55,20 +56,28 @@ class MealieAlphaMigrator(BaseMigrator):
zip_file.extractall(tmpdir)
temp_path = Path(tmpdir)
recipe_lookup: dict[str, Path] = {}
recipes_as_dicts = []
for x in temp_path.rglob("**/recipes/**/[!.]*.json"):
if (y := MigrationReaders.json(x)) is not None:
recipes_as_dicts.append(y)
slug = y["slug"]
recipe_lookup[slug] = x.parent
recipes = [self._convert_to_new_schema(x) for x in recipes_as_dicts]
recipes: list[Recipe] = []
for recipe_json_path in temp_path.rglob("**/recipes/**/[!.]*.json"):
try:
if (recipe_as_dict := MigrationReaders.json(recipe_json_path)) is not None:
recipe = self._convert_to_new_schema(recipe_as_dict)
recipes.append(recipe)
slug = recipe_as_dict["slug"]
recipe_lookup[slug] = recipe_json_path.parent
except Exception as e:
self.logger.exception(e)
self.report_entries.append(
ReportEntryCreate(
report_id=self.report_id,
success=False,
message=f"Failed to import {recipe_json_path.name}",
exception=f"{e.__class__.__name__}: {e}",
)
)
results = self.import_recipes_to_database(recipes)
for slug, recipe_id, status in results:
if not status:
continue