Command-line and Emacs Calendar Client
1open Cmdliner 2open Caledonia_lib 3open Event_args 4 5let run ~summary ~start_date ~start_time ~end_date ~end_time ~location 6 ~description ~recur ~calendar_name ?timezone ?end_timezone ~fs calendar_dir 7 = 8 let ( let* ) = Result.bind in 9 let* start = parse_start ~start_date ~start_time ~timezone in 10 let* start = 11 match start with 12 | Some s -> Ok s 13 | None -> Error (`Msg "Start date required") 14 in 15 let* end_ = 16 (* if we have an endtime and no end date default to start date *) 17 let end_date = 18 match (end_date, end_time) with 19 | None, Some _ -> start_date 20 | _ -> end_date 21 in 22 (* if we have a start date and no end date default to start date *) 23 let end_date = 24 match (start_date, end_date) with 25 | Some _, None -> start_date 26 | _ -> end_date 27 in 28 let end_timezone = 29 (* if we specify and end date and time without a end timezone, default to the start timezone *) 30 match (end_date, end_time, end_timezone) with 31 | Some _, Some _, None -> timezone 32 | _ -> end_timezone 33 in 34 parse_end ~end_date ~end_time ~end_timezone 35 in 36 let* recurrence = 37 match recur with 38 | Some r -> 39 let* p = parse_recurrence r in 40 Ok (Some p) 41 | None -> Ok None 42 in 43 let calendar_name = calendar_name in 44 let* event = 45 Event.create ~fs 46 ~calendar_dir_path:(Calendar_dir.get_path calendar_dir) 47 ~summary ~start ?end_ ?location ?description ?recurrence calendar_name 48 in 49 let* events = Calendar_dir.get_events ~fs calendar_dir in 50 let* _ = Calendar_dir.add_event ~fs calendar_dir events event in 51 Printf.printf "Event created with ID: %s\n" (Event.get_id event); 52 Ok () 53 54let cmd ~fs calendar_dir = 55 let run summary start_date start_time end_date end_time location description 56 recur calendar_name timezone end_timezone () = 57 match 58 run ~summary ~start_date ~start_time ~end_date ~end_time ~location 59 ~description ~recur ~calendar_name ?timezone ?end_timezone ~fs 60 calendar_dir 61 with 62 | Error (`Msg msg) -> 63 Printf.eprintf "Error: %s\n%!" msg; 64 1 65 | Ok () -> 0 66 in 67 let term = 68 Term.( 69 const run $ required_summary_arg $ start_date_arg $ start_time_arg 70 $ end_date_arg $ end_time_arg $ location_arg $ description_arg $ recur_arg 71 $ calendar_name_arg $ timezone_arg $ end_timezone_arg) 72 in 73 let doc = "Add a new calendar event" in 74 let man = 75 [ 76 `S Manpage.s_description; 77 `P "Add a new event to your calendar."; 78 `P 79 "Specify the event summary (title) as the first argument, and use \ 80 options to set other details."; 81 `S Manpage.s_examples; 82 `I 83 ( "Add a event for today:", 84 "caled add \"Meeting\" --date today --time 14:00" ); 85 `I 86 ( "Add an event with a specific date and time:", 87 "caled add \"Dentist Appointment\" --date 2025-04-15 --time 10:30" ); 88 `I 89 ( "Add an event with an end time:", 90 "caled add \"Conference\" --date 2025-05-20 --time 09:00 --end-date \ 91 2025-05-22 --end-time 17:00" ); 92 `I 93 ( "Add an event with location and description:", 94 "caled add \"Lunch with Bob\" --date 2025-04-02 --time 12:30 \ 95 --location \"Pasta Restaurant\" --description \"Discuss project \ 96 plans\"" ); 97 `I 98 ( "Add an event to a specific calendar:", 99 "caled add \"Work Meeting\" --date 2025-04-03 --time 15:00 \ 100 --calendar work" ); 101 `S Manpage.s_options; 102 ] 103 @ date_format_manpage_entries @ recurrence_format_manpage_entries 104 @ [ `S Manpage.s_see_also ] 105 in 106 let exit_info = 107 [ Cmd.Exit.info ~doc:"on success." 0; Cmd.Exit.info ~doc:"on error." 1 ] 108 in 109 let info = Cmd.info "add" ~doc ~man ~exits:exit_info in 110 Cmd.v info term