fix: error when trying to change recipe image

This commit is contained in:
mariodz95 2025-07-21 16:16:18 +02:00
commit 513c6850e4
4 changed files with 31 additions and 22 deletions

View file

@ -393,8 +393,6 @@ const props = defineProps({
const emit = defineEmits(["click-instruction-field", "update:assets"]); const emit = defineEmits(["click-instruction-field", "update:assets"]);
const BASE_URL = useRequestURL().origin;
const { isCookMode, toggleCookMode, isEditForm } = usePageState(props.recipe.slug); const { isCookMode, toggleCookMode, isEditForm } = usePageState(props.recipe.slug);
const dialog = ref(false); const dialog = ref(false);
@ -699,7 +697,7 @@ async function handleImageDrop(index: number, files: File[]) {
} }
emit("update:assets", [...assets.value, data]); emit("update:assets", [...assets.value, data]);
const assetUrl = BASE_URL + recipeAssetPath(props.recipe.id, data.fileName as string); const assetUrl = recipeAssetPath(props.recipe.id, data.fileName as string);
const text = `<img src="${assetUrl}" height="100%" width="100%"/>`; const text = `<img src="${assetUrl}" height="100%" width="100%"/>`;
instructionList.value[index].text += text; instructionList.value[index].text += text;
} }

View file

@ -83,12 +83,11 @@ class RepositoryGeneric[Schema: MealieModel, Model: SqlAlchemyBase]:
else: else:
return q return q
def _filter_builder(self, **kwargs) -> dict[str, Any]: def _filter_builder(self, skip_household: bool = False, **kwargs) -> dict[str, Any]:
dct = {} dct = {}
if self.group_id: if self.group_id:
dct["group_id"] = self.group_id dct["group_id"] = self.group_id
if self.household_id: if self.household_id and not skip_household:
dct["household_id"] = self.household_id dct["household_id"] = self.household_id
return {**dct, **kwargs} return {**dct, **kwargs}
@ -134,7 +133,9 @@ class RepositoryGeneric[Schema: MealieModel, Model: SqlAlchemyBase]:
result = self.session.execute(q).unique().scalars().all() result = self.session.execute(q).unique().scalars().all()
return [eff_schema.model_validate(x) for x in result] return [eff_schema.model_validate(x) for x in result]
def _query_one(self, match_value: str | int | UUID4, match_key: str | None = None) -> Model: def _query_one(
self, match_value: str | int | UUID4, match_key: str | None = None, skip_household: bool = False
) -> Model:
""" """
Query the sql database for one item an return the sql alchemy model Query the sql database for one item an return the sql alchemy model
object. If no match key is provided the primary_key attribute will be used. object. If no match key is provided the primary_key attribute will be used.
@ -142,11 +143,16 @@ class RepositoryGeneric[Schema: MealieModel, Model: SqlAlchemyBase]:
if match_key is None: if match_key is None:
match_key = self.primary_key match_key = self.primary_key
fltr = self._filter_builder(**{match_key: match_value}) fltr = self._filter_builder(**{match_key: match_value}, skip_household=skip_household)
return self.session.execute(self._query().filter_by(**fltr)).unique().scalars().one() return self.session.execute(self._query().filter_by(**fltr)).unique().scalars().one()
def get_one( def get_one(
self, value: str | int | UUID4, key: str | None = None, any_case=False, override_schema=None self,
value: str | int | UUID4,
key: str | None = None,
any_case=False,
override_schema=None,
skip_household: str = False,
) -> Schema | None: ) -> Schema | None:
key = key or self.primary_key key = key or self.primary_key
eff_schema = override_schema or self.schema eff_schema = override_schema or self.schema
@ -155,9 +161,11 @@ class RepositoryGeneric[Schema: MealieModel, Model: SqlAlchemyBase]:
if any_case: if any_case:
search_attr = getattr(self.model, key) search_attr = getattr(self.model, key)
q = q.where(func.lower(search_attr) == str(value).lower()).filter_by(**self._filter_builder()) q = q.where(func.lower(search_attr) == str(value).lower()).filter_by(
**self._filter_builder(skip_household=skip_household)
)
else: else:
q = q.filter_by(**self._filter_builder(**{key: value})) q = q.filter_by(**self._filter_builder(**{key: value}, skip_household=skip_household))
result = self.session.execute(q).unique().scalars().one_or_none() result = self.session.execute(q).unique().scalars().one_or_none()
@ -195,7 +203,9 @@ class RepositoryGeneric[Schema: MealieModel, Model: SqlAlchemyBase]:
return [self.schema.model_validate(x) for x in new_documents] return [self.schema.model_validate(x) for x in new_documents]
def update(self, match_value: str | int | UUID4, new_data: dict | BaseModel) -> Schema: def update(
self, match_value: str | int | UUID4, new_data: dict | BaseModel, skip_household: bool = False
) -> Schema:
"""Update a database entry. """Update a database entry.
Args: Args:
session (Session): Database Session session (Session): Database Session
@ -207,7 +217,7 @@ class RepositoryGeneric[Schema: MealieModel, Model: SqlAlchemyBase]:
""" """
new_data = new_data if isinstance(new_data, dict) else new_data.model_dump() new_data = new_data if isinstance(new_data, dict) else new_data.model_dump()
entry = self._query_one(match_value=match_value) entry = self._query_one(match_value=match_value, skip_household=skip_household)
entry.update(session=self.session, **new_data) entry.update(session=self.session, **new_data)
self.session.commit() self.session.commit()

