diff --git a/progscheduler/app.py b/progscheduler/app.py index bf77cb2..570d317 100644 --- a/progscheduler/app.py +++ b/progscheduler/app.py @@ -45,9 +45,9 @@ def run_scheduler(arguments): os.system(f'taskkill /f /fi "WINDOWTITLE eq kill_current_terminal_window"') -def is_time_to_stop_valid(program_name, time_to_stop): +def is_time_to_stop(program_name, time_to_stop): if time_to_stop != 'off'.lower(): - now = datetime.utcnow() + now = datetime.now() time = time_to_stop.split(':') if now.hour >= int(time[0]) and now.minute > int(time[1]): show('Option: \"time-to-stop\" is enabled for \'' + program_name + '\' and it will not run. Defined time: ' + @@ -61,20 +61,34 @@ def is_scheduled_today(days_to_schedule): return now.strftime("%A").lower() in days_to_schedule -def is_status_valid(program_name, status): +def is_job_active(program_name, status): if status.lower() == 'off'.lower(): show('\"' + program_name + '\" is inactive and it will not run. Status: OFF.') - return True + return False + return True + + +def is_excluded_day(program_name, excluded_days): + for date in excluded_days: + saved_date = date.split('/') + validate_date = datetime(day=int(saved_date[0]), month=int(saved_date[1]), year=int(saved_date[2])) + if validate_date == datetime.combine(datetime.today().date(), datetime.min.time()): + show('Today \"' + program_name + '\" will not run. ' + validate_date.strftime('%d/%m/%Y') + ' is an excluded date.') + return True + return False def scheduled_job_invalid(program): if not is_scheduled_today(program.days.value): return True - if is_time_to_stop_valid(program.alias.value, program.time_to_stop.value): + if is_time_to_stop(program.alias.value, program.time_to_stop.value): + return True + + if not is_job_active(program.alias.value, program.status.value): return True - if is_status_valid(program.alias.value, program.status.value): + if is_excluded_day(program.alias.value, program.exclude.value): return True return False diff --git a/progscheduler/settings/specific_arguments.py b/progscheduler/settings/specific_arguments.py index fa6e10b..e1407df 100644 --- a/progscheduler/settings/specific_arguments.py +++ b/progscheduler/settings/specific_arguments.py @@ -1,10 +1,11 @@ import argparse +from datetime import datetime from margument.argument import Argument from margument.arguments import Arguments from progscheduler.utils.directory import Directory -from progscheduler.utils.log import throw +from progscheduler.utils.log import throw, show class Specific(Arguments): @@ -65,6 +66,16 @@ def __init__(self): to_save=True, default='on') + self.exclude = Argument(name='exclude', + abbreviation_name='-ex', + full_name='--exclude', + help_message='This indicates the specific days for when a specific scheduled job will not run. Can be added multiple ' + 'dates in the format dd/mm/yyyy. Default value is empty. example: -ex 29/03/2023 25/12/2023. [NOTE]: ' + 'Any dates inserted will be replacing dates configured before.', + metavar="", + to_save=True, + default=[]) + def set_are_configs_saved(self, are_configs_saved): self.are_configs_saved = are_configs_saved @@ -106,11 +117,18 @@ def add_arguments(self, args_parser): metavar=self.status.metavar, default=argparse.SUPPRESS) + args_parser.add_argument(self.exclude.abbreviation_name, self.exclude.full_name, + nargs='*', + help=self.exclude.help_message, + metavar=self.exclude.metavar, + default=argparse.SUPPRESS) + def process_arguments(self, settings): - self.__check_any_errors(settings[0].user_arguments) - self.__process_days(settings[0].user_arguments) + self.__validate_exclude_dates(settings[0].user_arguments) + self.__validate_path(settings[0].user_arguments) + self.__validate_days(settings[0].user_arguments) - def __process_days(self, user_arguments): + def __validate_days(self, user_arguments): if self.days.name in user_arguments: if user_arguments.days[0] == 'weekdays': user_arguments.days = self.__get_specific_days('weekdays') @@ -119,12 +137,21 @@ def __process_days(self, user_arguments): elif user_arguments.days[0] == 'everyday': user_arguments.days = self.__get_specific_days('everyday') - def __check_any_errors(self, user_args): - try: - if not self.__given_argument_path_exists(user_args.path): - throw(user_args.path + '\' path does not exist.') - except (AttributeError, TypeError): - pass + def __validate_exclude_dates(self, user_arguments): + if self.exclude.name in user_arguments: + for date in user_arguments.exclude: + user_date = date.split('/') + try: + validate_date = datetime(day=int(user_date[0]), month=int(user_date[1]), year=int(user_date[2])) + if validate_date < datetime.combine(datetime.today().date(), datetime.min.time()): + show('\'' + date + '\': is an old date. It will be ignored.', to_exit=True) + except ValueError: + throw('\'' + date + '\': date not valid.') + + def __validate_path(self, user_arguments): + if self.path.name in user_arguments: + if not self.__given_argument_path_exists(user_arguments.path): + throw('\'' + user_arguments.path + '\' path does not exist.') def __get_specific_days(self, days_specified): days = []