Handle Weissman day and overnight times
This commit is contained in:
@@ -296,9 +296,10 @@ def enrich_recipe_node_from_dom(recipe_node: dict[str, Any], html: str) -> dict[
|
|||||||
|
|
||||||
DURATION_RE = re.compile(r'^P(?:T(?:(?P<hours>\d+)H)?(?:(?P<minutes>\d+)M)?(?:(?P<seconds>\d+)S)?)?$')
|
DURATION_RE = re.compile(r'^P(?:T(?:(?P<hours>\d+)H)?(?:(?P<minutes>\d+)M)?(?:(?P<seconds>\d+)S)?)?$')
|
||||||
TEXT_DURATION_PART_RE = re.compile(
|
TEXT_DURATION_PART_RE = re.compile(
|
||||||
r'(?P<value>\d+(?:\.\d+)?)\s*(?P<unit>hours?|hrs?|hr|minutes?|mins?|min|seconds?|secs?|sec|s)\b',
|
r'(?P<value>\d+(?:\.\d+)?)\s*(?P<unit>days?|day|hours?|hrs?|hr|minutes?|mins?|min|seconds?|secs?|sec|s)\b',
|
||||||
re.IGNORECASE,
|
re.IGNORECASE,
|
||||||
)
|
)
|
||||||
|
OVERNIGHT_RE = re.compile(r'\bovernight\b', re.IGNORECASE)
|
||||||
|
|
||||||
|
|
||||||
def parse_duration_minutes(value: Any) -> int | None:
|
def parse_duration_minutes(value: Any) -> int | None:
|
||||||
@@ -319,17 +320,21 @@ def parse_duration_minutes(value: Any) -> int | None:
|
|||||||
total = hours * 60 + minutes + (1 if seconds >= 30 else 0)
|
total = hours * 60 + minutes + (1 if seconds >= 30 else 0)
|
||||||
return total or None
|
return total or None
|
||||||
textual_matches = list(TEXT_DURATION_PART_RE.finditer(value))
|
textual_matches = list(TEXT_DURATION_PART_RE.finditer(value))
|
||||||
if textual_matches:
|
overnight_count = len(OVERNIGHT_RE.findall(value))
|
||||||
|
if textual_matches or overnight_count:
|
||||||
total_minutes = 0.0
|
total_minutes = 0.0
|
||||||
for part in textual_matches:
|
for part in textual_matches:
|
||||||
amount = float(part.group('value'))
|
amount = float(part.group('value'))
|
||||||
unit = part.group('unit').lower()
|
unit = part.group('unit').lower()
|
||||||
if unit.startswith(('hour', 'hr')):
|
if unit.startswith('day'):
|
||||||
|
total_minutes += amount * 24 * 60
|
||||||
|
elif unit.startswith(('hour', 'hr')):
|
||||||
total_minutes += amount * 60
|
total_minutes += amount * 60
|
||||||
elif unit.startswith(('minute', 'min')):
|
elif unit.startswith(('minute', 'min')):
|
||||||
total_minutes += amount
|
total_minutes += amount
|
||||||
else:
|
else:
|
||||||
total_minutes += amount / 60
|
total_minutes += amount / 60
|
||||||
|
total_minutes += overnight_count * 12 * 60
|
||||||
rounded = int(total_minutes + 0.5)
|
rounded = int(total_minutes + 0.5)
|
||||||
return rounded or None
|
return rounded or None
|
||||||
num = re.search(r'(\d+)', value)
|
num = re.search(r'(\d+)', value)
|
||||||
|
|||||||
@@ -21,9 +21,10 @@ STOPWORDS = {"fresh", "large", "small", "medium", "optional", "to", "taste", "fo
|
|||||||
TAG_KEYS = ("recipeCategory", "recipeCuisine", "keywords")
|
TAG_KEYS = ("recipeCategory", "recipeCuisine", "keywords")
|
||||||
DURATION_RE = re.compile(r"^P(?:T(?:(?P<hours>\d+)H)?(?:(?P<minutes>\d+)M)?(?:(?P<seconds>\d+)S)?)?$")
|
DURATION_RE = re.compile(r"^P(?:T(?:(?P<hours>\d+)H)?(?:(?P<minutes>\d+)M)?(?:(?P<seconds>\d+)S)?)?$")
|
||||||
TEXT_DURATION_PART_RE = re.compile(
|
TEXT_DURATION_PART_RE = re.compile(
|
||||||
r"(?P<value>\d+(?:\.\d+)?)\s*(?P<unit>hours?|hrs?|hr|minutes?|mins?|min|seconds?|secs?|sec|s)\b",
|
r"(?P<value>\d+(?:\.\d+)?)\s*(?P<unit>days?|day|hours?|hrs?|hr|minutes?|mins?|min|seconds?|secs?|sec|s)\b",
|
||||||
re.IGNORECASE,
|
re.IGNORECASE,
|
||||||
)
|
)
|
||||||
|
OVERNIGHT_RE = re.compile(r"\bovernight\b", re.IGNORECASE)
|
||||||
|
|
||||||
|
|
||||||
class ScriptExtractor(HTMLParser):
|
class ScriptExtractor(HTMLParser):
|
||||||
@@ -415,17 +416,21 @@ def parse_duration_minutes(value: Any) -> int | None:
|
|||||||
total = hours * 60 + minutes + (1 if seconds >= 30 else 0)
|
total = hours * 60 + minutes + (1 if seconds >= 30 else 0)
|
||||||
return total or None
|
return total or None
|
||||||
textual_matches = list(TEXT_DURATION_PART_RE.finditer(text))
|
textual_matches = list(TEXT_DURATION_PART_RE.finditer(text))
|
||||||
if textual_matches:
|
overnight_count = len(OVERNIGHT_RE.findall(text))
|
||||||
|
if textual_matches or overnight_count:
|
||||||
total_minutes = 0.0
|
total_minutes = 0.0
|
||||||
for part in textual_matches:
|
for part in textual_matches:
|
||||||
amount = float(part.group("value"))
|
amount = float(part.group("value"))
|
||||||
unit = part.group("unit").lower()
|
unit = part.group("unit").lower()
|
||||||
if unit.startswith(("hour", "hr")):
|
if unit.startswith("day"):
|
||||||
|
total_minutes += amount * 24 * 60
|
||||||
|
elif unit.startswith(("hour", "hr")):
|
||||||
total_minutes += amount * 60
|
total_minutes += amount * 60
|
||||||
elif unit.startswith(("minute", "min")):
|
elif unit.startswith(("minute", "min")):
|
||||||
total_minutes += amount
|
total_minutes += amount
|
||||||
else:
|
else:
|
||||||
total_minutes += amount / 60
|
total_minutes += amount / 60
|
||||||
|
total_minutes += overnight_count * 12 * 60
|
||||||
rounded = int(total_minutes + 0.5)
|
rounded = int(total_minutes + 0.5)
|
||||||
return rounded or None
|
return rounded or None
|
||||||
number = re.search(r"(\d+)", text)
|
number = re.search(r"(\d+)", text)
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ class TaggingTests(unittest.TestCase):
|
|||||||
def test_textual_durations_cover_weissman_style_time_strings(self):
|
def test_textual_durations_cover_weissman_style_time_strings(self):
|
||||||
self.assertEqual(parse_duration_minutes('1 hr, 15 min'), 75)
|
self.assertEqual(parse_duration_minutes('1 hr, 15 min'), 75)
|
||||||
self.assertEqual(parse_duration_minutes('45 min + 12 hrs'), 765)
|
self.assertEqual(parse_duration_minutes('45 min + 12 hrs'), 765)
|
||||||
|
self.assertEqual(parse_duration_minutes('1 day + 30 min'), 1470)
|
||||||
|
self.assertEqual(parse_duration_minutes('1 hr + overnight'), 780)
|
||||||
|
self.assertEqual(parse_duration_minutes('1 hr 30 min + overnight'), 810)
|
||||||
self.assertEqual(parse_duration_minutes('30 minutes'), 30)
|
self.assertEqual(parse_duration_minutes('30 minutes'), 30)
|
||||||
self.assertEqual(parse_duration_minutes('90 sec'), 2)
|
self.assertEqual(parse_duration_minutes('90 sec'), 2)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user