Add NLP, scheduler, generator, and describer modules
Some checks failed
CI / test (push) Has been cancelled

This commit is contained in:
2026-02-01 15:08:39 +00:00
parent e06465760a
commit 14cff59527

266
src/cronparse/generator.py Normal file
View File

@@ -0,0 +1,266 @@
"""Interactive cron generator wizard module."""
import click
from typing import Dict, Any, List, Tuple
MINUTE_CHOICES = [
("Every minute", "*"),
("Every 5 minutes", "*/5"),
("Every 10 minutes", "*/10"),
("Every 15 minutes", "*/15"),
("Every 30 minutes", "0"),
("Specific minutes", "specific"),
]
HOUR_CHOICES = [
("Every hour", "*"),
("Every 2 hours", "*/2"),
("Every 4 hours", "*/4"),
("Every 6 hours", "*/6"),
("Every 12 hours", "*/12"),
("Specific hour", "specific"),
]
DAY_CHOICES = [
("Every day", "*"),
("Every 2 days", "*/2"),
("Every 3 days", "*/3"),
("Specific day of month", "specific"),
]
MONTH_CHOICES = [
("Every month", "*"),
("Every 2 months", "*/2"),
("Every 3 months", "*/3"),
("Every 6 months", "*/6"),
("Specific month", "specific"),
]
DOW_CHOICES = [
("Every day of week", "*"),
("Monday to Friday (weekdays)", "1-5"),
("Saturday and Sunday (weekend)", "0,6"),
("Specific day", "specific"),
]
def prompt_minute() -> str:
"""Prompt user for minute selection."""
click.echo("\nMinute selection:")
for i, (desc, value) in enumerate(MINUTE_CHOICES, 1):
click.echo(f" {i}. {desc}")
choice = click.prompt("Select (1-6)", type=int, default=1)
if choice == 1:
return "*"
elif choice == 2:
return "*/5"
elif choice == 3:
return "*/10"
elif choice == 4:
return "*/15"
elif choice == 5:
return "0"
elif choice == 6:
minutes = prompt_specific_values("minute", 0, 59)
return ",".join(map(str, minutes))
else:
return "*"
def prompt_hour() -> str:
"""Prompt user for hour selection."""
click.echo("\nHour selection:")
for i, (desc, value) in enumerate(HOUR_CHOICES, 1):
click.echo(f" {i}. {desc}")
choice = click.prompt("Select (1-6)", type=int, default=1)
if choice == 1:
return "*"
elif choice == 2:
return "*/2"
elif choice == 3:
return "*/4"
elif choice == 4:
return "*/6"
elif choice == 5:
return "*/12"
elif choice == 6:
hours = prompt_specific_values("hour", 0, 23)
return ",".join(map(str, hours))
else:
return "*"
def prompt_day() -> str:
"""Prompt user for day of month selection."""
click.echo("\nDay of month selection:")
for i, (desc, value) in enumerate(DAY_CHOICES, 1):
click.echo(f" {i}. {desc}")
choice = click.prompt("Select (1-4)", type=int, default=1)
if choice == 1:
return "*"
elif choice == 2:
return "*/2"
elif choice == 3:
return "*/3"
elif choice == 4:
days = prompt_specific_values("day", 1, 31)
return ",".join(map(str, days))
else:
return "*"
def prompt_month() -> str:
"""Prompt user for month selection."""
click.echo("\nMonth selection:")
for i, (desc, value) in enumerate(MONTH_CHOICES, 1):
click.echo(f" {i}. {desc}")
choice = click.prompt("Select (1-5)", type=int, default=1)
if choice == 1:
return "*"
elif choice == 2:
return "*/2"
elif choice == 3:
return "*/3"
elif choice == 4:
return "*/6"
elif choice == 5:
months = prompt_specific_values("month", 1, 12)
return ",".join(map(str, months))
else:
return "*"
def prompt_dow() -> str:
"""Prompt user for day of week selection."""
click.echo("\nDay of week selection:")
for i, (desc, value) in enumerate(DOW_CHOICES, 1):
click.echo(f" {i}. {desc}")
choice = click.prompt("Select (1-4)", type=int, default=1)
if choice == 1:
return "*"
elif choice == 2:
return "1-5"
elif choice == 3:
return "0,6"
elif choice == 4:
days = prompt_specific_dow_values()
return ",".join(map(str, days))
else:
return "*"
def prompt_specific_values(name: str, min_val: int, max_val: int) -> List[int]:
"""Prompt user for specific values within a range.
Args:
name: Name of the field (for display).
min_val: Minimum value.
max_val: Maximum value.
Returns:
List of selected values.
"""
values = []
while True:
prompt_text = f"Enter {name} ({min_val}-{max_val}), or 'done' to finish"
value = click.prompt(prompt_text, type=str, default="done")
if value.lower() == "done":
if not values:
click.echo(f"No values selected. Using {min_val}.")
values = [min_val]
break
try:
val = int(value)
if min_val <= val <= max_val:
if val not in values:
values.append(val)
else:
click.echo(f" {val} already selected.")
else:
click.echo(f" Invalid {name}. Must be between {min_val} and {max_val}.")
except ValueError:
click.echo(" Invalid input. Enter a number or 'done'.")
return sorted(values)
def prompt_specific_dow_values() -> List[int]:
"""Prompt user for specific day of week values.
Returns:
List of selected day numbers (0=Sunday).
"""
click.echo(" Select days of week:")
click.echo(" 0 = Sunday 4 = Thursday")
click.echo(" 1 = Monday 5 = Friday")
click.echo(" 2 = Tuesday 6 = Saturday")
click.echo(" 3 = Wednesday")
values = []
while True:
prompt_text = "Enter day (0-6), or 'done' to finish"
value = click.prompt(prompt_text, type=str, default="done")
if value.lower() == "done":
if not values:
click.echo("No values selected. Using 0 (Sunday).")
values = [0]
break
try:
val = int(value)
if 0 <= val <= 6:
if val not in values:
values.append(val)
else:
click.echo(f" {val} already selected.")
else:
click.echo(" Invalid day. Must be between 0 and 6.")
except ValueError:
click.echo(" Invalid input. Enter a number or 'done'.")
return sorted(values)
def generate_cron_interactive() -> Dict[str, Any]:
"""Run interactive wizard to generate a cron expression.
Returns:
Dict with 'cron' and 'fields'.
"""
click.echo(click.style("Cron Expression Wizard", fg="cyan", bold=True))
click.echo("=" * 50)
click.echo("This wizard will help you create a cron expression.")
click.echo("Press Ctrl+C at any time to cancel.\n")
minute = prompt_minute()
hour = prompt_hour()
day = prompt_day()
month = prompt_month()
dow = prompt_dow()
cron = f"{minute} {hour} {day} {month} {dow}"
return {
"cron": cron,
"fields": {
"minute": minute,
"hour": hour,
"day": day,
"month": month,
"day_of_week": dow,
}
}