mirror of
https://github.com/ArchiveBox/ArchiveBox.git
synced 2026-09-14 11:06:13 +05:00
Renames (no functional change, just consistency with the rest of the codebase): - cli/cli_utils.py → cli/cli_util.py - core/host_utils.py → core/host_util.py - core/tag_utils.py → core/tag_util.py - crawls/schedule_utils.py → crawls/schedule_util.py - machine/env_utils.py → machine/env_util.py Functional fixes: - archivebox add --index-only now materializes Snapshot rows synchronously via crawl.create_snapshots_from_urls() instead of just queueing the Crawl and leaving the index empty. The previous behavior broke every test that expected --index-only to populate the index, since the runner is never started in index-only mode. - config/collection.py: add _coerce_from_str_dict as the inverse of _coerce_to_str_dict so JSON-encoded INI values are decoded back to native dict/list types when mirrored into Machine.config (a JSONField). Without this, downstream consumers like MachineEvent / abx-dl get raw JSON strings where they expect dicts. Plus matching admin / middleware / model touch-ups, the registration password_change_form template, and assorted small cleanups the user worked through while validating the deploy path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
44 lines
1.1 KiB
Python
44 lines
1.1 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
|
|
from croniter import croniter
|
|
|
|
|
|
SCHEDULE_ALIASES: dict[str, str] = {
|
|
"minute": "* * * * *",
|
|
"minutely": "* * * * *",
|
|
"hour": "0 * * * *",
|
|
"hourly": "0 * * * *",
|
|
"day": "0 0 * * *",
|
|
"daily": "0 0 * * *",
|
|
"week": "0 0 * * 0",
|
|
"weekly": "0 0 * * 0",
|
|
"month": "0 0 1 * *",
|
|
"monthly": "0 0 1 * *",
|
|
"year": "0 0 1 1 *",
|
|
"yearly": "0 0 1 1 *",
|
|
}
|
|
|
|
|
|
def normalize_schedule(schedule: str) -> str:
|
|
normalized = (schedule or "").strip()
|
|
if not normalized:
|
|
raise ValueError("Schedule cannot be empty.")
|
|
|
|
return SCHEDULE_ALIASES.get(normalized.lower(), normalized)
|
|
|
|
|
|
def validate_schedule(schedule: str) -> str:
|
|
normalized = normalize_schedule(schedule)
|
|
if not croniter.is_valid(normalized):
|
|
raise ValueError(
|
|
"Invalid schedule. Use an alias like daily/weekly/monthly or a cron expression such as '0 */6 * * *'.",
|
|
)
|
|
return normalized
|
|
|
|
|
|
def next_run_for_schedule(schedule: str, after: datetime) -> datetime:
|
|
normalized = validate_schedule(schedule)
|
|
return croniter(normalized, after).get_next(datetime)
|