feat: initial implementation of iCalendar to Remind converter
- Add project scaffolding (dune, dune-project, opam, .ocamlformat) - Implement basic parsing and handling of iCalendar events - Add event predicates for common event types (all-day, timed, recurrence, exceptions) - Add transformation logic to map iCalendar events to Remind format (stub implementation) - Provide utilities for extracting event details and converting dates/times - Set up executable entrypoint and command-line interface using Cmdliner - Include Remind event type definitions and helpers
This commit is contained in:
70
bin/utils.ml
Normal file
70
bin/utils.ml
Normal file
@@ -0,0 +1,70 @@
|
||||
open Icalendar
|
||||
|
||||
let get_uid ev =
|
||||
let _, uid = ev.uid in
|
||||
uid
|
||||
|
||||
let timedesc_of_date_or_datetime (t : date_or_datetime) : Timedesc.t =
|
||||
match t with
|
||||
| `Datetime (`Local _ptime_ts) ->
|
||||
(* TODO: this case is not present in my current dataset… *)
|
||||
failwith "Unhandled case: `Local datetime"
|
||||
| `Datetime (`Utc ts) ->
|
||||
Timedesc.Utils.timestamp_of_ptime ts |> Timedesc.of_timestamp_exn ~tz_of_date_time:(Timedesc.Time_zone.local_exn ())
|
||||
| `Datetime (`With_tzid (ts, (_b, tz_name))) ->
|
||||
(* Qui il timestamp è SCRITTO come se fosse UTC (+00:00) ma in realtà va interpretato con
|
||||
il fuso orario indicato da tz_name. *)
|
||||
let tz = Timedesc.Time_zone.make_exn tz_name in
|
||||
let wrong_ts = Timedesc.Utils.timestamp_of_ptime ts in
|
||||
let date = Timedesc.date (Timedesc.of_timestamp_exn ~tz_of_date_time:Timedesc.Time_zone.utc wrong_ts) in
|
||||
let year, month, day = (Timedesc.Date.year date, Timedesc.Date.month date, Timedesc.Date.day date) in
|
||||
let time = Timedesc.time_view (Timedesc.of_timestamp_exn ~tz_of_date_time:Timedesc.Time_zone.utc wrong_ts) in
|
||||
let hour, minute, second = (time.Timedesc.Time.hour, time.Timedesc.Time.minute, time.Timedesc.Time.second) in
|
||||
Timedesc.make_exn ~year ~month ~day ~hour ~minute ~second ~tz ()
|
||||
| `Date (year, month, day) ->
|
||||
Timedesc.make_exn ~year ~month ~day ~hour:0 ~minute:0 ~second:0 ~tz:(Timedesc.Time_zone.local_exn ()) ()
|
||||
|
||||
let get_start ev =
|
||||
let _, start = ev.dtstart in
|
||||
timedesc_of_date_or_datetime start
|
||||
|
||||
let get_exdates ev =
|
||||
let event_props = ev.props in
|
||||
let dates_or_datetimes =
|
||||
List.filter_map
|
||||
(fun prop ->
|
||||
match prop with
|
||||
| `Exdate (_, dates) -> Some dates
|
||||
| _ -> None)
|
||||
event_props
|
||||
in
|
||||
ListLabels.fold_left ~init:[] dates_or_datetimes ~f:(fun acc dates ->
|
||||
let added =
|
||||
match dates with
|
||||
| `Datetimes ts_list -> List.map (fun ts -> `Datetime ts) ts_list
|
||||
| `Dates date_list -> List.map (fun date -> `Date date) date_list
|
||||
in
|
||||
added @ acc)
|
||||
|> List.map timedesc_of_date_or_datetime
|
||||
|
||||
let get_rdates ev =
|
||||
let event_props = ev.props in
|
||||
let dates_or_datetimes =
|
||||
List.filter_map
|
||||
(fun prop ->
|
||||
match prop with
|
||||
| `Rdate (_, dates) -> Some dates
|
||||
| _ -> None)
|
||||
event_props
|
||||
in
|
||||
ListLabels.fold_left ~init:[] dates_or_datetimes ~f:(fun acc dates ->
|
||||
let added =
|
||||
match dates with
|
||||
| `Datetimes ts_list -> List.map (fun ts -> `Datetime ts) ts_list
|
||||
| `Dates date_list -> List.map (fun date -> `Date date) date_list
|
||||
| `Periods _ ->
|
||||
(* TODO: Ignored for now, does not appear in my current dataset *)
|
||||
failwith "Unhandled case: `Periods in RDATE"
|
||||
in
|
||||
added @ acc)
|
||||
|> List.map timedesc_of_date_or_datetime
|
||||
Reference in New Issue
Block a user