Add NLP, scheduler, generator, and describer modules
Some checks failed
CI / test (push) Has been cancelled
Some checks failed
CI / test (push) Has been cancelled
This commit is contained in:
266
src/cronparse/generator.py
Normal file
266
src/cronparse/generator.py
Normal 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,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user