Command-line and Emacs Calendar Client
1open Cmdliner
2open Caledonia_lib
3open Event_args
4
5let run ~event_id ~summary ~start_date ~start_time ~end_date ~end_time ~location
6 ~description ~recur ?timezone ?end_timezone ~fs calendar_dir =
7 let ( let* ) = Result.bind in
8 let filter = Event.with_id event_id in
9 let* events = Calendar_dir.get_events ~fs calendar_dir in
10 let results = Event.query_without_recurrence events ~filter () in
11 let* event =
12 match results with
13 | [ event ] -> Ok event
14 | [] -> Error (`Msg ("No events found found for id " ^ event_id))
15 | _ -> Error (`Msg ("More than one found for id " ^ event_id))
16 in
17 let* start = parse_start ~start_date ~start_time ~timezone in
18 let* end_ =
19 let end_date =
20 (* if we have an endtime and no end date default to start date *)
21 match (end_date, end_time) with
22 | None, Some _ -> start_date
23 | _ -> end_date
24 in
25 let end_timezone =
26 (* if we specify and end date and time without a end timezone, default to the start timezone *)
27 match (end_date, end_time, end_timezone) with
28 | Some _, Some _, None -> timezone
29 | _ -> end_timezone
30 in
31 parse_end ~end_date ~end_time ~end_timezone
32 in
33 let* recurrence =
34 match recur with
35 | Some r ->
36 let* p = parse_recurrence r in
37 Ok (Some p)
38 | None -> Ok None
39 in
40 let* modifed_event =
41 Event.edit ?summary ?start ?end_ ?location ?description ?recurrence event
42 in
43 let* _ = Calendar_dir.edit_event ~fs calendar_dir events modifed_event in
44 Printf.printf "Event %s updated.\n" event_id;
45 Ok ()
46
47let event_id_arg =
48 let doc = "ID of the event to edit" in
49 Arg.(required & pos 0 (some string) None & info [] ~docv:"EVENT_ID" ~doc)
50
51let cmd ~fs calendar_dir =
52 let run event_id summary start_date start_time end_date end_time location
53 description recur timezone end_timezone () =
54 match
55 run ~event_id ~summary ~start_date ~start_time ~end_date ~end_time
56 ~location ~description ~recur ?timezone ?end_timezone ~fs calendar_dir
57 with
58 | Error (`Msg msg) ->
59 Printf.eprintf "Error: %s\n%!" msg;
60 1
61 | Ok () -> 0
62 in
63 let term =
64 Term.(
65 const run $ event_id_arg $ optional_summary_arg $ start_date_arg
66 $ start_time_arg $ end_date_arg $ end_time_arg $ location_arg
67 $ description_arg $ recur_arg $ timezone_arg $ end_timezone_arg)
68 in
69 let doc = "Edit an existing calendar event" in
70 let man =
71 [
72 `S Manpage.s_description;
73 `P "Edit an existing event in your calendar by its ID.";
74 `P
75 "Specify the event ID as the first argument, and use options to change \
76 event details.";
77 `S Manpage.s_examples;
78 `I
79 ( "Change the summary of an event:",
80 "caled edit 12345678-1234-5678-1234-567812345678 --summary \"New \
81 Title\"" );
82 `I
83 ( "Change the date and time:",
84 "caled edit 12345678-1234-5678-1234-567812345678 --date 2025-05-01 \
85 --time 15:30" );
86 `I
87 ( "Update the location:",
88 "caled edit 12345678-1234-5678-1234-567812345678 --location \
89 \"Conference Room B\"" );
90 `I
91 ( "Change the description:",
92 "caled edit 12345678-1234-5678-1234-567812345678 --description \
93 \"Updated agenda for the meeting\"" );
94 `S Manpage.s_options;
95 ]
96 @ date_format_manpage_entries @ recurrence_format_manpage_entries
97 @ [ `S Manpage.s_see_also ]
98 in
99 let exit_info =
100 [ Cmd.Exit.info ~doc:"on success." 0; Cmd.Exit.info ~doc:"on error." 1 ]
101 in
102 let info = Cmd.info "edit" ~doc ~man ~exits:exit_info in
103 Cmd.v info term