- Simplify `.ocamlformat` to use `default` profile with fewer overrides - Extract shared types and utilities into a `remind_sync` library (`icalendar_augmented`, `ptime_augmented`, `timedesc_augmented`, `result_augmented`, `utf8`) - Replace `eventTransformer.ml` and the predicate system in `eventPredicates.ml` with a sequential collector pipeline (`collect_uuid`, `collect_summary`, `collect_start_end_duration`, etc.) - Simplify `Remind.rem` to a flat record with `Timedesc` date/time fields and replace `rem_to_string` with a leaner `string_of_rem` - Add `separate_master_and_recurrence` and `get_recurrence_id` helpers to `utils.ml` - Wire `main.ml` to call `EventPredicates.remind_of_event` per UID group and print results directly - Remove `eventTransformer` module from `bin/dune` and enable the `remind_sync` library dependency
45 lines
1.9 KiB
OCaml
45 lines
1.9 KiB
OCaml
open Remind_sync
|
|
module Map = MoreLabels.Map.Make (String)
|
|
|
|
(*
|
|
We use a list of events here because there can be multiple events with the same UID, and we want to preserve all of
|
|
them. This is important for handling cases where there are multiple events with the same UID but different properties
|
|
(e.g., due to updates or recurring events or cancellations).
|
|
*)
|
|
|
|
let ical2rem ical_file =
|
|
let ic = open_in ical_file in
|
|
let n = in_channel_length ic in
|
|
let s = Bytes.create n in
|
|
really_input ic s 0 n;
|
|
close_in ic;
|
|
let cal_or_error = Icalendar.parse (Bytes.unsafe_to_string s) in
|
|
match cal_or_error with
|
|
| Error e ->
|
|
if e = ": not enough input" then
|
|
exit 0 (* This is a common error when the file is empty, so we treat it as a non-error case *)
|
|
else prerr_endline ("Error parsing iCalendar file: " ^ e)
|
|
| Ok (_, components) -> begin
|
|
let events_map : Icalendar.event list Map.t =
|
|
ListLabels.fold_left ~init:Map.empty components ~f:(fun acc comp ->
|
|
match comp with
|
|
| `Event ev ->
|
|
let uid = Utils.get_uid ev in
|
|
let event_list = Map.find_opt uid acc |> Option.value ~default:[] in
|
|
Map.add ~key:uid ~data:(ev :: event_list) acc
|
|
| _ -> acc (* Ignore non-event components *))
|
|
in
|
|
(* Now revert all the lists *)
|
|
let events_map = Map.map ~f:List.rev events_map in
|
|
(* Printf.printf "Events: %d\n\n" (Map.cardinal events_map); *)
|
|
|
|
Map.iter events_map ~f:(fun ~key:uid ~data:events ->
|
|
let rem_or_error = EventPredicates.remind_of_event events in
|
|
match rem_or_error with
|
|
| Ok rem -> begin Printf.printf "%s\n" (Remind.string_of_rem rem) end
|
|
| Error (EventPredicates.Invalid_date s) -> Printf.eprintf "UID: %s Invalid date: %s\n" uid s
|
|
| Error Skip -> Printf.eprintf "UID: %s Skipped\n" uid)
|
|
end
|
|
|
|
let () = if !Sys.interactive then () else exit (CommandLine.main ical2rem)
|