From 2bb9aed4a3fa917c443255669ebdc7fb0222437b Mon Sep 17 00:00:00 2001 From: Emi Vasilek Date: Sun, 5 Nov 2023 11:05:23 +0100 Subject: [PATCH] use context to hold commonly used instances --- recipes.py | 159 +++++++++++++++++++++++++++++------------------------ 1 file changed, 88 insertions(+), 71 deletions(-) diff --git a/recipes.py b/recipes.py index 92e02a3..b03d889 100644 --- a/recipes.py +++ b/recipes.py @@ -4,6 +4,11 @@ import os import yaml import jinja2 +class Context: + def __init__(self) -> None: + self.units = Units() + self.ingredients = Ingredients(self) + class Unit: def __init__(self, name: str) -> None: @@ -29,6 +34,8 @@ class Units: class Ingredient: + def __init__(self, ctx: Context) -> None: + self.ctx = ctx def load(self, dct: Dict[str, Any]) -> List[str]: issues = [] issues += assert_dict(dct, ["name"], ["wdid", "pricedb", "aliases"]) @@ -44,7 +51,7 @@ class Ingredient: self.pricedb = None if "pricedb" in dct: assert_list(dct["pricedb"]) - self.pricedb = PriceDBs() + self.pricedb = PriceDBs(self.ctx) issues += self.pricedb.load(dct["pricedb"]) self.aliases = [] @@ -58,14 +65,15 @@ class Ingredient: class Ingredients: - def __init__(self) -> None: + def __init__(self, ctx: Context) -> None: + self.ctx = ctx self.ingredients: List[Ingredient] = [] def load(self, lst: List[Any]) -> List[str]: issues = [] assert_list(lst) for ingdct in lst: - ing = Ingredient() + ing = Ingredient(self.ctx) issues += ing.load(ingdct) self.ingredients.append(ing) return issues @@ -78,20 +86,24 @@ class Ingredients: class PriceDBs: - def __init__(self) -> None: + def __init__(self, ctx: Context) -> None: + self.ctx = ctx self.pricedbs: List[PriceDB] = [] def load(self, lst: List[Any]) -> List[str]: issues = [] assert_list(lst) for elem in lst: - pricedb = PriceDB() + pricedb = PriceDB(self.ctx) issues += pricedb.load(elem) self.pricedbs.append(pricedb) return issues class PriceDB: + def __init__(self, ctx: Context) -> None: + self.ctx = ctx + def load(self, dct: Dict[str, Any]) -> List[str]: issues = [] issues += assert_dict(dct, ["price"], ["amount", "unit"]) @@ -116,13 +128,16 @@ class PriceDB: if "unit" in dct: assert_type(dct, "unit", str) try: - self.unit = units.get(dct["unit"]) + self.unit = self.ctx.units.get(dct["unit"]) except RuntimeError as e: issues.append(str(e)) return issues class IngredientInstance: + def __init__(self, ctx: Context) -> None: + self.ctx = ctx + def load(self, dct: Dict[str, Any]) -> List[str]: issues = [] issues += assert_dict(dct, ["name"], ["amount", "unit", "note"]) @@ -131,7 +146,7 @@ class IngredientInstance: self.name = dct["name"] try: - self.ingredient = ingredients.get(self.name) + self.ingredient = self.ctx.ingredients.get(self.name) except RuntimeError as e: issues.append(str(e)) @@ -148,7 +163,7 @@ class IngredientInstance: if "unit" in dct: assert_type(dct, "unit", str) try: - self.unit = units.get(dct["unit"]) + self.unit = self.ctx.units.get(dct["unit"]) except RuntimeError as e: issues.append(str(e)) @@ -161,6 +176,8 @@ class IngredientInstance: class RecipePart: + def __init__(self, ctx: Context) -> None: + self.ctx = ctx def load(self, dct: Dict[str, Any]) -> List[str]: issues = [] issues += assert_dict(dct, ["title", "ingredients", "steps"], []) @@ -171,7 +188,7 @@ class RecipePart: assert_type(dct, "ingredients", list) self.ingredients: List[IngredientInstance] = [] for ing in dct["ingredients"]: - ingredient = IngredientInstance() + ingredient = IngredientInstance(self.ctx) issues += ingredient.load(ing) self.ingredients.append(ingredient) @@ -184,7 +201,8 @@ class RecipePart: class Recipe: - def __init__(self) -> None: + def __init__(self, ctx: Context) -> None: + self.ctx = ctx self.parts: List[RecipePart] = [] self.srcpath = "" self.outpath = "" @@ -199,24 +217,17 @@ class Recipe: assert_list(dct["parts"]) for partdct in dct["parts"]: - rp = RecipePart() + rp = RecipePart(self.ctx) issues += rp.load(partdct) self.parts.append(rp) else: - rp = RecipePart() + rp = RecipePart(self.ctx) issues = rp.load(dct) self.parts = [rp] self.title = rp.title return issues -def load_file(file: str) -> Any: - print(f"loading {file}") - with open(file, encoding="utf-8") as f: - ymltxt = f.read() - return yaml.safe_load(ymltxt) - - def assert_dict( dct: Dict[str, Any], required_keys: List[str], optional_keys: List[str] ) -> List[str]: @@ -245,70 +256,76 @@ def assert_list(lst: List[Any]) -> None: raise RuntimeError(f"{lst} has to be a {list}") -def rendertemplate( - template: jinja2.Template, format: str, file: str, args: Any -) -> None: - print(f"rendering {file}") - outstr = template.render(args) +class Builder: + def __init__(self) -> None: + self.jinjaenv = jinja2.Environment( + loader=jinja2.FileSystemLoader("templates"), + autoescape=jinja2.select_autoescape(), + ) + self.ctx = Context() - os.makedirs(f"out/{format}", exist_ok=True) + def load_file(self, file: str) -> Any: + print(f"loading {file}") + with open(file, encoding="utf-8") as f: + ymltxt = f.read() + return yaml.safe_load(ymltxt) - with open(f"out/{format}/{file}", "w", encoding="utf-8") as f: - f.write(outstr) + def rendertemplate( + self, templatepath: str, format: str, file: str, args: Any + ) -> None: + template = self.jinjaenv.get_template(templatepath) + print(f"rendering {file}") + outstr = template.render(args) + os.makedirs(f"out/{format}", exist_ok=True) -units = Units() -ingredients = Ingredients() + with open(f"out/{format}/{file}", "w", encoding="utf-8") as f: + f.write(outstr) + def load(self) -> None: + issues: List[str] = [] -def main() -> None: - issues: List[str] = [] + unitsdct = self.load_file("recipes/units.yaml") + issues += self.ctx.units.load(unitsdct) - unitsdct = load_file("recipes/units.yaml") - issues += units.load(unitsdct) + ingredientsdct = self.load_file("recipes/ingredients.yaml") + issues += self.ctx.ingredients.load(ingredientsdct) - ingredientsdct = load_file("recipes/ingredients.yaml") - issues += ingredients.load(ingredientsdct) + if len(issues) != 0: + for issue in issues: + print("ERROR", issue) + return - if len(issues) != 0: - for issue in issues: - print("ERROR", issue) - return + def run(self) -> None: + issues = [] + files = [] + for _, _, filesx in os.walk("recipes/recipes"): + files = filesx + files.sort() - files = [] - for _, _, filesx in os.walk("recipes/recipes"): - files = filesx - files.sort() + recipes: List[Recipe] = [] + for file in files: + if not file.endswith(".yaml"): + print(f"unknown extension of {file}") + continue + recipe = Recipe(self.ctx) + recipedct = self.load_file("recipes/recipes/" + file) + issues += recipe.load(recipedct) + recipe.srcpath = file + recipe.outpath = file[:-5] + ".html" + recipes.append(recipe) - recipes: List[Recipe] = [] - for file in files: - if not file.endswith(".yaml"): - print(f"unknown extension of {file}") - continue - recipe = Recipe() - recipedct = load_file("recipes/recipes/" + file) - issues += recipe.load(recipedct) - recipe.srcpath = file - recipe.outpath = file[:-5] + ".html" - recipes.append(recipe) + if len(issues) != 0: + for issue in issues: + print("ERROR", issue) + return - if len(issues) != 0: - for issue in issues: - print("ERROR", issue) - return - - env = jinja2.Environment( - loader=jinja2.FileSystemLoader("templates"), - autoescape=jinja2.select_autoescape(), - ) - - indextemplate = env.get_template("index.html") - rendertemplate(indextemplate, "html", "index.html", {"recipes": recipes}) - - recipetemplate = env.get_template("recipe.html") - for recipe in recipes: - rendertemplate(recipetemplate, "html", recipe.outpath, {"recipe": recipe}) + self.rendertemplate("index.html", "html", "index.html", {"recipes": recipes}) + for recipe in recipes: + self.rendertemplate( "recipe.html", "html", recipe.outpath, {"recipe": recipe}) if __name__ == "__main__": - main() + builder = Builder() + builder.load() + builder.run()