[evolution-ews/wip/mcrha/office365] Calendar: Get Free/Busy information from the server



commit 0a7cb2c373f388cec655c8a0a6b5ee2acd24ee90
Author: Milan Crha <mcrha redhat com>
Date:   Wed Jul 29 18:34:53 2020 +0200

    Calendar: Get Free/Busy information from the server

 src/Microsoft365/calendar/e-cal-backend-m365.c | 170 ++++++++++++++++++-
 src/Microsoft365/common/e-m365-connection.c    |  76 +++++++++
 src/Microsoft365/common/e-m365-connection.h    |  10 ++
 src/Microsoft365/common/e-m365-json-utils.c    | 216 +++++++++++++++++++++++--
 src/Microsoft365/common/e-m365-json-utils.h    |  62 ++++++-
 5 files changed, 517 insertions(+), 17 deletions(-)
---
diff --git a/src/Microsoft365/calendar/e-cal-backend-m365.c b/src/Microsoft365/calendar/e-cal-backend-m365.c
index 2b2cf473..44b4f0fc 100644
--- a/src/Microsoft365/calendar/e-cal-backend-m365.c
+++ b/src/Microsoft365/calendar/e-cal-backend-m365.c
@@ -1410,7 +1410,7 @@ ecb_m365_get_recurrence (ECalBackendM365 *cbm365,
        switch (e_m365_recurrence_range_get_type (m365_range)) {
        case E_M365_RECURRENCE_RANGE_ENDDATE:
                if (e_m365_recurrence_range_get_end_date (m365_range) > 0) {
-                       guint yy = 0, mm = 0, dd = 0;
+                       gint yy = 0, mm = 0, dd = 0;
 
                        if (e_m365_date_decode (e_m365_recurrence_range_get_end_date (m365_range), &yy, &mm, 
&dd)) {
                                ICalTime *itt;
@@ -2734,6 +2734,169 @@ ecb_m365_remove_component_sync (ECalMetaBackend *meta_backend,
        return success;
 }
 
+static void
+ecb_m365_discard_alarm_sync (ECalBackendSync *cal_backend_sync,
+                            EDataCal *cal,
+                            GCancellable *cancellable,
+                            const gchar *uid,
+                            const gchar *rid,
+                            const gchar *auid,
+                            guint32 opflags,
+                            GError **error)
+{
+       ECalBackendM365 *cbm365;
+
+       g_return_if_fail (E_IS_CAL_BACKEND_M365 (cal_backend_sync));
+       g_return_if_fail (uid != NULL);
+
+       cbm365 = E_CAL_BACKEND_M365 (cal_backend_sync);
+
+       if (!e_cal_meta_backend_ensure_connected_sync (E_CAL_META_BACKEND (cbm365), cancellable, error))
+               return;
+
+       LOCK (cbm365);
+
+       e_m365_connection_dismiss_reminder_sync (cbm365->priv->cnc, NULL, cbm365->priv->group_id,
+               cbm365->priv->calendar_id, uid, cancellable, error);
+
+       UNLOCK (cbm365);
+
+       ecb_m365_convert_error_to_client_error (error);
+       ecb_m365_maybe_disconnect_sync (cbm365, error, cancellable);
+}
+
+static void
+ecb_m365_get_free_busy_sync (ECalBackendSync *cal_backend_sync,
+                            EDataCal *cal,
+                            GCancellable *cancellable,
+                            const GSList *users,
+                            time_t start,
+                            time_t end,
+                            GSList **out_freebusyobjs,
+                            GError **error)
+{
+       ECalBackendM365 *cbm365;
+       GSList *infos = NULL;
+       gboolean success;
+
+       g_return_if_fail (E_IS_CAL_BACKEND_M365 (cal_backend_sync));
+       g_return_if_fail (users != NULL);
+       g_return_if_fail (out_freebusyobjs != NULL);
+
+       cbm365 = E_CAL_BACKEND_M365 (cal_backend_sync);
+
+       if (!e_cal_meta_backend_ensure_connected_sync (E_CAL_META_BACKEND (cbm365), cancellable, error))
+               return;
+
+       LOCK (cbm365);
+
+       success = e_m365_connection_get_schedule_sync (cbm365->priv->cnc, NULL, 30, start, end, users, 
&infos, cancellable, error);
+
+       UNLOCK (cbm365);
+
+       ecb_m365_convert_error_to_client_error (error);
+       ecb_m365_maybe_disconnect_sync (cbm365, error, cancellable);
+
+       if (success) {
+               ICalTimezone *utc_zone = i_cal_timezone_get_utc_timezone ();
+               GSList *link;
+
+               *out_freebusyobjs = NULL;
+
+               for (link = infos; link; link = g_slist_next (link)) {
+                       EM365ScheduleInformation *schinfo = link->data;
+                       ICalComponent *vfb = NULL;
+                       JsonArray *array;
+                       guint ii, sz;
+
+                       if (!schinfo || !e_m365_schedule_information_get_schedule_id (schinfo))
+                               continue;
+
+                       array = e_m365_schedule_information_get_schedule_items (schinfo);
+                       sz = array ? json_array_get_length (array) : 0;
+
+                       for (ii = 0; ii < sz; ii++) {
+                               EM365ScheduleItem *schitem = json_array_get_object_element (array, ii);
+                               EM365DateTimeWithZone *dt;
+                               ICalProperty *prop;
+                               ICalPeriod *ipt;
+                               ICalTime *itt;
+                               const gchar *tmp;
+
+                               if (!schitem || !e_m365_schedule_item_get_start (schitem) || 
!e_m365_schedule_item_get_end (schitem))
+                                       continue;
+
+                               ipt = i_cal_period_new_null_period ();
+
+                               dt = e_m365_schedule_item_get_start (schitem);
+                               itt = i_cal_time_new_from_timet_with_zone (e_m365_date_time_get_date_time 
(dt), 0, utc_zone);
+                               i_cal_period_set_start (ipt, itt);
+                               g_clear_object (&itt);
+
+                               dt = e_m365_schedule_item_get_end (schitem);
+                               itt = i_cal_time_new_from_timet_with_zone (e_m365_date_time_get_date_time 
(dt), 0, utc_zone);
+                               i_cal_period_set_end (ipt, itt);
+                               g_clear_object (&itt);
+
+                               prop = i_cal_property_new_freebusy (ipt);
+                               g_clear_object (&ipt);
+
+                               switch (e_m365_schedule_item_get_status (schitem)) {
+                               case E_M365_FREE_BUSY_STATUS_FREE:
+                                       i_cal_property_set_parameter_from_string (prop, "FBTYPE", "FREE");
+                                       break;
+                               case E_M365_FREE_BUSY_STATUS_TENTATIVE:
+                                       i_cal_property_set_parameter_from_string (prop, "FBTYPE", 
"BUSY-TENTATIVE");
+                                       break;
+                               case E_M365_FREE_BUSY_STATUS_BUSY:
+                                       i_cal_property_set_parameter_from_string (prop, "FBTYPE", "BUSY");
+                                       break;
+                               case E_M365_FREE_BUSY_STATUS_OOF:
+                               case E_M365_FREE_BUSY_STATUS_WORKING_ELSEWHERE:
+                                       i_cal_property_set_parameter_from_string (prop, "FBTYPE", 
"BUSY-UNAVAILABLE");
+                                       break;
+                               default:
+                                       break;
+                               }
+
+                               tmp = e_m365_schedule_item_get_subject (schitem);
+
+                               if (tmp && *tmp)
+                                       i_cal_property_set_parameter_from_string (prop, "X-SUMMARY", tmp);
+
+                               tmp = e_m365_schedule_item_get_location (schitem);
+
+                               if (tmp && *tmp)
+                                       i_cal_property_set_parameter_from_string (prop, "X-LOCATION", tmp);
+
+                               if (!vfb)
+                                       vfb = i_cal_component_new_vfreebusy ();
+
+                               i_cal_component_take_property (vfb, prop);
+                       }
+
+                       if (vfb) {
+                               gchar *mailto;
+
+                               mailto = g_strconcat ("mailto:";, e_m365_schedule_information_get_schedule_id 
(schinfo), NULL);
+                               i_cal_component_take_property (vfb, i_cal_property_new_attendee (mailto));
+                               g_free (mailto);
+
+                               *out_freebusyobjs = g_slist_prepend (*out_freebusyobjs, 
i_cal_component_as_ical_string (vfb));
+
+                               g_clear_object (&vfb);
+                       }
+               }
+
+               *out_freebusyobjs = g_slist_reverse (*out_freebusyobjs);
+       }
+
+       g_slist_free_full (infos, (GDestroyNotify) json_object_unref);
+
+       ecb_m365_convert_error_to_client_error (error);
+       ecb_m365_maybe_disconnect_sync (cbm365, error, cancellable);
+}
+
 static gchar *
 ecb_m365_get_backend_property (ECalBackend *cal_backend,
                              const gchar *prop_name)
@@ -2882,6 +3045,7 @@ e_cal_backend_m365_class_init (ECalBackendM365Class *klass)
        GObjectClass *object_class;
        EBackendClass *backend_class;
        ECalBackendClass *cal_backend_class;
+       ECalBackendSyncClass *cal_backend_sync_class;
        ECalMetaBackendClass *cal_meta_backend_class;
 
        cal_meta_backend_class = E_CAL_META_BACKEND_CLASS (klass);
@@ -2892,6 +3056,10 @@ e_cal_backend_m365_class_init (ECalBackendM365Class *klass)
        cal_meta_backend_class->save_component_sync = ecb_m365_save_component_sync;
        cal_meta_backend_class->remove_component_sync = ecb_m365_remove_component_sync;
 
+       cal_backend_sync_class = E_CAL_BACKEND_SYNC_CLASS (klass);
+       cal_backend_sync_class->discard_alarm_sync = ecb_m365_discard_alarm_sync;
+       cal_backend_sync_class->get_free_busy_sync = ecb_m365_get_free_busy_sync;
+
        cal_backend_class = E_CAL_BACKEND_CLASS (klass);
        cal_backend_class->impl_get_backend_property = ecb_m365_get_backend_property;
 
diff --git a/src/Microsoft365/common/e-m365-connection.c b/src/Microsoft365/common/e-m365-connection.c
index 8fd461fd..b578640e 100644
--- a/src/Microsoft365/common/e-m365-connection.c
+++ b/src/Microsoft365/common/e-m365-connection.c
@@ -4790,3 +4790,79 @@ e_m365_connection_delete_event_attachment_sync (EM365Connection *cnc,
 
        return success;
 }
+
+/* https://docs.microsoft.com/en-us/graph/api/calendar-getschedule?view=graph-rest-1.0&tabs=http */
+
+gboolean
+e_m365_connection_get_schedule_sync (EM365Connection *cnc,
+                                    const gchar *user_override, /* for which user, NULL to use the account 
user */
+                                    gint interval_minutes, /* between 5 and 1440, -1 to use the default (30) 
*/
+                                    time_t start_time,
+                                    time_t end_time,
+                                    const GSList *email_addresses, /* const gchar * - SMTP addresses to 
query */
+                                    GSList **out_infos, /* EM365ScheduleInformation * */
+                                    GCancellable *cancellable,
+                                    GError **error)
+{
+       EM365ResponseData rd;
+       JsonBuilder *builder;
+       SoupMessage *message;
+       GSList *link;
+       gboolean success;
+       gchar *uri;
+
+       g_return_val_if_fail (E_IS_M365_CONNECTION (cnc), FALSE);
+       g_return_val_if_fail (email_addresses != NULL, FALSE);
+       g_return_val_if_fail (out_infos != NULL, FALSE);
+
+       uri = e_m365_connection_construct_uri (cnc, TRUE, user_override, E_M365_API_V1_0, NULL,
+               "calendar",
+               "getSchedule",
+               NULL,
+               NULL);
+
+       message = m365_connection_new_soup_message (SOUP_METHOD_POST, uri, CSM_DEFAULT, error);
+
+       if (!message) {
+               g_free (uri);
+
+               return FALSE;
+       }
+
+       g_free (uri);
+
+       builder = json_builder_new_immutable ();
+
+       e_m365_json_begin_object_member (builder, NULL);
+
+       if (interval_minutes > 0)
+               e_m365_json_add_int_member (builder, "interval", interval_minutes);
+
+       e_m365_add_date_time (builder, "startTime", start_time, "UTC");
+       e_m365_add_date_time (builder, "endTime", end_time, "UTC");
+       e_m365_json_begin_array_member (builder, "schedules");
+
+       for (link = (GSList *) email_addresses; link; link = g_slist_next (link)) {
+               const gchar *addr = link->data;
+
+               if (addr && *addr)
+                       json_builder_add_string_value (builder, addr);
+       }
+
+       e_m365_json_end_array_member (builder); /* "schedules" */
+       e_m365_json_end_object_member (builder);
+
+       e_m365_connection_set_json_body (message, builder);
+
+       g_object_unref (builder);
+
+       memset (&rd, 0, sizeof (EM365ResponseData));
+
+       rd.out_items = out_infos;
+
+       success = m365_connection_send_request_sync (cnc, message, e_m365_read_valued_response_cb, NULL, &rd, 
cancellable, error);
+
+       g_clear_object (&message);
+
+       return success;
+}
diff --git a/src/Microsoft365/common/e-m365-connection.h b/src/Microsoft365/common/e-m365-connection.h
index ca839b35..df6deff9 100644
--- a/src/Microsoft365/common/e-m365-connection.h
+++ b/src/Microsoft365/common/e-m365-connection.h
@@ -556,6 +556,16 @@ gboolean   e_m365_connection_delete_event_attachment_sync
                                                 const gchar *attachment_id,
                                                 GCancellable *cancellable,
                                                 GError **error);
+gboolean       e_m365_connection_get_schedule_sync
+                                               (EM365Connection *cnc,
+                                                const gchar *user_override, /* for which user, NULL to use 
the account user */
+                                                gint interval_minutes, /* between 5 and 1440, -1 to use the 
default (30) */
+                                                time_t start_time,
+                                                time_t end_time,
+                                                const GSList *email_addresses, /* const gchar * - SMTP 
addresses to query */
+                                                GSList **out_infos, /* EM365ScheduleInformation * */
+                                                GCancellable *cancellable,
+                                                GError **error);
 
 G_END_DECLS
 
diff --git a/src/Microsoft365/common/e-m365-json-utils.c b/src/Microsoft365/common/e-m365-json-utils.c
index 020adbc3..84fa63a0 100644
--- a/src/Microsoft365/common/e-m365-json-utils.c
+++ b/src/Microsoft365/common/e-m365-json-utils.c
@@ -554,14 +554,14 @@ e_m365_date_get (JsonObject *object,
                 const gchar *member_name)
 {
        const gchar *value;
-       guint year = 0, month = 0, day = 0;
+       gint year = 0, month = 0, day = 0;
 
        value = e_m365_json_get_string_member (object, member_name, NULL);
 
        if (!value || !*value)
                return -1;
 
-       if (sscanf (value, "%04u-%02u-%02u", &year, &month, &day) != 3) {
+       if (sscanf (value, "%04d-%02d-%02d", &year, &month, &day) != 3) {
                g_warning ("%s: Failed to decode date '%s' of member '%s'", G_STRFUNC, value, member_name);
                return -1;
        }
@@ -574,21 +574,21 @@ e_m365_add_date (JsonBuilder *builder,
                 const gchar *member_name,
                 EM365Date value)
 {
-       guint year, month, day;
+       gint year, month, day;
 
        if (e_m365_date_decode (value, &year, &month, &day)) {
                gchar buff[128];
 
-               g_snprintf (buff, sizeof (buff), "%04u-%02u-%02u", year, month, day);
+               g_snprintf (buff, sizeof (buff), "%04d-%02d-%02d", year, month, day);
                e_m365_json_add_string_member (builder, member_name, buff);
        }
 }
 
 gboolean
 e_m365_date_decode (EM365Date dt,
-                   guint *out_year,
-                   guint *out_month,
-                   guint *out_day)
+                   gint *out_year,
+                   gint *out_month,
+                   gint *out_day)
 {
        g_return_val_if_fail (out_year != NULL, FALSE);
        g_return_val_if_fail (out_month != NULL, FALSE);
@@ -607,9 +607,9 @@ e_m365_date_decode (EM365Date dt,
 }
 
 EM365Date
-e_m365_date_encode (guint year,
-                   guint month,
-                   guint day)
+e_m365_date_encode (gint year,
+                   gint month,
+                   gint day)
 {
        g_return_val_if_fail (year > 0 && year < 10000, -1);
        g_return_val_if_fail (month >= 1 && month <= 12, -1);
@@ -618,6 +618,80 @@ e_m365_date_encode (guint year,
        return year + (10000 * month) + (1000000 * day);
 }
 
+EM365TimeOfDay
+e_m365_time_of_day_get (JsonObject *object,
+                       const gchar *member_name)
+{
+       const gchar *value;
+       gint hour = 0, minute = 0, second = 0, fraction = 0;
+
+       value = e_m365_json_get_string_member (object, member_name, NULL);
+
+       if (!value || !*value)
+               return -1;
+
+       if (sscanf (value, "%02d:%02d:%02d.%07d", &hour, &minute, &second, &fraction) != 4) {
+               g_warning ("%s: Failed to decode timeOfDay '%s' of member '%s'", G_STRFUNC, value, 
member_name);
+               return -1;
+       }
+
+       return e_m365_time_of_day_encode (hour, minute, second, fraction);
+}
+
+void
+e_m365_add_time_of_day (JsonBuilder *builder,
+                       const gchar *member_name,
+                       EM365TimeOfDay value)
+{
+       gint hour, minute, second, fraction;
+
+       if (e_m365_time_of_day_decode (value, &hour, &minute, &second, &fraction)) {
+               gchar buff[128];
+
+               g_snprintf (buff, sizeof (buff), "%02d:%02d:%02d.%07d", hour, minute, second, fraction);
+               e_m365_json_add_string_member (builder, member_name, buff);
+       }
+}
+
+gboolean
+e_m365_time_of_day_decode (EM365TimeOfDay tod,
+                          gint *out_hour,
+                          gint *out_minute,
+                          gint *out_second,
+                          gint *out_fraction)
+{
+       g_return_val_if_fail (out_hour != NULL, FALSE);
+       g_return_val_if_fail (out_minute != NULL, FALSE);
+       g_return_val_if_fail (out_second != NULL, FALSE);
+       g_return_val_if_fail (out_fraction != NULL, FALSE);
+
+       if (tod <= 0)
+               return FALSE;
+
+       *out_hour = tod % 100;
+       *out_minute = (tod / 100) % 100;
+       *out_second = (tod / 10000) % 100;
+       *out_fraction = tod / 1000000;
+
+       return *out_hour >= 0 && *out_hour < 24 &&
+               *out_minute >= 0 && *out_minute < 60 &&
+               *out_second >= 0 && *out_second < 60;
+}
+
+EM365TimeOfDay
+e_m365_time_of_day_encode (gint hour,
+                          gint minute,
+                          gint second,
+                          gint fraction)
+{
+       g_return_val_if_fail (hour >= 0 && hour < 24, -1);
+       g_return_val_if_fail (minute >= 0 && minute < 60, -1);
+       g_return_val_if_fail (second >= 0 && second < 60, -1);
+       g_return_val_if_fail (fraction >= 0 && fraction < 10000000, -1);
+
+       return ((EM365TimeOfDay) hour) + (100L * minute) + (10000L * second) + (1000000L * fraction);
+}
+
 time_t
 e_m365_get_date_time_offset_member (JsonObject *object,
                                    const gchar *member_name)
@@ -3359,3 +3433,125 @@ e_m365_event_get_web_link (EM365Event *event)
 {
        return e_m365_json_get_string_member (event, "webLink", NULL);
 }
+
+/* https://docs.microsoft.com/en-us/graph/api/resources/freebusyerror?view=graph-rest-1.0 */
+
+const gchar *
+e_m365_free_busy_error_get_message (EM365FreeBusyError *fberror)
+{
+       return e_m365_json_get_string_member (fberror, "message", NULL);
+}
+
+const gchar *
+e_m365_free_busy_error_get_response_code (EM365FreeBusyError *fberror)
+{
+       return e_m365_json_get_string_member (fberror, "responseCode", NULL);
+}
+
+/* https://docs.microsoft.com/en-us/graph/api/resources/scheduleitem?view=graph-rest-1.0 */
+
+EM365DateTimeWithZone *
+e_m365_schedule_item_get_end (EM365ScheduleItem *schitem)
+{
+       return e_m365_json_get_object_member (schitem, "end");
+}
+
+gboolean
+e_m365_schedule_item_get_is_private (EM365ScheduleItem *schitem)
+{
+       return e_m365_json_get_boolean_member (schitem, "isPrivate", FALSE);
+}
+
+const gchar *
+e_m365_schedule_item_get_location (EM365ScheduleItem *schitem)
+{
+       return e_m365_json_get_string_member (schitem, "location", NULL);
+}
+
+EM365DateTimeWithZone *
+e_m365_schedule_item_get_start (EM365ScheduleItem *schitem)
+{
+       return e_m365_json_get_object_member (schitem, "start");
+}
+
+EM365FreeBusyStatusType
+e_m365_schedule_item_get_status (EM365ScheduleItem *schitem)
+{
+       return m365_json_utils_get_json_as_enum (schitem, "status",
+               free_busy_status_map, G_N_ELEMENTS (free_busy_status_map),
+               E_M365_FREE_BUSY_STATUS_NOT_SET,
+               E_M365_FREE_BUSY_STATUS_UNKNOWN);
+}
+
+const gchar *
+e_m365_schedule_item_get_subject (EM365ScheduleItem *schitem)
+{
+       return e_m365_json_get_string_member (schitem, "subject", NULL);
+}
+
+/* https://docs.microsoft.com/en-us/graph/api/resources/workinghours?view=graph-rest-1.0 */
+
+JsonArray * /* Use e_m365_array_get_day_of_week_element() to get the items */
+e_m365_working_hours_get_days_of_week (EM365WorkingHours *wrkhrs)
+{
+       return e_m365_json_get_array_member (wrkhrs, "daysOfWeek");
+}
+
+EM365TimeOfDay
+e_m365_working_hours_get_start_time (EM365WorkingHours *wrkhrs)
+{
+       return e_m365_time_of_day_get (wrkhrs, "startTime");
+}
+
+EM365TimeOfDay
+e_m365_working_hours_get_end_time (EM365WorkingHours *wrkhrs)
+{
+       return e_m365_time_of_day_get (wrkhrs, "endTime");
+}
+
+const gchar *
+e_m365_working_hours_get_time_zone_name (EM365WorkingHours *wrkhrs)
+{
+       JsonObject *value;
+
+       value = e_m365_json_get_object_member (wrkhrs, "timeZone");
+
+       if (!value)
+               return NULL;
+
+       /* https://docs.microsoft.com/en-us/graph/api/resources/timezonebase?view=graph-rest-1.0 */
+
+       return e_m365_json_get_string_member (value, "name", NULL);
+}
+
+/* https://docs.microsoft.com/en-us/graph/api/resources/scheduleinformation?view=graph-rest-1.0 */
+
+const gchar *
+e_m365_schedule_information_get_availability_view (EM365ScheduleInformation *schinfo)
+{
+       return e_m365_json_get_string_member (schinfo, "availabilityView", NULL);
+}
+
+EM365FreeBusyError *
+e_m365_schedule_information_get_free_busy_error (EM365ScheduleInformation *schinfo)
+{
+       return e_m365_json_get_object_member (schinfo, "error");
+}
+
+const gchar *
+e_m365_schedule_information_get_schedule_id (EM365ScheduleInformation *schinfo)
+{
+       return e_m365_json_get_string_member (schinfo, "scheduleId", NULL);
+}
+
+JsonArray * /* EM365ScheduleItem * */
+e_m365_schedule_information_get_schedule_items (EM365ScheduleInformation *schinfo)
+{
+       return e_m365_json_get_array_member (schinfo, "scheduleItems");
+}
+
+EM365WorkingHours *
+e_m365_schedule_information_get_working_hours (EM365ScheduleInformation *schinfo)
+{
+       return e_m365_json_get_object_member (schinfo, "workingHours");
+}
diff --git a/src/Microsoft365/common/e-m365-json-utils.h b/src/Microsoft365/common/e-m365-json-utils.h
index 15e50640..46eac480 100644
--- a/src/Microsoft365/common/e-m365-json-utils.h
+++ b/src/Microsoft365/common/e-m365-json-utils.h
@@ -25,6 +25,7 @@ G_BEGIN_DECLS
 #define EM365Event                     JsonObject
 #define EM365Folder                    JsonObject
 #define EM365FollowupFlag              JsonObject
+#define EM365FreeBusyError             JsonObject
 #define EM365InternetMessageHeader     JsonObject
 #define EM365ItemBody                  JsonObject
 #define EM365Location                  JsonObject
@@ -39,6 +40,10 @@ G_BEGIN_DECLS
 #define EM365RecurrencePattern         JsonObject
 #define EM365RecurrenceRange           JsonObject
 #define EM365ResponseStatus            JsonObject
+#define EM365ScheduleInformation       JsonObject
+#define EM365ScheduleItem              JsonObject
+#define EM365TimeOfDay                 gint64
+#define EM365WorkingHours              JsonObject
 
 typedef enum _EM365AttachmentDataType {
        E_M365_ATTACHMENT_DATA_TYPE_NOT_SET,
@@ -277,12 +282,26 @@ void              e_m365_add_date                         (JsonBuilder *builder,
                                                         const gchar *member_name,
                                                         EM365Date value);
 gboolean       e_m365_date_decode                      (EM365Date dt,
-                                                        guint *out_year,
-                                                        guint *out_month,
-                                                        guint *out_day);
-EM365Date      e_m365_date_encode                      (guint year,
-                                                        guint month,
-                                                        guint day);
+                                                        gint *out_year,
+                                                        gint *out_month,
+                                                        gint *out_day);
+EM365Date      e_m365_date_encode                      (gint year,
+                                                        gint month,
+                                                        gint day);
+EM365TimeOfDay e_m365_time_of_day_get                  (JsonObject *object,
+                                                        const gchar *member_name);
+void           e_m365_add_time_of_day                  (JsonBuilder *builder,
+                                                        const gchar *member_name,
+                                                        EM365TimeOfDay value);
+gboolean       e_m365_time_of_day_decode               (EM365TimeOfDay tod,
+                                                        gint *out_hour,
+                                                        gint *out_minute,
+                                                        gint *out_second,
+                                                        gint *out_fraction);
+EM365TimeOfDay e_m365_time_of_day_encode               (gint hour,
+                                                        gint minute,
+                                                        gint second,
+                                                        gint fraction);
 
 time_t         e_m365_get_date_time_offset_member      (JsonObject *object,
                                                         const gchar *member_name);
@@ -914,6 +933,37 @@ EM365EventTypeType
                e_m365_event_get_type                   (EM365Event *event);
 const gchar *  e_m365_event_get_web_link               (EM365Event *event);
 
+const gchar *  e_m365_free_busy_error_get_message      (EM365FreeBusyError *fberror);
+const gchar *  e_m365_free_busy_error_get_response_code(EM365FreeBusyError *fberror);
+
+EM365DateTimeWithZone *
+               e_m365_schedule_item_get_end            (EM365ScheduleItem *schitem);
+gboolean       e_m365_schedule_item_get_is_private     (EM365ScheduleItem *schitem);
+const gchar *  e_m365_schedule_item_get_location       (EM365ScheduleItem *schitem);
+EM365DateTimeWithZone *
+               e_m365_schedule_item_get_start          (EM365ScheduleItem *schitem);
+EM365FreeBusyStatusType
+               e_m365_schedule_item_get_status         (EM365ScheduleItem *schitem);
+const gchar *  e_m365_schedule_item_get_subject        (EM365ScheduleItem *schitem);
+
+JsonArray *    e_m365_working_hours_get_days_of_week   (EM365WorkingHours *wrkhrs); /* Use 
e_m365_array_get_day_of_week_element() to get the items */
+EM365TimeOfDay e_m365_working_hours_get_start_time     (EM365WorkingHours *wrkhrs);
+EM365TimeOfDay e_m365_working_hours_get_end_time       (EM365WorkingHours *wrkhrs);
+const gchar *  e_m365_working_hours_get_time_zone_name (EM365WorkingHours *wrkhrs);
+
+const gchar *  e_m365_schedule_information_get_availability_view
+                                                       (EM365ScheduleInformation *schinfo);
+EM365FreeBusyError *
+               e_m365_schedule_information_get_free_busy_error
+                                                       (EM365ScheduleInformation *schinfo);
+const gchar *  e_m365_schedule_information_get_schedule_id
+                                                       (EM365ScheduleInformation *schinfo);
+JsonArray *    e_m365_schedule_information_get_schedule_items /* EM365ScheduleItem * */
+                                                       (EM365ScheduleInformation *schinfo);
+EM365WorkingHours *
+               e_m365_schedule_information_get_working_hours
+                                                       (EM365ScheduleInformation *schinfo);
+
 G_END_DECLS
 
 #endif /* E_M365_JSON_UTILS_H */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]