ungana

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

commit f0f8c87a84cb7140f43729d881b69ec4d742bb0d
parent ab15a6a81a3fa7f708da0123d473cdb67cdc575b
Author: Carlosokumu <carlosokumu254@gmail.com>
Date:   Tue, 11 Nov 2025 12:44:44 +0300

feat: add a merge command

Diffstat:
Mungana/cmd/args_parser.py | 44++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 42 insertions(+), 2 deletions(-)

diff --git a/ungana/cmd/args_parser.py b/ungana/cmd/args_parser.py @@ -10,16 +10,18 @@ from ungana.ical.ical_helper import ICalHelper from ungana.logging.logging_manager import LoggingManager from dateutil import tz +from ungana.store.resolve import resolve_backend_store from ungana.utils import validate_datetime, validate_duration class ArgsParser: EMAIL_RE = re.compile(r"^[^@]+@[^@]+\.[^@]+$") - def __init__(self): + def __init__(self,cfg): self.parser = argparse.ArgumentParser( description="Create a customized iCalendar (.ics) event" ) + self.cfg = cfg self.ical_manager = ICalManager() self._add_command_arguments() @@ -50,6 +52,19 @@ class ArgsParser: help="If your ical file has more than one event, interactively choose one to edit") edit_event_parser.set_defaults(func=lambda args: self.handle_edit(args, edit_event_parser)) + merge_events_parser = subparsers.add_parser('merge', help='Merge multiple .ics event files into one') + merge_events_parser.add_argument( + "-i", "--input-dir", + default="./events", + help="Directory to look for .ics files (default: ./events)" + ) + merge_events_parser.add_argument( + "-o", "--output", + default="merged_events.ics", + help="Output merged .ics filename (default: merged_events.ics)" + ) + self._add_logging_arguments(merge_events_parser) + merge_events_parser.set_defaults(func=lambda args: self.handle_merge(args)) def add_common_args(self, parser, required=False): parser.add_argument("-s", "--summary",type = self._ensure_no_multiline_input, required=required, help="Event summary") @@ -107,7 +122,7 @@ class ArgsParser: args = self.parser.parse_args() self.logging = LoggingManager(verbose=args.verbose, quiet=args.quiet) self.logger = self.logging.get_logger("ArgsParser") - self.attachment_manager = AttachmentManager(logger=self.logging.get_logger("AttachmentManager")) + self.attachment_manager = AttachmentManager(cfg=self.cfg,logger=self.logging.get_logger("AttachmentManager")) return args def _prompt_datetime(self, prompt: str, allow_blank: bool = False): @@ -259,6 +274,29 @@ class ArgsParser: self._edit_most_recent_event(cal, args, ical_file_path) + def handle_merge(self, args): + try: + data_bytes,output_path = ICalHelper.merge_calendars( + events_dir=args.input_dir, + output_file=args.output + ) + obj_stores = self.cfg.get("OBJ_STORES") + self.logger.info(f"number of obj_stores: {len(obj_stores)}") + for obj_store in obj_stores: + try: + store = resolve_backend_store(obj_store) + key = self.attachment_manager.digest(output_path) + url = store.put(obj_store, key, data_bytes) + self.logger.debug(f"Data write to: {url} with key: {key}") + except Exception as e: + self.logger.error( + f"Failed to write data store '{obj_store}': {e}", + exc_info=True + ) + except Exception as e: + self.parser.error(f"Failed to merge calendars: {e}") + + def _edit_most_recent_event(self, cal, args, ical_file_path): event = ICalHelper.get_first_event(cal) @@ -512,5 +550,7 @@ class ArgsParser: self.handle_create(args) elif args.command == "edit": self.handle_edit(args) + elif args.command == "merge": + self.handle_merge(args) else: self.parser.error(f"Unknown command: {args.command}")