52 lines
1.7 KiB
Python
52 lines
1.7 KiB
Python
|
"""Functions to parse the weigth string into a dictionary that represents
|
||
|
the weight in g
|
||
|
"""
|
||
|
|
||
|
import logging
|
||
|
from typing import Optional
|
||
|
import re
|
||
|
|
||
|
from helpers.misc import convert_units
|
||
|
|
||
|
|
||
|
UNIT_CONVERSIONS = {"pounds": 453.592, "ounces": 28.3495, "g": 1, "kg": 1000}
|
||
|
|
||
|
|
||
|
def parse_weight(weight: Optional[str]) -> Optional[float]:
|
||
|
"""Parse a weigth string into a dictionary representing the weight unit and
|
||
|
value"""
|
||
|
if weight is None:
|
||
|
return None
|
||
|
expr = r"(?P<value>\d*[.,]?\d*)\s+(?P<unit>[a-zA-Z]*)"
|
||
|
|
||
|
# strip is needed to prevent the regex from lazily
|
||
|
# matching just from the first whitespace separator,
|
||
|
# this could happen because the number part in the
|
||
|
# expression is technically all optional, to avoid
|
||
|
# an expression too complex and unreadable
|
||
|
if match := re.search(expr, weight.strip()):
|
||
|
match_value = match.group("value")
|
||
|
try:
|
||
|
value = float(match_value)
|
||
|
except ValueError:
|
||
|
logging.error("could not parse value `%s` as a float for a weight")
|
||
|
return None
|
||
|
unit = match.group("unit").lower()
|
||
|
return convert_units(value, unit, unit_conversions=UNIT_CONVERSIONS)
|
||
|
|
||
|
return None
|
||
|
|
||
|
|
||
|
def dimensional_weight(
|
||
|
height: Optional[float], width: Optional[float], depth: Optional[float]
|
||
|
) -> Optional[float]:
|
||
|
"""The dimensional weight (in kg) is calculated as:
|
||
|
Length * Height * Width (in cm) / 5000.
|
||
|
We'll return it in g here"""
|
||
|
if None in [height, width, depth]:
|
||
|
return None
|
||
|
dimensional_weight_kg = height * width * depth / 5000
|
||
|
return convert_units(
|
||
|
value=dimensional_weight_kg, unit="kg", unit_conversions=UNIT_CONVERSIONS
|
||
|
)
|