rename pricedb to prices
This commit is contained in:
parent
065975d4c2
commit
546ef63289
3 changed files with 80 additions and 30 deletions
104
recipes.py
104
recipes.py
|
@ -47,20 +47,14 @@ class Element:
|
||||||
|
|
||||||
class Conversion(Element):
|
class Conversion(Element):
|
||||||
def load(self, dct: Dict[str, Any]) -> None:
|
def load(self, dct: Dict[str, Any]) -> None:
|
||||||
def find_unit(name: str) -> Optional[Unit]:
|
fromunit = self.ctx.units.get(dct["from"])
|
||||||
for unit in self.ctx.units.units:
|
|
||||||
if unit["name"] == name:
|
|
||||||
return unit
|
|
||||||
return None
|
|
||||||
|
|
||||||
fromunit = find_unit(dct["from"])
|
|
||||||
if fromunit is None:
|
if fromunit is None:
|
||||||
raise RuntimeError(f"unit {fromunit} doesn't exist")
|
raise RuntimeError(f"unit {dct['from']} doesn't exist")
|
||||||
self["from"] = fromunit
|
self["from"] = fromunit
|
||||||
|
|
||||||
tounit = find_unit(dct["to"])
|
tounit = self.ctx.units.get(dct["to"])
|
||||||
if tounit is None:
|
if tounit is None:
|
||||||
raise RuntimeError(f"unit {tounit} doesn't exist")
|
raise RuntimeError(f"unit {dct['to']} doesn't exist")
|
||||||
self["to"] = tounit
|
self["to"] = tounit
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,10 +63,18 @@ class Unit(Element):
|
||||||
oldunits = self.ctx.units.units[:]
|
oldunits = self.ctx.units.units[:]
|
||||||
self.ctx.units.units.append(self)
|
self.ctx.units.units.append(self)
|
||||||
|
|
||||||
|
aliases: List[str] = []
|
||||||
|
if "aliases" in dct:
|
||||||
|
for alias in dct["aliases"]:
|
||||||
|
aliases.append(alias)
|
||||||
|
self["aliases"] = aliases
|
||||||
|
self.ctx.units.units = oldunits
|
||||||
|
|
||||||
|
def finish_load(self) -> None:
|
||||||
conversions: List[Conversion] = []
|
conversions: List[Conversion] = []
|
||||||
if "conversions" in dct:
|
if "conversions" in self.dct:
|
||||||
for convdct in dct["conversions"]:
|
for convdct in self.dct["conversions"]:
|
||||||
if "from" in dct["conversions"]:
|
if "from" in self.dct["conversions"]:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
"conversions in units.yaml cannot have a from field, it is automatically assigned from the unit name"
|
"conversions in units.yaml cannot have a from field, it is automatically assigned from the unit name"
|
||||||
)
|
)
|
||||||
|
@ -81,13 +83,6 @@ class Unit(Element):
|
||||||
conversions.append(conversion)
|
conversions.append(conversion)
|
||||||
self["conversions"] = conversions
|
self["conversions"] = conversions
|
||||||
|
|
||||||
aliases: List[str] = []
|
|
||||||
if "aliases" in dct:
|
|
||||||
for alias in dct["aliases"]:
|
|
||||||
aliases.append(alias)
|
|
||||||
self["aliases"] = aliases
|
|
||||||
self.ctx.units.units = oldunits
|
|
||||||
|
|
||||||
|
|
||||||
class Units:
|
class Units:
|
||||||
def __init__(self, ctx: Context) -> None:
|
def __init__(self, ctx: Context) -> None:
|
||||||
|
@ -98,6 +93,8 @@ class Units:
|
||||||
for unitdct in lst:
|
for unitdct in lst:
|
||||||
unit = Unit(self.ctx, unitdct)
|
unit = Unit(self.ctx, unitdct)
|
||||||
self.units.append(unit)
|
self.units.append(unit)
|
||||||
|
for unit in self.units:
|
||||||
|
unit.finish_load()
|
||||||
|
|
||||||
def get(self, name: str) -> Optional[Unit]:
|
def get(self, name: str) -> Optional[Unit]:
|
||||||
for unit in self.units:
|
for unit in self.units:
|
||||||
|
@ -108,10 +105,10 @@ class Units:
|
||||||
|
|
||||||
class Ingredient(Element):
|
class Ingredient(Element):
|
||||||
def load(self, dct: Dict[str, Any]) -> None:
|
def load(self, dct: Dict[str, Any]) -> None:
|
||||||
if "pricedb" in dct:
|
if "prices" in dct:
|
||||||
pricedb = PriceDBs(self.ctx)
|
pricedb = PriceDBs(self.ctx)
|
||||||
self.ctx.issues += pricedb.load(dct["pricedb"])
|
self.ctx.issues += pricedb.load(dct["prices"])
|
||||||
self["pricedb"] = pricedb
|
self["prices"] = pricedb
|
||||||
|
|
||||||
conversions = []
|
conversions = []
|
||||||
if "conversions" in dct:
|
if "conversions" in dct:
|
||||||
|
@ -120,6 +117,50 @@ class Ingredient(Element):
|
||||||
conversions.append(conversion)
|
conversions.append(conversion)
|
||||||
self["conversions"] = conversions
|
self["conversions"] = conversions
|
||||||
|
|
||||||
|
def convert(
|
||||||
|
self, amount: float, unitfrom: Unit, unitto: Unit, scannedunits: List[Unit] = []
|
||||||
|
) -> Optional[float]:
|
||||||
|
# TODO: this can not solve conversions when we have kg -> g and g -> piece
|
||||||
|
if unitto == unitfrom:
|
||||||
|
return amount
|
||||||
|
conversions = (
|
||||||
|
self["conversions"] + unitfrom["conversions"] + unitto["conversions"]
|
||||||
|
)
|
||||||
|
for conv in conversions:
|
||||||
|
ratio: float = conv["ratio"]
|
||||||
|
if (
|
||||||
|
conv["from"]["name"] == unitfrom["name"]
|
||||||
|
and conv["to"]["name"] == unitto["name"]
|
||||||
|
):
|
||||||
|
return amount * ratio
|
||||||
|
if (
|
||||||
|
conv["to"]["name"] == unitfrom["name"]
|
||||||
|
and conv["from"]["name"] == unitto["name"]
|
||||||
|
):
|
||||||
|
return amount / ratio
|
||||||
|
return None
|
||||||
|
|
||||||
|
def getprice(self, amount: float, unit: Unit) -> Optional[float]:
|
||||||
|
if "prices" not in self.dct:
|
||||||
|
return None
|
||||||
|
prices: List[float] = []
|
||||||
|
pricedbs: PriceDBs = self["prices"]
|
||||||
|
for entry in pricedbs.pricedbs:
|
||||||
|
assert isinstance(entry, PriceDB)
|
||||||
|
entryamount: float = entry["amount"]
|
||||||
|
entryprice: float = entry["price"]
|
||||||
|
entryunit: Unit = entry["unit"]
|
||||||
|
if entryunit == unit:
|
||||||
|
prices.append((amount / entryamount) * entryprice)
|
||||||
|
else:
|
||||||
|
newamount = self.convert(amount, unit, entryunit)
|
||||||
|
if newamount is not None:
|
||||||
|
prices.append((newamount / entryamount) * entryprice)
|
||||||
|
if len(prices) == 0:
|
||||||
|
return None
|
||||||
|
assert len(prices) == 1
|
||||||
|
return prices[0]
|
||||||
|
|
||||||
|
|
||||||
class Ingredients:
|
class Ingredients:
|
||||||
def __init__(self, ctx: Context) -> None:
|
def __init__(self, ctx: Context) -> None:
|
||||||
|
@ -166,9 +207,10 @@ class PriceDB(Element):
|
||||||
|
|
||||||
class IngredientInstance(Element):
|
class IngredientInstance(Element):
|
||||||
def load(self, dct: Dict[str, Any]) -> None:
|
def load(self, dct: Dict[str, Any]) -> None:
|
||||||
self["ingredient"] = self.ctx.ingredients.get(dct["name"])
|
ingredient = self.ctx.ingredients.get(dct["name"])
|
||||||
if self["ingredient"] is None:
|
if ingredient is None:
|
||||||
self.ctx.issues.append(f"unknown ingredient {dct['name']}")
|
self.ctx.issues.append(f"unknown ingredient {dct['name']}")
|
||||||
|
self["ingredient"] = ingredient
|
||||||
|
|
||||||
if "amount" not in dct:
|
if "amount" not in dct:
|
||||||
self["amount"] = 1.0
|
self["amount"] = 1.0
|
||||||
|
@ -187,10 +229,13 @@ class IngredientInstance(Element):
|
||||||
alternatives = []
|
alternatives = []
|
||||||
if "or" in dct:
|
if "or" in dct:
|
||||||
for ingdct in dct["or"]:
|
for ingdct in dct["or"]:
|
||||||
ingredient = IngredientInstance(self.ctx, ingdct)
|
ing = IngredientInstance(self.ctx, ingdct)
|
||||||
alternatives.append(ingredient)
|
alternatives.append(ing)
|
||||||
self["alternatives"] = alternatives
|
self["alternatives"] = alternatives
|
||||||
|
|
||||||
|
if ingredient is not None:
|
||||||
|
self["price"] = ingredient.getprice(self["amount"], self["unit"])
|
||||||
|
|
||||||
|
|
||||||
class Recipe(Element):
|
class Recipe(Element):
|
||||||
def __init__(self, ctx: Context, dct: Dict[str, Any]) -> None:
|
def __init__(self, ctx: Context, dct: Dict[str, Any]) -> None:
|
||||||
|
@ -225,6 +270,10 @@ class Builder:
|
||||||
out = str(input)
|
out = str(input)
|
||||||
if out.endswith(".0"):
|
if out.endswith(".0"):
|
||||||
return out.split(".", maxsplit=1)[0]
|
return out.split(".", maxsplit=1)[0]
|
||||||
|
return out
|
||||||
|
|
||||||
|
def amountprint(input: int) -> str:
|
||||||
|
out = numprint(input)
|
||||||
if out == "0.5":
|
if out == "0.5":
|
||||||
return "1/2"
|
return "1/2"
|
||||||
if out == "0.25":
|
if out == "0.25":
|
||||||
|
@ -234,6 +283,7 @@ class Builder:
|
||||||
return out
|
return out
|
||||||
|
|
||||||
self.jinjaenv.filters["numprint"] = numprint
|
self.jinjaenv.filters["numprint"] = numprint
|
||||||
|
self.jinjaenv.filters["amountprint"] = amountprint
|
||||||
self.ctx = Context()
|
self.ctx = Context()
|
||||||
# list of output files that will be built
|
# list of output files that will be built
|
||||||
self.outfiles: Set[str] = set()
|
self.outfiles: Set[str] = set()
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"name": { "type": "string" },
|
"name": { "type": "string" },
|
||||||
"wdid": { "type": "integer" },
|
"wdid": { "type": "integer" },
|
||||||
"pricedb": {
|
"prices": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% macro ingredientpart(ing) -%}
|
{% macro ingredientpart(ing) -%}
|
||||||
{{ing.amount|numprint}} {{ing["unit"].name}} {{ ing.name }}
|
{% if ing.price != None %}{{ing.price|round(1)|numprint}}{%else%} ?{%endif%} {{ing.amount|amountprint}} {{ing["unit"].name}} {{ ing.name }}
|
||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
|
|
||||||
{% macro ingredient(ing) -%}
|
{% macro ingredient(ing) -%}
|
||||||
|
@ -36,4 +36,4 @@
|
||||||
{%block body %}
|
{%block body %}
|
||||||
<a href="index.html">back</a>
|
<a href="index.html">back</a>
|
||||||
{{getrecipe(recipe)}}
|
{{getrecipe(recipe)}}
|
||||||
{%endblock%}
|
{%endblock%}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue