fix: strict optional errors (#1759)

* fix strict optional errors

* fix typing in repository

* fix backup db files location

* update workspace settings
This commit is contained in:
Hayden
2022-10-23 13:04:04 -08:00
committed by GitHub
parent 97d9e2a109
commit 84c23765cd
31 changed files with 253 additions and 139 deletions

View File

@@ -1,5 +1,6 @@
from pathlib import Path
from mealie.core.exceptions import UnexpectedNone
from mealie.repos.repository_factory import AllRepositories
from mealie.schema.group.group_exports import GroupDataExport
from mealie.schema.recipe import CategoryBase
@@ -41,6 +42,9 @@ class RecipeBulkActionsService(BaseService):
group = self.repos.groups.get_one(self.group.id)
if group is None:
raise UnexpectedNone("Failed to purge exports for group, no group found")
for match in group.directory.glob("**/export/*zip"):
if match.is_file():
match.unlink()
@@ -52,8 +56,8 @@ class RecipeBulkActionsService(BaseService):
for slug in recipes:
recipe = self.repos.recipes.get_one(slug)
if recipe is None:
self.logger.error(f"Failed to set settings for recipe {slug}, no recipe found")
if recipe is None or recipe.settings is None:
raise UnexpectedNone(f"Failed to set settings for recipe {slug}, no recipe found")
settings.locked = recipe.settings.locked
recipe.settings = settings
@@ -69,9 +73,12 @@ class RecipeBulkActionsService(BaseService):
recipe = self.repos.recipes.get_one(slug)
if recipe is None:
self.logger.error(f"Failed to tag recipe {slug}, no recipe found")
raise UnexpectedNone(f"Failed to tag recipe {slug}, no recipe found")
recipe.tags += tags
if recipe.tags is None:
recipe.tags = []
recipe.tags += tags # type: ignore
try:
self.repos.recipes.update(slug, recipe)
@@ -84,9 +91,12 @@ class RecipeBulkActionsService(BaseService):
recipe = self.repos.recipes.get_one(slug)
if recipe is None:
self.logger.error(f"Failed to categorize recipe {slug}, no recipe found")
raise UnexpectedNone(f"Failed to categorize recipe {slug}, no recipe found")
recipe.recipe_category += categories
if recipe.recipe_category is None:
recipe.recipe_category = []
recipe.recipe_category += categories # type: ignore
try:
self.repos.recipes.update(slug, recipe)

View File

@@ -50,6 +50,8 @@ class RecipeService(BaseService):
return recipe
def can_update(self, recipe: Recipe) -> bool:
if recipe.settings is None:
raise exceptions.UnexpectedNone("Recipe Settings is None")
return recipe.settings.locked is False or self.user.id == recipe.user_id
def can_lock_unlock(self, recipe: Recipe) -> bool:
@@ -66,6 +68,9 @@ class RecipeService(BaseService):
except FileNotFoundError:
self.logger.error(f"Recipe Directory not Found: {original_slug}")
if recipe.assets is None:
recipe.assets = []
all_asset_files = [x.file_name for x in recipe.assets]
for file in recipe.asset_dir.iterdir():
@@ -92,7 +97,7 @@ class RecipeService(BaseService):
additional_attrs["group_id"] = user.group_id
if additional_attrs.get("tags"):
for i in range(len(additional_attrs.get("tags"))):
for i in range(len(additional_attrs.get("tags", []))):
additional_attrs["tags"][i]["group_id"] = user.group_id
if not additional_attrs.get("recipe_ingredient"):
@@ -105,6 +110,9 @@ class RecipeService(BaseService):
def create_one(self, create_data: Union[Recipe, CreateRecipe]) -> Recipe:
if create_data.name is None:
create_data.name = "New Recipe"
data: Recipe = self._recipe_creation_factory(
self.user,
name=create_data.name,
@@ -134,8 +142,8 @@ class RecipeService(BaseService):
with temp_path.open("wb") as buffer:
shutil.copyfileobj(archive.file, buffer)
recipe_dict = None
recipe_image = None
recipe_dict: dict | None = None
recipe_image: bytes | None = None
with ZipFile(temp_path) as myzip:
for file in myzip.namelist():
@@ -146,10 +154,15 @@ class RecipeService(BaseService):
with myzip.open(file) as myfile:
recipe_image = myfile.read()
if recipe_dict is None:
raise exceptions.UnexpectedNone("No json data found in Zip")
recipe = self.create_one(Recipe(**recipe_dict))
if recipe:
if recipe and recipe.id:
data_service = RecipeDataService(recipe.id)
if recipe_image:
data_service.write_image(recipe_image, "webp")
return recipe
@@ -172,6 +185,10 @@ class RecipeService(BaseService):
"""
recipe = self._get_recipe(slug)
if recipe is None or recipe.settings is None:
raise exceptions.NoEntryFound("Recipe not found.")
if not self.can_update(recipe):
raise exceptions.PermissionDenied("You do not have permission to edit this recipe.")
@@ -189,9 +206,12 @@ class RecipeService(BaseService):
return new_data
def patch_one(self, slug: str, patch_data: Recipe) -> Recipe:
recipe = self._pre_update_check(slug, patch_data)
recipe: Recipe | None = self._pre_update_check(slug, patch_data)
recipe = self.repos.recipes.by_group(self.group.id).get_one(slug)
if recipe is None:
raise exceptions.NoEntryFound("Recipe not found.")
new_data = self.repos.recipes.by_group(self.group.id).patch(recipe.slug, patch_data.dict(exclude_unset=True))
self.check_assets(new_data, recipe.slug)
@@ -210,6 +230,6 @@ class RecipeService(BaseService):
# =================================================================
# Recipe Template Methods
def render_template(self, recipe: Recipe, temp_dir: Path, template: str = None) -> Path:
def render_template(self, recipe: Recipe, temp_dir: Path, template: str) -> Path:
t_service = TemplateService(temp_dir)
return t_service.render(recipe, template)

View File

@@ -16,7 +16,7 @@ class TemplateType(str, enum.Enum):
class TemplateService(BaseService):
def __init__(self, temp: Path = None) -> None:
def __init__(self, temp: Path | None = None) -> None:
"""Creates a template service that can be used for multiple template generations
A temporary directory must be provided as a place holder for where to render all templates
Args:
@@ -58,7 +58,7 @@ class TemplateService(BaseService):
return TemplateType(t_type)
def render(self, recipe: Recipe, template: str = None) -> Path:
def render(self, recipe: Recipe, template: str) -> Path:
"""
Renders a TemplateType in a temporary directory and returns the path to the file.
@@ -87,6 +87,9 @@ class TemplateService(BaseService):
"""
self.__check_temp(self._render_json)
if self.temp is None:
raise ValueError("Temporary directory must be provided for method _render_json")
save_path = self.temp.joinpath(f"{recipe.slug}.json")
with open(save_path, "w") as f:
f.write(recipe.json(indent=4, by_alias=True))
@@ -100,6 +103,9 @@ class TemplateService(BaseService):
"""
self.__check_temp(self._render_jinja2)
if j2_template is None:
raise ValueError("Template must be provided for method _render_jinja2")
j2_path: Path = self.directories.TEMPLATE_DIR / j2_template
if not j2_path.is_file():
@@ -113,6 +119,9 @@ class TemplateService(BaseService):
save_name = f"{recipe.slug}{j2_path.suffix}"
if self.temp is None:
raise ValueError("Temporary directory must be provided for method _render_jinja2")
save_path = self.temp.joinpath(save_name)
with open(save_path, "w") as f:
@@ -124,6 +133,10 @@ class TemplateService(BaseService):
self.__check_temp(self._render_jinja2)
image_asset = recipe.image_dir.joinpath(RecipeImageTypes.original.value)
if self.temp is None:
raise ValueError("Temporary directory must be provided for method _render_zip")
zip_temp = self.temp.joinpath(f"{recipe.slug}.zip")
with ZipFile(zip_temp, "w") as myzip: