use context to hold commonly used instances
This commit is contained in:
parent
2e12ab77a5
commit
2bb9aed4a3
1 changed files with 88 additions and 71 deletions
103
recipes.py
103
recipes.py
|
@ -4,6 +4,11 @@ import os
|
||||||
import yaml
|
import yaml
|
||||||
import jinja2
|
import jinja2
|
||||||
|
|
||||||
|
class Context:
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self.units = Units()
|
||||||
|
self.ingredients = Ingredients(self)
|
||||||
|
|
||||||
|
|
||||||
class Unit:
|
class Unit:
|
||||||
def __init__(self, name: str) -> None:
|
def __init__(self, name: str) -> None:
|
||||||
|
@ -29,6 +34,8 @@ class Units:
|
||||||
|
|
||||||
|
|
||||||
class Ingredient:
|
class Ingredient:
|
||||||
|
def __init__(self, ctx: Context) -> None:
|
||||||
|
self.ctx = ctx
|
||||||
def load(self, dct: Dict[str, Any]) -> List[str]:
|
def load(self, dct: Dict[str, Any]) -> List[str]:
|
||||||
issues = []
|
issues = []
|
||||||
issues += assert_dict(dct, ["name"], ["wdid", "pricedb", "aliases"])
|
issues += assert_dict(dct, ["name"], ["wdid", "pricedb", "aliases"])
|
||||||
|
@ -44,7 +51,7 @@ class Ingredient:
|
||||||
self.pricedb = None
|
self.pricedb = None
|
||||||
if "pricedb" in dct:
|
if "pricedb" in dct:
|
||||||
assert_list(dct["pricedb"])
|
assert_list(dct["pricedb"])
|
||||||
self.pricedb = PriceDBs()
|
self.pricedb = PriceDBs(self.ctx)
|
||||||
issues += self.pricedb.load(dct["pricedb"])
|
issues += self.pricedb.load(dct["pricedb"])
|
||||||
|
|
||||||
self.aliases = []
|
self.aliases = []
|
||||||
|
@ -58,14 +65,15 @@ class Ingredient:
|
||||||
|
|
||||||
|
|
||||||
class Ingredients:
|
class Ingredients:
|
||||||
def __init__(self) -> None:
|
def __init__(self, ctx: Context) -> None:
|
||||||
|
self.ctx = ctx
|
||||||
self.ingredients: List[Ingredient] = []
|
self.ingredients: List[Ingredient] = []
|
||||||
|
|
||||||
def load(self, lst: List[Any]) -> List[str]:
|
def load(self, lst: List[Any]) -> List[str]:
|
||||||
issues = []
|
issues = []
|
||||||
assert_list(lst)
|
assert_list(lst)
|
||||||
for ingdct in lst:
|
for ingdct in lst:
|
||||||
ing = Ingredient()
|
ing = Ingredient(self.ctx)
|
||||||
issues += ing.load(ingdct)
|
issues += ing.load(ingdct)
|
||||||
self.ingredients.append(ing)
|
self.ingredients.append(ing)
|
||||||
return issues
|
return issues
|
||||||
|
@ -78,20 +86,24 @@ class Ingredients:
|
||||||
|
|
||||||
|
|
||||||
class PriceDBs:
|
class PriceDBs:
|
||||||
def __init__(self) -> None:
|
def __init__(self, ctx: Context) -> None:
|
||||||
|
self.ctx = ctx
|
||||||
self.pricedbs: List[PriceDB] = []
|
self.pricedbs: List[PriceDB] = []
|
||||||
|
|
||||||
def load(self, lst: List[Any]) -> List[str]:
|
def load(self, lst: List[Any]) -> List[str]:
|
||||||
issues = []
|
issues = []
|
||||||
assert_list(lst)
|
assert_list(lst)
|
||||||
for elem in lst:
|
for elem in lst:
|
||||||
pricedb = PriceDB()
|
pricedb = PriceDB(self.ctx)
|
||||||
issues += pricedb.load(elem)
|
issues += pricedb.load(elem)
|
||||||
self.pricedbs.append(pricedb)
|
self.pricedbs.append(pricedb)
|
||||||
return issues
|
return issues
|
||||||
|
|
||||||
|
|
||||||
class PriceDB:
|
class PriceDB:
|
||||||
|
def __init__(self, ctx: Context) -> None:
|
||||||
|
self.ctx = ctx
|
||||||
|
|
||||||
def load(self, dct: Dict[str, Any]) -> List[str]:
|
def load(self, dct: Dict[str, Any]) -> List[str]:
|
||||||
issues = []
|
issues = []
|
||||||
issues += assert_dict(dct, ["price"], ["amount", "unit"])
|
issues += assert_dict(dct, ["price"], ["amount", "unit"])
|
||||||
|
@ -116,13 +128,16 @@ class PriceDB:
|
||||||
if "unit" in dct:
|
if "unit" in dct:
|
||||||
assert_type(dct, "unit", str)
|
assert_type(dct, "unit", str)
|
||||||
try:
|
try:
|
||||||
self.unit = units.get(dct["unit"])
|
self.unit = self.ctx.units.get(dct["unit"])
|
||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
issues.append(str(e))
|
issues.append(str(e))
|
||||||
return issues
|
return issues
|
||||||
|
|
||||||
|
|
||||||
class IngredientInstance:
|
class IngredientInstance:
|
||||||
|
def __init__(self, ctx: Context) -> None:
|
||||||
|
self.ctx = ctx
|
||||||
|
|
||||||
def load(self, dct: Dict[str, Any]) -> List[str]:
|
def load(self, dct: Dict[str, Any]) -> List[str]:
|
||||||
issues = []
|
issues = []
|
||||||
issues += assert_dict(dct, ["name"], ["amount", "unit", "note"])
|
issues += assert_dict(dct, ["name"], ["amount", "unit", "note"])
|
||||||
|
@ -131,7 +146,7 @@ class IngredientInstance:
|
||||||
self.name = dct["name"]
|
self.name = dct["name"]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.ingredient = ingredients.get(self.name)
|
self.ingredient = self.ctx.ingredients.get(self.name)
|
||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
issues.append(str(e))
|
issues.append(str(e))
|
||||||
|
|
||||||
|
@ -148,7 +163,7 @@ class IngredientInstance:
|
||||||
if "unit" in dct:
|
if "unit" in dct:
|
||||||
assert_type(dct, "unit", str)
|
assert_type(dct, "unit", str)
|
||||||
try:
|
try:
|
||||||
self.unit = units.get(dct["unit"])
|
self.unit = self.ctx.units.get(dct["unit"])
|
||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
issues.append(str(e))
|
issues.append(str(e))
|
||||||
|
|
||||||
|
@ -161,6 +176,8 @@ class IngredientInstance:
|
||||||
|
|
||||||
|
|
||||||
class RecipePart:
|
class RecipePart:
|
||||||
|
def __init__(self, ctx: Context) -> None:
|
||||||
|
self.ctx = ctx
|
||||||
def load(self, dct: Dict[str, Any]) -> List[str]:
|
def load(self, dct: Dict[str, Any]) -> List[str]:
|
||||||
issues = []
|
issues = []
|
||||||
issues += assert_dict(dct, ["title", "ingredients", "steps"], [])
|
issues += assert_dict(dct, ["title", "ingredients", "steps"], [])
|
||||||
|
@ -171,7 +188,7 @@ class RecipePart:
|
||||||
assert_type(dct, "ingredients", list)
|
assert_type(dct, "ingredients", list)
|
||||||
self.ingredients: List[IngredientInstance] = []
|
self.ingredients: List[IngredientInstance] = []
|
||||||
for ing in dct["ingredients"]:
|
for ing in dct["ingredients"]:
|
||||||
ingredient = IngredientInstance()
|
ingredient = IngredientInstance(self.ctx)
|
||||||
issues += ingredient.load(ing)
|
issues += ingredient.load(ing)
|
||||||
self.ingredients.append(ingredient)
|
self.ingredients.append(ingredient)
|
||||||
|
|
||||||
|
@ -184,7 +201,8 @@ class RecipePart:
|
||||||
|
|
||||||
|
|
||||||
class Recipe:
|
class Recipe:
|
||||||
def __init__(self) -> None:
|
def __init__(self, ctx: Context) -> None:
|
||||||
|
self.ctx = ctx
|
||||||
self.parts: List[RecipePart] = []
|
self.parts: List[RecipePart] = []
|
||||||
self.srcpath = ""
|
self.srcpath = ""
|
||||||
self.outpath = ""
|
self.outpath = ""
|
||||||
|
@ -199,24 +217,17 @@ class Recipe:
|
||||||
|
|
||||||
assert_list(dct["parts"])
|
assert_list(dct["parts"])
|
||||||
for partdct in dct["parts"]:
|
for partdct in dct["parts"]:
|
||||||
rp = RecipePart()
|
rp = RecipePart(self.ctx)
|
||||||
issues += rp.load(partdct)
|
issues += rp.load(partdct)
|
||||||
self.parts.append(rp)
|
self.parts.append(rp)
|
||||||
else:
|
else:
|
||||||
rp = RecipePart()
|
rp = RecipePart(self.ctx)
|
||||||
issues = rp.load(dct)
|
issues = rp.load(dct)
|
||||||
self.parts = [rp]
|
self.parts = [rp]
|
||||||
self.title = rp.title
|
self.title = rp.title
|
||||||
return issues
|
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(
|
def assert_dict(
|
||||||
dct: Dict[str, Any], required_keys: List[str], optional_keys: List[str]
|
dct: Dict[str, Any], required_keys: List[str], optional_keys: List[str]
|
||||||
) -> List[str]:
|
) -> List[str]:
|
||||||
|
@ -245,9 +256,24 @@ def assert_list(lst: List[Any]) -> None:
|
||||||
raise RuntimeError(f"{lst} has to be a {list}")
|
raise RuntimeError(f"{lst} has to be a {list}")
|
||||||
|
|
||||||
|
|
||||||
|
class Builder:
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self.jinjaenv = jinja2.Environment(
|
||||||
|
loader=jinja2.FileSystemLoader("templates"),
|
||||||
|
autoescape=jinja2.select_autoescape(),
|
||||||
|
)
|
||||||
|
self.ctx = Context()
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
def rendertemplate(
|
def rendertemplate(
|
||||||
template: jinja2.Template, format: str, file: str, args: Any
|
self, templatepath: str, format: str, file: str, args: Any
|
||||||
) -> None:
|
) -> None:
|
||||||
|
template = self.jinjaenv.get_template(templatepath)
|
||||||
print(f"rendering {file}")
|
print(f"rendering {file}")
|
||||||
outstr = template.render(args)
|
outstr = template.render(args)
|
||||||
|
|
||||||
|
@ -256,25 +282,22 @@ def rendertemplate(
|
||||||
with open(f"out/{format}/{file}", "w", encoding="utf-8") as f:
|
with open(f"out/{format}/{file}", "w", encoding="utf-8") as f:
|
||||||
f.write(outstr)
|
f.write(outstr)
|
||||||
|
|
||||||
|
def load(self) -> None:
|
||||||
units = Units()
|
|
||||||
ingredients = Ingredients()
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
|
||||||
issues: List[str] = []
|
issues: List[str] = []
|
||||||
|
|
||||||
unitsdct = load_file("recipes/units.yaml")
|
unitsdct = self.load_file("recipes/units.yaml")
|
||||||
issues += units.load(unitsdct)
|
issues += self.ctx.units.load(unitsdct)
|
||||||
|
|
||||||
ingredientsdct = load_file("recipes/ingredients.yaml")
|
ingredientsdct = self.load_file("recipes/ingredients.yaml")
|
||||||
issues += ingredients.load(ingredientsdct)
|
issues += self.ctx.ingredients.load(ingredientsdct)
|
||||||
|
|
||||||
if len(issues) != 0:
|
if len(issues) != 0:
|
||||||
for issue in issues:
|
for issue in issues:
|
||||||
print("ERROR", issue)
|
print("ERROR", issue)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def run(self) -> None:
|
||||||
|
issues = []
|
||||||
files = []
|
files = []
|
||||||
for _, _, filesx in os.walk("recipes/recipes"):
|
for _, _, filesx in os.walk("recipes/recipes"):
|
||||||
files = filesx
|
files = filesx
|
||||||
|
@ -285,8 +308,8 @@ def main() -> None:
|
||||||
if not file.endswith(".yaml"):
|
if not file.endswith(".yaml"):
|
||||||
print(f"unknown extension of {file}")
|
print(f"unknown extension of {file}")
|
||||||
continue
|
continue
|
||||||
recipe = Recipe()
|
recipe = Recipe(self.ctx)
|
||||||
recipedct = load_file("recipes/recipes/" + file)
|
recipedct = self.load_file("recipes/recipes/" + file)
|
||||||
issues += recipe.load(recipedct)
|
issues += recipe.load(recipedct)
|
||||||
recipe.srcpath = file
|
recipe.srcpath = file
|
||||||
recipe.outpath = file[:-5] + ".html"
|
recipe.outpath = file[:-5] + ".html"
|
||||||
|
@ -297,18 +320,12 @@ def main() -> None:
|
||||||
print("ERROR", issue)
|
print("ERROR", issue)
|
||||||
return
|
return
|
||||||
|
|
||||||
env = jinja2.Environment(
|
self.rendertemplate("index.html", "html", "index.html", {"recipes": recipes})
|
||||||
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:
|
for recipe in recipes:
|
||||||
rendertemplate(recipetemplate, "html", recipe.outpath, {"recipe": recipe})
|
self.rendertemplate( "recipe.html", "html", recipe.outpath, {"recipe": recipe})
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
builder = Builder()
|
||||||
|
builder.load()
|
||||||
|
builder.run()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue