ungana

Unnamed repository; edit this file 'description' to name the repository.
Info | Log | Files | Refs | README

commit 3fa25344f494e66071fd15f3719d796cf9ca3a67
parent 6a10ea8690415396c61a1cde9ff56f91d9ca2b41
Author: Carlosokumu <carlosokumu254@gmail.com>
Date:   Mon,  1 Sep 2025 12:52:30 +0300

move datetime parsing to utils

Diffstat:
Mungana/cmd/args_parser.py | 50++++++++++++++------------------------------------
1 file changed, 14 insertions(+), 36 deletions(-)

diff --git a/ungana/cmd/args_parser.py b/ungana/cmd/args_parser.py @@ -6,9 +6,12 @@ import logging import sys from ungana.attachment.attachment_manager import AttachmentManager from ungana.ical.ical_manager import ICalManager +from ungana.ical.ical_helper import ICalHelper from ungana.logging.logging_manager import LoggingManager from dateutil import tz +from ungana.utils import validate_datetime, validate_duration + class ArgsParser: EMAIL_RE = re.compile(r"^[^@]+@[^@]+\.[^@]+$") @@ -27,31 +30,6 @@ class ArgsParser: except Exception as e: raise SystemExit(f"Error: Could not read file '{file_path}': {e}") - def _validate_datetime(self, dt_str: str) -> str: - try: - dt = datetime.fromisoformat(dt_str) - return dt.isoformat() - except ValueError: - pass - try: - dt = datetime.strptime(dt_str, "%d-%m-%Y %H:%M") - return dt.isoformat() - except ValueError: - pass - - raise argparse.ArgumentTypeError( - f"Invalid datetime format: '{dt_str}'. " - "Expected ISO format (YYYY-MM-DDTHH:MM:SS+ZZ:ZZ) or DD-MM-YYYY HH:MM" - ) - - def _validate_duration(self, duration_str: str) -> str: - """Validate duration format (e.g., '2h' or '30m').""" - if not re.match(r'^(\d+h)?(\d+m)?$', duration_str): - raise argparse.ArgumentTypeError( - f"Invalid duration format: '{duration_str}'. Expected format like '2h' or '30m'" - ) - return duration_str - def _add_command_arguments(self): subparsers = self.parser.add_subparsers(dest='command', required=True) @@ -74,7 +52,7 @@ class ArgsParser: help="Run interactive calendar creation") parser.add_argument("-s", "--summary", required=required, help="Event summary") - parser.add_argument("--start", type=self._validate_datetime, required=required,help="Event start time (ISO format or DD-MM-YYYY HH:MM)") + parser.add_argument("--start", type=validate_datetime, required=required,help="Event start time (ISO format or DD-MM-YYYY HH:MM)") parser.add_argument("-d", "--description",required=required, help="Event description") parser.add_argument("-l", "--location",required=required,help="Event location") parser.add_argument("-o", "--organizer",required=required,help="Event organizer") @@ -82,8 +60,8 @@ class ArgsParser: parser.add_argument("--sf", "--summary-file", dest="summary_file", help="File containing event summary") parser.add_argument("--df", "--description-file", dest="description_file", help="File containing event description") parser.add_argument("--tzid", help="Time zone ID") - parser.add_argument("--duration", type=self._validate_duration, help="Event duration") - parser.add_argument("--end", type=self._validate_datetime, help="Event end time") + parser.add_argument("--duration", type=validate_duration, help="Event duration") + parser.add_argument("--end", type=validate_datetime, help="Event end time") def add_create_args(self, parser): @@ -96,7 +74,7 @@ class ArgsParser: non_interactive = parser.add_argument_group("non-interactive arguments") non_interactive.add_argument("-s", "--summary", help="Event summary") - non_interactive.add_argument("--start", type=self._validate_datetime, help="Event start time (ISO format or DD-MM-YYYY HH:MM)") + non_interactive.add_argument("--start", type=validate_datetime, help="Event start time (ISO format or DD-MM-YYYY HH:MM)") non_interactive.add_argument("-d", "--description", help="Event description") non_interactive.add_argument("-l", "--location", help="Event location") non_interactive.add_argument("-o", "--organizer", help="Event organizer") @@ -108,8 +86,8 @@ class ArgsParser: parser.add_argument("--domain", help="Domain used to generate event UID (default: ungana.local)",default="ungana.local") event_end_time_group = non_interactive.add_mutually_exclusive_group(required=False) - event_end_time_group.add_argument("--end", type=self._validate_datetime,help="Event end time (ISO format or DD-MM-YYYY HH:MM). ""Required if no --duration is specified.",) - event_end_time_group.add_argument( "--duration",type=self._validate_duration, help="Event duration (e.g shorthand like '1h30m'). Required if no --end is specified.",) + event_end_time_group.add_argument("--end", type=validate_datetime,help="Event end time (ISO format or DD-MM-YYYY HH:MM). ""Required if no --duration is specified.",) + event_end_time_group.add_argument( "--duration",type=validate_duration, help="Event duration (e.g shorthand like '1h30m'). Required if no --end is specified.",) @@ -235,7 +213,7 @@ class ArgsParser: if args.ics_filename: filename = args.ics_filename cal = self.ical_manager.load_ical_file(filename) - exists = self.ical_manager.check_existing_event(cal, event_data) + exists = ICalHelper.check_existing_event(cal, event_data) if exists: details = ( f"Summary='{event_data['summary']}', " @@ -271,7 +249,7 @@ class ArgsParser: updates, attachments = self._get_user_updates_from_args(args) if any([updates, attachments]): # Non-interactive mode - self.ical_manager.update_event(cal, updates, attachments, ical_file_path) + ICalHelper.update_event(cal, updates, attachments, ical_file_path) logging.info("Calendar updated successfully") else: # Interactive mode @@ -279,7 +257,7 @@ class ArgsParser: def _edit_most_recent_event(self, cal, args, ical_file_path): - event = self.ical_manager.get_first_event(cal) + event = ICalHelper.get_first_event(cal) # only interactive prompts updates = self._get_user_event_updates(event) @@ -293,7 +271,7 @@ class ArgsParser: def _edit_multiple_events(self, cal, ical_file_path): """Edit a specific event from multiple events (requires --all).""" - events = self.ical_manager.get_all_events(cal) + events = ICalHelper.get_all_events(cal) if not events: self.parser.error("no events found for the selected ical file") return @@ -321,7 +299,7 @@ class ArgsParser: updates = self._get_user_event_updates(event) if updates: - self.ical_manager.update_event(cal, updates, None, ical_file_path) + ICalHelper.update_event(cal, updates, None, ical_file_path) logging.info("Calendar updated successfully") else: logging.info("No changes made to calendar file")