commit dacd73873cbecc76b4163ee780303c0e67475d16
parent da3bcf7252af3dbdc3ce79d6ca2eadda6afc054f
Author: Carlosokumu <carlosokumu254@gmail.com>
Date: Tue, 19 Aug 2025 00:20:16 +0300
breakdown parse_args and add a run dispatcher
Diffstat:
1 file changed, 136 insertions(+), 118 deletions(-)
diff --git a/calendarapp/cmd/args_parser.py b/calendarapp/cmd/args_parser.py
@@ -3,7 +3,6 @@ from pathlib import Path
from datetime import datetime
import re
import logging
-
from calendarapp.ical.ical_manager import ICalManager
from calendarapp.logging.logging_manager import LoggingManager
@@ -91,127 +90,147 @@ class ArgsParser:
help="Enable verbose debug output")
parser.add_argument("-q", "--quiet", action="store_true",
help="Suppress all non-error output")
-
+
def parse_args(self):
"""Parses CLI args and resolves file-based inputs."""
args = self.parser.parse_args()
-
self.logging = LoggingManager(verbose=args.verbose, quiet=args.quiet)
self.logger = self.logging.get_logger("ArgsParser")
+ return args
+
+
+ def handle_create(self, args):
+ if args.summary_file:
+ args.summary = self._read_file_or_exit(args.summary_file)
+ if args.description_file:
+ args.description = self._read_file_or_exit(args.description_file)
+
+ if not args.end and not args.duration:
+ self.parser.error("Either --end or --duration must be specified")
- if args.command == 'create':
- if args.summary_file:
- args.summary = self._read_file_or_exit(args.summary_file)
- if args.description_file:
- args.description = self._read_file_or_exit(args.description_file)
-
- if not args.end and not args.duration:
- self.parser.error("Either --end or --duration must be specified")
-
- args.start_dt = datetime.fromisoformat(args.start)
-
- # Calculate duration if endtime is provided
- if args.end:
- end_dt = datetime.fromisoformat(args.end)
- duration = end_dt - args.start_dt
- args.duration = f"{duration.seconds//3600}h{(duration.seconds%3600)//60}m"
-
- event_data = {
- 'start': args.start_dt,
- 'duration': args.duration,
- 'summary': args.summary,
- 'location': args.location,
- 'description': args.description,
- 'organizer': args.organizer,
- 'tzid': args.tzid
- }
- event = self.ical_manager.create_event(event_data)
- self.ical_manager.save_ical_file(event, 'event.ics')
- if args.command == 'edit':
- if not args.ical:
- self.parser.error("missing required ical file path to edit")
-
- ical_file_path = args.ical
- try:
- cal = self.ical_manager.load_ical_file(ical_file_path)
- except (FileNotFoundError, ValueError) as e:
- self.parser.error("corrupted or missing ical file")
-
- if args.all:
- events = self.ical_manager.get_all_events(cal)
-
- if not events:
- self.parser.error("no events found for the selected ical file")
- return
-
- for idx, e in enumerate(events, start=1):
- summary = e.get("SUMMARY", "No title")
- start = e.get("DTSTART")
- if isinstance(start, list):
- start = start[0]
-
- start_str = start.dt if hasattr(start, "dt") else "No date"
- print(f"{idx}. {summary} — {start_str}")
-
- try:
- choice = int(input("\nEnter the number of the event you want to edit: "))
- if not (1 <= choice <= len(events)):
- raise ValueError
- except ValueError:
- self.parser.error("invalid selection")
- return
- except KeyboardInterrupt:
- self.parser.error("Operation cancelled by user")
- return
-
- event = events[choice - 1]
- editable_fields = list(event.keys())
-
- skip_fields = {"UID"}
- editable_fields = [f for f in editable_fields if f not in skip_fields]
-
- updates = {}
-
- for field in editable_fields:
- current_value = event.get(field, "")
- new_value = input(f"{field} [{current_value}]: ").strip()
- if new_value:
- updates[field] = new_value
-
- if updates:
- self.ical_manager.update_event(cal, updates, ical_file_path)
- logging.info("Calendar updated successfully")
- else:
- logging.info("No changes made to calendar file")
-
- else:
- updates = {}
-
- if args.start is not None:
- updates["DTSTART"] = args.start
-
- if args.duration is not None:
- updates["DURATION"] = args.duration
-
- if args.summary is not None:
- updates["SUMMARY"] = args.summary
-
- if args.location is not None:
- updates["LOCATION"] = args.location
-
- if args.description is not None:
- updates["DESCRIPTION"] = args.description
-
- if args.organizer is not None:
- updates["ORGANIZER"] = args.organizer
-
- try:
- self.ical_manager.update_event(cal, updates, ical_file_path)
- logging.info("Event updated successfully!")
- except Exception as e:
- logging.error(f"Event not found: {e}")
- self.parser.error("An error occurred while updating ical file")
-
- return args
-\ No newline at end of file
+ args.start_dt = datetime.fromisoformat(args.start)
+
+ if args.end:
+ end_dt = datetime.fromisoformat(args.end)
+ duration = end_dt - args.start_dt
+ args.duration = f"{duration.seconds//3600}h{(duration.seconds%3600)//60}m"
+
+ event_data = {
+ 'start': args.start_dt,
+ 'duration': args.duration,
+ 'summary': args.summary,
+ 'location': args.location,
+ 'description': args.description,
+ 'organizer': args.organizer,
+ 'tzid': args.tzid
+ }
+
+ event = self.ical_manager.create_event(event_data)
+ self.ical_manager.save_ical_file(event, 'event.ics')
+
+ def handle_edit(self, args):
+ if not args.ical:
+ self.parser.error("missing required ical file path to edit")
+
+ ical_file_path = args.ical
+ try:
+ cal = self.ical_manager.load_ical_file(ical_file_path)
+ except (FileNotFoundError, ValueError):
+ self.parser.error("corrupted or missing ical file")
+
+ if args.all:
+ self._edit_multiple_events(cal, ical_file_path)
+ else:
+ self._edit_most_recent_event(cal,args,ical_file_path)
+
+
+
+ def _edit_most_recent_event(self, cal, args, ical_file_path):
+ """Edit the first event in the calendar (default)."""
+ updates = {}
+
+ if args.start is not None:
+ updates["DTSTART"] = args.start
+ if args.duration is not None:
+ updates["DURATION"] = args.duration
+ if args.summary is not None:
+ updates["SUMMARY"] = args.summary
+ if args.location is not None:
+ updates["LOCATION"] = args.location
+ if args.description is not None:
+ updates["DESCRIPTION"] = args.description
+ if args.organizer is not None:
+ updates["ORGANIZER"] = args.organizer
+
+ event = self.ical_manager.get_first_event(cal)
+ editable_fields = [f for f in event.keys() if f != "UID"]
+
+ for field in editable_fields:
+ current_value = event.get(field, "")
+ new_value = input(f"{field} [{current_value}]: ").strip()
+ if new_value:
+ updates[field] = new_value
+
+ if updates:
+ self.ical_manager.update_event(cal, updates, ical_file_path)
+ self.logging.info("Calendar updated successfully")
+ else:
+ self.logging.info("No changes made to calendar file")
+
+
+ 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)
+ if not events:
+ self.parser.error("no events found for the selected ical file")
+ return
+
+ # List all available events
+ for idx, e in enumerate(events, start=1):
+ summary = e.get("SUMMARY", "No title")
+ start = e.get("DTSTART")
+ if isinstance(start, list):
+ start = start[0]
+ start_str = start.dt if hasattr(start, "dt") else "No date"
+ print(f"{idx}. {summary} — {start_str}")
+
+ try:
+ choice = int(input("\nEnter the number of the event you want to edit: "))
+ if not (1 <= choice <= len(events)):
+ raise ValueError
+ except ValueError:
+ self.parser.error("invalid selection")
+ return
+ except KeyboardInterrupt:
+ self.parser.error("Operation cancelled by user")
+ return
+
+ event = events[choice - 1]
+ editable_fields = [f for f in event.keys() if f != "UID"]
+
+ updates = {}
+ for field in editable_fields:
+ current_value = event.get(field, "")
+ new_value = input(f"{field} [{current_value}]: ").strip()
+ if new_value:
+ updates[field] = new_value
+
+ if updates:
+ self.ical_manager.update_event(cal, updates, ical_file_path)
+ logging.info("Calendar updated successfully")
+ else:
+ logging.info("No changes made to calendar file")
+
+
+
+ def run(self):
+ args = self.parse_args()
+
+ if args.command == "create":
+ self.handle_create(args)
+ elif args.command == "edit":
+ self.handle_edit(args)
+ else:
+ self.parser.error(f"Unknown command: {args.command}")