commit f0f8c87a84cb7140f43729d881b69ec4d742bb0d
parent ab15a6a81a3fa7f708da0123d473cdb67cdc575b
Author: Carlosokumu <carlosokumu254@gmail.com>
Date: Tue, 11 Nov 2025 12:44:44 +0300
feat: add a merge command
Diffstat:
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}")