12345678910111213141516171819202122232425262728293031323334353637383940414243444546 |
- import re
- from datetime import datetime, timedelta
- from typing import Annotated
- from django.utils import timezone
- from pydantic import BeforeValidator, Field
- SlugStr = Annotated[str, Field(pattern=r"^[-a-zA-Z0-9_]+$", max_length=50)]
- # RELATIVE_TIME_REGEX = re.compile(r"now[+-]\d+[mhd]")
- RELATIVE_TIME_REGEX = re.compile(r"now\s*\-\s*\d+\s*(m|h|d)\s*$")
- def parse_relative_datetime(value: str) -> datetime:
- """
- Allow relative terms like now or now-1h. Only 0 or 1 math operation is permitted.
- Accepts
- - now
- - + (addition)
- - - (subtraction)
- - m (minutes)
- - h (hours)
- - d (days)
- """
- if value == "now":
- return timezone.now()
- match = RELATIVE_TIME_REGEX.match(value)
- if match:
- now = timezone.now()
- stripped_value = value.replace(" ", "")
- sign = 1 if "+" in stripped_value else -1
- number = int(re.findall(r"\d+", stripped_value)[0])
- if "m" in stripped_value:
- return now + sign * timedelta(minutes=number)
- elif "h" in stripped_value:
- return now + sign * timedelta(hours=number)
- elif "d" in stripped_value:
- return now + sign * timedelta(days=number)
- return value
- RelativeDateTime = Annotated[datetime, BeforeValidator(parse_relative_datetime)]
|