refac
This commit is contained in:
@@ -163,7 +163,7 @@ async def create_new_automation(
|
|||||||
):
|
):
|
||||||
await check_automations_permission(request, user)
|
await check_automations_permission(request, user)
|
||||||
try:
|
try:
|
||||||
validate_rrule(form_data.data.rrule)
|
validate_rrule(form_data.data.rrule, tz=user.timezone)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
@@ -213,7 +213,7 @@ async def update_automation_by_id(
|
|||||||
check_automation_access(automation, user)
|
check_automation_access(automation, user)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
validate_rrule(form_data.data.rrule)
|
validate_rrule(form_data.data.rrule, tz=user.timezone)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
|||||||
@@ -2575,7 +2575,7 @@ async def create_automation(
|
|||||||
|
|
||||||
# Validate the RRULE
|
# Validate the RRULE
|
||||||
try:
|
try:
|
||||||
validate_rrule(rrule)
|
validate_rrule(rrule, tz=user.timezone)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
return json.dumps({'error': f'Invalid schedule: {e}'})
|
return json.dumps({'error': f'Invalid schedule: {e}'})
|
||||||
|
|
||||||
@@ -2656,7 +2656,7 @@ async def update_automation(
|
|||||||
# Validate RRULE if changed
|
# Validate RRULE if changed
|
||||||
if rrule is not None:
|
if rrule is not None:
|
||||||
try:
|
try:
|
||||||
validate_rrule(new_rrule)
|
validate_rrule(new_rrule, tz=user.timezone if user else None)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
return json.dumps({'error': f'Invalid schedule: {e}'})
|
return json.dumps({'error': f'Invalid schedule: {e}'})
|
||||||
|
|
||||||
|
|||||||
@@ -61,13 +61,19 @@ def _parse_rule(s: str):
|
|||||||
return rrulestr(s, ignoretz=True)
|
return rrulestr(s, ignoretz=True)
|
||||||
|
|
||||||
|
|
||||||
def validate_rrule(s: str) -> None:
|
def validate_rrule(s: str, tz: str = None) -> None:
|
||||||
"""Raise ValueError if the RRULE is malformed or exhausted."""
|
"""Raise ValueError if the RRULE is malformed or exhausted.
|
||||||
|
|
||||||
|
When *tz* is provided the "now" reference uses the user's local
|
||||||
|
clock so that near-future schedules are not incorrectly rejected
|
||||||
|
on servers whose system clock is ahead (e.g. UTC vs US timezones).
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
rule = _parse_rule(s)
|
rule = _parse_rule(s)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise ValueError(ERROR_MESSAGES.AUTOMATION_INVALID_RRULE(e))
|
raise ValueError(ERROR_MESSAGES.AUTOMATION_INVALID_RRULE(e))
|
||||||
if rule.after(datetime.now()) is None:
|
now = datetime.now(ZoneInfo(tz)).replace(tzinfo=None) if tz else datetime.now()
|
||||||
|
if rule.after(now) is None:
|
||||||
raise ValueError(ERROR_MESSAGES.AUTOMATION_NO_FUTURE_RUNS)
|
raise ValueError(ERROR_MESSAGES.AUTOMATION_NO_FUTURE_RUNS)
|
||||||
|
|
||||||
|
|
||||||
@@ -83,10 +89,15 @@ def next_run_ns(s: str, tz: str = None) -> Optional[int]:
|
|||||||
|
|
||||||
|
|
||||||
def next_n_runs_ns(s: str, n: int = 5, tz: str = None) -> list[int]:
|
def next_n_runs_ns(s: str, n: int = 5, tz: str = None) -> list[int]:
|
||||||
"""Compute next N occurrences for UI preview."""
|
"""Compute next N occurrences for UI preview.
|
||||||
|
|
||||||
|
Uses the user's timezone for the starting "now" so that the
|
||||||
|
preview matches the user's local clock (same as next_run_ns).
|
||||||
|
"""
|
||||||
rule = _parse_rule(s)
|
rule = _parse_rule(s)
|
||||||
result = []
|
result = []
|
||||||
dt = datetime.now()
|
now = datetime.now(ZoneInfo(tz)).replace(tzinfo=None) if tz else datetime.now()
|
||||||
|
dt = now
|
||||||
for _ in range(n):
|
for _ in range(n):
|
||||||
dt = rule.after(dt)
|
dt = rule.after(dt)
|
||||||
if not dt:
|
if not dt:
|
||||||
|
|||||||
Reference in New Issue
Block a user