[evolution-ews/wip/mcrha/office365: 47/50] Calendar: Get Free/Busy information from the server
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews/wip/mcrha/office365: 47/50] Calendar: Get Free/Busy information from the server
- Date: Mon, 3 Aug 2020 15:24:09 +0000 (UTC)
commit 578f8f9cb8e75336d29cf8be5bac6823edd6f625
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]