mirror of
				https://github.com/mealie-recipes/mealie.git
				synced 2025-10-27 08:14:30 -04:00 
			
		
		
		
	Bug/error relating units foods (#987)
* fix type guard * update typing * rearrange methods * spelling * fix unknown error response * update type check for none types * add discord notification
This commit is contained in:
		
							
								
								
									
										9
									
								
								.github/workflows/backend-docker-nightly.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.github/workflows/backend-docker-nightly.yml
									
									
									
									
										vendored
									
									
								
							| @@ -47,3 +47,12 @@ jobs: | ||||
|           docker build --push --no-cache \ | ||||
|             --tag hkotel/mealie:api-nightly \ | ||||
|             --platform linux/amd64,linux/arm64 . | ||||
|       # | ||||
|       # Build Discord Notification | ||||
|       # | ||||
|       - name: Discord notification | ||||
|         env: | ||||
|           DISCORD_WEBHOOK: ${{ secrets.DISCORD_NIGHTLY_WEBHOOK }} | ||||
|         uses: Ilshidur/action-discord@0.3.2 | ||||
|         with: | ||||
|           args: "🚀  A New Nighlty Build of Mealie is ready" | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| from functools import wraps | ||||
| from uuid import UUID | ||||
|  | ||||
| from pydantic import BaseModel, Field | ||||
| from sqlalchemy.orm import MANYTOMANY, MANYTOONE, ONETOMANY, Session | ||||
| @@ -170,9 +171,13 @@ def auto_init():  # sourcery no-metrics | ||||
|                             if val is None: | ||||
|                                 raise ValueError(f"Expected 'id' to be provided for {key}") | ||||
|  | ||||
|                         if isinstance(val, (str, int)): | ||||
|                         if isinstance(val, (str, int, UUID)): | ||||
|                             instance = session.query(relation_cls).filter_by(**{get_attr: val}).one_or_none() | ||||
|                             setattr(self, key, instance) | ||||
|                         else: | ||||
|                             # If the value is not of the type defined above we assume that it isn't a valid id | ||||
|                             # and try a different approach. | ||||
|                             pass | ||||
|  | ||||
|                     elif relation_dir == MANYTOMANY: | ||||
|                         instances = handle_many_to_many(session, get_attr, relation_cls, val) | ||||
|   | ||||
| @@ -142,7 +142,7 @@ class RecipeModel(SqlAlchemyBase, BaseMixins): | ||||
|         assets: list = None, | ||||
|         notes: list[dict] = None, | ||||
|         nutrition: dict = None, | ||||
|         recipe_ingredient: list[str] = None, | ||||
|         recipe_ingredient: list[dict] = None, | ||||
|         settings: dict = None, | ||||
|         **_, | ||||
|     ) -> None: | ||||
|   | ||||
| @@ -117,6 +117,25 @@ router = UserAPIRouter(prefix="/recipes", tags=["Recipe: CRUD"]) | ||||
|  | ||||
| @controller(router) | ||||
| class RecipeController(BaseRecipeController): | ||||
|     def handle_exceptions(self, ex: Exception) -> None: | ||||
|         match type(ex): | ||||
|             case exceptions.PermissionDenied: | ||||
|                 self.deps.logger.error("Permission Denied on recipe controller action") | ||||
|                 raise HTTPException(status_code=403, detail=ErrorResponse.respond(message="Permission Denied")) | ||||
|             case exceptions.NoEntryFound: | ||||
|                 self.deps.logger.error("No Entry Found on recipe controller action") | ||||
|                 raise HTTPException(status_code=404, detail=ErrorResponse.respond(message="No Entry Found")) | ||||
|             case sqlalchemy.exc.IntegrityError: | ||||
|                 self.deps.logger.error("SQL Integrity Error on recipe controller action") | ||||
|                 raise HTTPException(status_code=400, detail=ErrorResponse.respond(message="Recipe already exists")) | ||||
|  | ||||
|             case _: | ||||
|                 self.deps.logger.error("Unknown Error on recipe controller action") | ||||
|                 self.deps.logger.exception(ex) | ||||
|                 raise HTTPException( | ||||
|                     status_code=500, detail=ErrorResponse.respond(message="Unknown Error", exception=str(ex)) | ||||
|                 ) | ||||
|  | ||||
|     # ======================================================================= | ||||
|     # URL Scraping Operations | ||||
|  | ||||
| @@ -212,24 +231,6 @@ class RecipeController(BaseRecipeController): | ||||
|         except Exception as e: | ||||
|             self.handle_exceptions(e) | ||||
|  | ||||
|     def handle_exceptions(self, ex: Exception) -> None: | ||||
|         match type(ex): | ||||
|             case exceptions.PermissionDenied: | ||||
|                 self.deps.logger.error("Permission Denied on recipe controller action") | ||||
|                 raise HTTPException(status_code=403, detail=ErrorResponse.respond(message="Permission Denied")) | ||||
|             case exceptions.NoEntryFound: | ||||
|                 self.deps.logger.error("No Entry Found on recipe controller action") | ||||
|                 raise HTTPException(status_code=404, detail=ErrorResponse.respond(message="No Entry Found")) | ||||
|             case sqlalchemy.exc.IntegrityError: | ||||
|                 self.deps.logger.error("SQL Integrity Error on recipe controller action") | ||||
|                 raise HTTPException(status_code=400, detail=ErrorResponse.respond(message="Recipe already exists")) | ||||
|  | ||||
|             case _: | ||||
|                 self.deps.logger.error("Unknown Error on recipe controller action") | ||||
|                 raise HTTPException( | ||||
|                     status_code=500, detail=ErrorResponse.respond(message="Unknown Error", exception=ex) | ||||
|                 ) | ||||
|  | ||||
|     @router.put("/{slug}") | ||||
|     def update_one(self, slug: str, data: Recipe): | ||||
|         """Updates a recipe by existing slug and data.""" | ||||
|   | ||||
| @@ -25,7 +25,7 @@ step_text = """Recipe steps as well as other fields in the recipe page support m | ||||
|  | ||||
| [My Link](https://beta.mealie.io) | ||||
|  | ||||
| **Imbed an image** | ||||
| **Embed an image** | ||||
|  | ||||
| Use the `height="100"` or `width="100"` attributes to set the size of the image. | ||||
|  | ||||
| @@ -158,6 +158,7 @@ class RecipeService(BaseService): | ||||
|  | ||||
|     def update_one(self, slug: str, update_data: Recipe) -> Recipe: | ||||
|         recipe = self._pre_update_check(slug, update_data) | ||||
|  | ||||
|         new_data = self.repos.recipes.update(slug, update_data) | ||||
|         self.check_assets(new_data, recipe.slug) | ||||
|         return new_data | ||||
| @@ -165,6 +166,7 @@ class RecipeService(BaseService): | ||||
|     def patch_one(self, slug: str, patch_data: Recipe) -> Recipe: | ||||
|         recipe = self._pre_update_check(slug, patch_data) | ||||
|         recipe = self.repos.recipes.by_group(self.group.id).get_one(slug) | ||||
|  | ||||
|         new_data = self.repos.recipes.patch(recipe.slug, patch_data) | ||||
|  | ||||
|         self.check_assets(new_data, recipe.slug) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user