78 lines
3.0 KiB
Python
78 lines
3.0 KiB
Python
from pint import UnitRegistry, UndefinedUnitError, PintError
|
|
|
|
from cookbook.models import Ingredient, Unit
|
|
|
|
CONVERT_TO_UNITS = {
|
|
'metric': ['g', 'kg', 'ml', 'l'],
|
|
'us': ['ounce', 'pound', 'fluid_ounce', 'pint', 'quart', 'gallon'],
|
|
'uk': ['ounce', 'pound', 'imperial_fluid_ounce', 'imperial_pint', 'imperial_quart', 'imperial_gallon'],
|
|
}
|
|
|
|
|
|
def base_conversions(ingredient_list):
|
|
ureg = UnitRegistry()
|
|
pint_converted_list = ingredient_list.copy()
|
|
for i in ingredient_list:
|
|
try:
|
|
conversion_unit = i.unit.name
|
|
if i.unit.base_unit:
|
|
conversion_unit = i.unit.base_unit
|
|
quantitiy = ureg.Quantity(f'{i.amount} {conversion_unit}')
|
|
|
|
# TODO allow setting which units to convert to
|
|
units = Unit.objects.filter(base_unit__in=(CONVERT_TO_UNITS['metric'] + CONVERT_TO_UNITS['us'] + CONVERT_TO_UNITS['uk'])).all()
|
|
|
|
for u in units:
|
|
try:
|
|
converted = quantitiy.to(u.base_unit)
|
|
ingredient = Ingredient(amount=converted.m, unit=u, food=ingredient_list[0].food, )
|
|
if not any((x.unit.name == ingredient.unit.name or x.unit.base_unit == ingredient.unit.name) for x in pint_converted_list):
|
|
pint_converted_list.append(ingredient)
|
|
except PintError:
|
|
pass
|
|
except PintError:
|
|
pass
|
|
|
|
return pint_converted_list
|
|
|
|
|
|
def get_conversions(ingredient):
|
|
conversions = [ingredient]
|
|
if ingredient.unit:
|
|
for c in ingredient.unit.unit_conversion_base_relation.all():
|
|
r = _uc_convert(c, ingredient.amount, ingredient.unit, ingredient.food)
|
|
if r and r not in conversions:
|
|
conversions.append(r)
|
|
for c in ingredient.unit.unit_conversion_converted_relation.all():
|
|
r = _uc_convert(c, ingredient.amount, ingredient.unit, ingredient.food)
|
|
if r and r not in conversions:
|
|
conversions.append(r)
|
|
|
|
conversions = base_conversions(conversions)
|
|
|
|
return conversions
|
|
|
|
|
|
def _uc_convert(uc, amount, unit, food):
|
|
if uc.food is None or uc.food == food:
|
|
if unit == uc.base_unit:
|
|
return Ingredient(amount=amount * (uc.converted_amount / uc.base_amount), unit=uc.converted_unit, food=food)
|
|
# return {
|
|
# 'amount': amount * (uc.converted_amount / uc.base_amount),
|
|
# 'unit': {
|
|
# 'id': uc.converted_unit.id,
|
|
# 'name': uc.converted_unit.name,
|
|
# 'plural_name': uc.converted_unit.plural_name
|
|
# },
|
|
# }
|
|
else:
|
|
return Ingredient(amount=amount * (uc.base_amount / uc.converted_amount), unit=uc.base_unit, food=food)
|
|
# return {
|
|
# 'amount': amount * (uc.base_amount / uc.converted_amount),
|
|
# 'unit': {
|
|
# 'id': uc.base_unit.id,
|
|
# 'name': uc.base_unit.name,
|
|
# 'plural_name': uc.base_unit.plural_name
|
|
# },
|
|
# }
|