View file

@ -73,8 +73,8 @@ class HttpRepo[C: BaseModel, R: BaseModel, U: BaseModel]:
return item return item
def get_one(self, item_id: int | str | UUID4, key: str | None = None) -> R: def get_one(self, item_id: int | str | UUID4, key: str | None = None, skip_household: bool = False) -> R:
item = self.repo.get_one(item_id, key) item = self.repo.get_one(item_id, key, skip_household=skip_household)
if not item: if not item:
raise HTTPException( raise HTTPException(
@ -84,8 +84,8 @@ class HttpRepo[C: BaseModel, R: BaseModel, U: BaseModel]:
return item return item
def update_one(self, data: U, item_id: int | str | UUID4) -> R: def update_one(self, data: U, item_id: int | str | UUID4, skip_household: bool = False) -> R:
item = self.repo.get_one(item_id) item = self.repo.get_one(item_id, skip_household=skip_household)
if not item: if not item:
raise HTTPException( raise HTTPException(
@ -94,7 +94,7 @@ class HttpRepo[C: BaseModel, R: BaseModel, U: BaseModel]:
) )
try: try:
item = self.repo.update(item_id, data) # type: ignore item = self.repo.update(item_id, data, skip_household=skip_household) # type: ignore
except Exception as ex: except Exception as ex:
self.handle_exception(ex) self.handle_exception(ex)

View file

@ -523,7 +523,7 @@ class RecipeController(BaseRecipeController):
@router.put("/{slug}/image", response_model=UpdateImageResponse, tags=["Recipe: Images and Assets"]) @router.put("/{slug}/image", response_model=UpdateImageResponse, tags=["Recipe: Images and Assets"])
def update_recipe_image(self, slug: str, image: bytes = File(...), extension: str = Form(...)): def update_recipe_image(self, slug: str, image: bytes = File(...), extension: str = Form(...)):
recipe = self.mixins.get_one(slug) recipe = self.mixins.get_one(slug, skip_household=True)
data_service = RecipeDataService(recipe.id) data_service = RecipeDataService(recipe.id)
data_service.write_image(image, extension) data_service.write_image(image, extension)
@ -540,6 +540,7 @@ class RecipeController(BaseRecipeController):
file: UploadFile = File(...), file: UploadFile = File(...),
): ):
"""Upload a file to store as a recipe asset""" """Upload a file to store as a recipe asset"""
skip_household = True
if "." in extension: if "." in extension:
extension = extension.split(".")[-1] extension = extension.split(".")[-1]
@ -550,7 +551,7 @@ class RecipeController(BaseRecipeController):
file_name = f"{file_slug}.{extension}" file_name = f"{file_slug}.{extension}"
asset_in = RecipeAsset(name=name, icon=icon, file_name=file_name) asset_in = RecipeAsset(name=name, icon=icon, file_name=file_name)
recipe = self.mixins.get_one(slug) recipe = self.mixins.get_one(slug, skip_household=skip_household)
dest = recipe.asset_dir / file_name dest = recipe.asset_dir / file_name
@ -567,9 +568,9 @@ class RecipeController(BaseRecipeController):
if not dest.is_file(): if not dest.is_file():
raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR) raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR)
recipe = self.mixins.get_one(slug) recipe = self.mixins.get_one(slug, skip_household=skip_household)
recipe.assets.append(asset_in) recipe.assets.append(asset_in)
self.mixins.update_one(recipe, slug) self.mixins.update_one(recipe, slug, skip_household=skip_household)
return asset_in return asset_in