Feat/add status filter to workflow runs (#26850)
Co-authored-by: Jacky Su <jacky_su@trendmicro.com>
This commit is contained in:
32
api/libs/custom_inputs.py
Normal file
32
api/libs/custom_inputs.py
Normal file
@@ -0,0 +1,32 @@
|
||||
"""Custom input types for Flask-RESTX request parsing."""
|
||||
|
||||
import re
|
||||
|
||||
|
||||
def time_duration(value: str) -> str:
|
||||
"""
|
||||
Validate and return time duration string.
|
||||
|
||||
Accepts formats: <number>d (days), <number>h (hours), <number>m (minutes), <number>s (seconds)
|
||||
Examples: 7d, 4h, 30m, 30s
|
||||
|
||||
Args:
|
||||
value: The time duration string
|
||||
|
||||
Returns:
|
||||
The validated time duration string
|
||||
|
||||
Raises:
|
||||
ValueError: If the format is invalid
|
||||
"""
|
||||
if not value:
|
||||
raise ValueError("Time duration cannot be empty")
|
||||
|
||||
pattern = r"^(\d+)([dhms])$"
|
||||
if not re.match(pattern, value.lower()):
|
||||
raise ValueError(
|
||||
"Invalid time duration format. Use: <number>d (days), <number>h (hours), "
|
||||
"<number>m (minutes), or <number>s (seconds). Examples: 7d, 4h, 30m, 30s"
|
||||
)
|
||||
|
||||
return value.lower()
|
||||
67
api/libs/time_parser.py
Normal file
67
api/libs/time_parser.py
Normal file
@@ -0,0 +1,67 @@
|
||||
"""Time duration parser utility."""
|
||||
|
||||
import re
|
||||
from datetime import UTC, datetime, timedelta
|
||||
|
||||
|
||||
def parse_time_duration(duration_str: str) -> timedelta | None:
|
||||
"""
|
||||
Parse time duration string to timedelta.
|
||||
|
||||
Supported formats:
|
||||
- 7d: 7 days
|
||||
- 4h: 4 hours
|
||||
- 30m: 30 minutes
|
||||
- 30s: 30 seconds
|
||||
|
||||
Args:
|
||||
duration_str: Duration string (e.g., "7d", "4h", "30m", "30s")
|
||||
|
||||
Returns:
|
||||
timedelta object or None if invalid format
|
||||
"""
|
||||
if not duration_str:
|
||||
return None
|
||||
|
||||
# Pattern: number followed by unit (d, h, m, s)
|
||||
pattern = r"^(\d+)([dhms])$"
|
||||
match = re.match(pattern, duration_str.lower())
|
||||
|
||||
if not match:
|
||||
return None
|
||||
|
||||
value = int(match.group(1))
|
||||
unit = match.group(2)
|
||||
|
||||
if unit == "d":
|
||||
return timedelta(days=value)
|
||||
elif unit == "h":
|
||||
return timedelta(hours=value)
|
||||
elif unit == "m":
|
||||
return timedelta(minutes=value)
|
||||
elif unit == "s":
|
||||
return timedelta(seconds=value)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def get_time_threshold(duration_str: str | None) -> datetime | None:
|
||||
"""
|
||||
Get datetime threshold from duration string.
|
||||
|
||||
Calculates the datetime that is duration_str ago from now.
|
||||
|
||||
Args:
|
||||
duration_str: Duration string (e.g., "7d", "4h", "30m", "30s")
|
||||
|
||||
Returns:
|
||||
datetime object representing the threshold time, or None if no duration
|
||||
"""
|
||||
if not duration_str:
|
||||
return None
|
||||
|
||||
duration = parse_time_duration(duration_str)
|
||||
if duration is None:
|
||||
return None
|
||||
|
||||
return datetime.now(UTC) - duration
|
||||
Reference in New Issue
Block a user