[evolution-ews/wip/get_server_time_zones: 4/6] Move functions from e-cal-backend.c to ews-cal-backend-utils.[ch]
- From: Fabiano Fidêncio <ffidencio src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews/wip/get_server_time_zones: 4/6] Move functions from e-cal-backend.c to ews-cal-backend-utils.[ch]
- Date: Wed, 15 Jan 2014 12:41:11 +0000 (UTC)
commit ff322e5dae1ccb5aa97c05d23cabff657a6c3e0c
Author: Fabiano Fidêncio <fidencio redhat com>
Date: Mon Jan 6 15:02:29 2014 +0100
Move functions from e-cal-backend.c to ews-cal-backend-utils.[ch]
This code refactoring has the motivation we can re-use a lot of
internal code in our tests, avoiding duplication.
src/calendar/e-cal-backend-ews-utils.c | 980 +++++++++++++++++++
src/calendar/e-cal-backend-ews-utils.h | 33 +
src/calendar/e-cal-backend-ews.c | 1641 +++++++-------------------------
src/calendar/e-cal-backend-ews.h | 9 +
4 files changed, 1392 insertions(+), 1271 deletions(-)
---
diff --git a/src/calendar/e-cal-backend-ews-utils.c b/src/calendar/e-cal-backend-ews-utils.c
index 601c73c..5469119 100644
--- a/src/calendar/e-cal-backend-ews-utils.c
+++ b/src/calendar/e-cal-backend-ews-utils.c
@@ -39,6 +39,7 @@
#include "server/e-ews-connection.h"
#include "server/e-ews-message.h"
+#include "server/e-ews-item-change.h"
#include "e-cal-backend-ews-utils.h"
@@ -670,6 +671,37 @@ e_cal_backend_ews_unref_tz_msdn_to_ical (void)
g_rec_mutex_unlock (&tz_mutex);
}
+EwsCalendarConvertData *
+ews_calendar_convert_data_new (void)
+{
+ return g_new0 (EwsCalendarConvertData, 1);
+}
+
+void
+ews_calendar_convert_data_free (EwsCalendarConvertData *convert_data)
+{
+ if (convert_data != NULL) {
+ if (convert_data->connection != NULL)
+ g_object_unref (convert_data->connection);
+ if (convert_data->comp != NULL)
+ g_object_unref (convert_data->comp);
+ if (convert_data->old_comp != NULL)
+ g_object_unref (convert_data->old_comp);
+ if (convert_data->default_zone != NULL)
+ icaltimezone_free (convert_data->default_zone, TRUE);
+ if (convert_data->icalcomp != NULL)
+ icalcomponent_free (convert_data->icalcomp);
+
+ g_free (convert_data->item_id);
+ g_free (convert_data->change_key);
+ g_free (convert_data->user_email);
+ g_free (convert_data->response_type);
+ g_slist_free_full (convert_data->users, g_free);
+
+ g_free (convert_data);
+ }
+}
+
/*
* Iterate over the icalcomponent properties and collect attendees
*/
@@ -1587,3 +1619,951 @@ e_ews_clean_icalcomponent (icalcomponent *icalcomp)
if (changekey_prop != NULL)
icalcomponent_remove_property (icalcomp, changekey_prop);
}
+
+static void
+add_attendees_list_to_message (ESoapMessage *msg,
+ const gchar *listname,
+ GSList *list)
+{
+ GSList *item;
+
+ e_soap_message_start_element (msg, listname, NULL, NULL);
+
+ for (item = list; item != NULL; item = item->next) {
+ e_soap_message_start_element (msg, "Attendee", NULL, NULL);
+ e_soap_message_start_element (msg, "Mailbox", NULL, NULL);
+
+ e_ews_message_write_string_parameter (msg, "EmailAddress", NULL, item->data);
+
+ e_soap_message_end_element (msg); /* "Mailbox" */
+ e_soap_message_end_element (msg); /* "Attendee" */
+ }
+
+ e_soap_message_end_element (msg);
+}
+
+static void
+convert_sensitivity_calcomp_to_xml (ESoapMessage *msg,
+ icalcomponent *icalcomp)
+{
+ icalproperty *prop;
+
+ g_return_if_fail (msg != NULL);
+ g_return_if_fail (icalcomp != NULL);
+
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_CLASS_PROPERTY);
+ if (prop) {
+ icalproperty_class classify = icalproperty_get_class (prop);
+ if (classify == ICAL_CLASS_PUBLIC) {
+ e_ews_message_write_string_parameter (msg, "Sensitivity", NULL, "Normal");
+ } else if (classify == ICAL_CLASS_PRIVATE) {
+ e_ews_message_write_string_parameter (msg, "Sensitivity", NULL, "Private");
+ } else if (classify == ICAL_CLASS_CONFIDENTIAL) {
+ e_ews_message_write_string_parameter (msg, "Sensitivity", NULL, "Personal");
+ }
+ }
+}
+
+static void
+convert_categories_calcomp_to_xml (ESoapMessage *msg,
+ ECalComponent *comp,
+ icalcomponent *icalcomp)
+{
+ GSList *categ_list, *citer;
+
+ g_return_if_fail (msg != NULL);
+ g_return_if_fail (icalcomp != NULL);
+
+ if (comp) {
+ g_object_ref (comp);
+ } else {
+ icalcomponent *clone = icalcomponent_new_clone (icalcomp);
+
+ comp = e_cal_component_new ();
+ if (!e_cal_component_set_icalcomponent (comp, clone)) {
+ icalcomponent_free (clone);
+ g_object_unref (comp);
+
+ return;
+ }
+ }
+
+ e_cal_component_get_categories_list (comp, &categ_list);
+
+ g_object_unref (comp);
+
+ if (!categ_list)
+ return;
+
+ e_soap_message_start_element (msg, "Categories", NULL, NULL);
+
+ for (citer = categ_list; citer; citer = g_slist_next (citer)) {
+ const gchar *category = citer->data;
+
+ if (!category || !*category)
+ continue;
+
+ e_ews_message_write_string_parameter (msg, "String", NULL, category);
+ }
+
+ e_soap_message_end_element (msg); /* Categories */
+
+ e_cal_component_free_categories_list (categ_list);
+}
+
+static void
+convert_vevent_calcomp_to_xml (ESoapMessage *msg,
+ gpointer user_data)
+{
+ EwsCalendarConvertData *convert_data = user_data;
+ icalcomponent *icalcomp = convert_data->icalcomp;
+ ECalComponent *comp = e_cal_component_new ();
+ GSList *required = NULL, *optional = NULL, *resource = NULL;
+ icaltimetype dtstart, dtend;
+ icalproperty *prop;
+ gboolean has_alarms;
+ const gchar *value;
+
+ e_cal_component_set_icalcomponent (comp, icalcomp);
+
+ /* FORMAT OF A SAMPLE SOAP MESSAGE: http://msdn.microsoft.com/en-us/library/aa564690.aspx */
+
+ /* Prepare CalendarItem node in the SOAP message */
+ e_soap_message_start_element (msg, "CalendarItem", NULL, NULL);
+
+ /* subject */
+ value = icalcomponent_get_summary (icalcomp);
+ if (value)
+ e_ews_message_write_string_parameter (msg, "Subject", NULL, value);
+
+ convert_sensitivity_calcomp_to_xml (msg, icalcomp);
+
+ /* description */
+ value = icalcomponent_get_description (icalcomp);
+ if (value)
+ e_ews_message_write_string_parameter_with_attribute (msg, "Body", NULL, value, "BodyType",
"Text");
+
+ convert_categories_calcomp_to_xml (msg, comp, icalcomp);
+
+ /* set alarms */
+ has_alarms = e_cal_component_has_alarms (comp);
+ if (has_alarms)
+ ews_set_alarm (msg, comp);
+ else
+ e_ews_message_write_string_parameter (msg, "ReminderIsSet", NULL, "false");
+
+ /* start time, end time and meeting time zone */
+ dtstart = icalcomponent_get_dtstart (icalcomp);
+ dtend = icalcomponent_get_dtend (icalcomp);
+
+ ewscal_set_time (msg, "Start", &dtstart, FALSE);
+ ewscal_set_time (msg, "End", &dtend, FALSE);
+ /* We have to do the time zone(s) later, or the server rejects the request */
+
+ /* All day event ? */
+ if (icaltime_is_date (dtstart))
+ e_ews_message_write_string_parameter (msg, "IsAllDayEvent", NULL, "true");
+
+ /*freebusy*/
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_TRANSP_PROPERTY);
+ if (!g_strcmp0 (icalproperty_get_value_as_string (prop), "TRANSPARENT"))
+ e_ews_message_write_string_parameter (msg, "LegacyFreeBusyStatus",NULL,"Free");
+ else
+ e_ews_message_write_string_parameter (msg, "LegacyFreeBusyStatus",NULL,"Busy");
+
+ /* location */
+ value = icalcomponent_get_location (icalcomp);
+ if (value)
+ e_ews_message_write_string_parameter (msg, "Location", NULL, value);
+
+ /* collect attendees */
+ e_ews_collect_attendees (icalcomp, &required, &optional, &resource);
+
+ if (required != NULL) {
+ add_attendees_list_to_message (msg, "RequiredAttendees", required);
+ g_slist_free (required);
+ }
+ if (optional != NULL) {
+ add_attendees_list_to_message (msg, "OptionalAttendees", optional);
+ g_slist_free (optional);
+ }
+ if (resource != NULL) {
+ add_attendees_list_to_message (msg, "Resources", resource);
+ g_slist_free (resource);
+ }
+ /* end of attendees */
+
+ /* Recurrence */
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
+ if (prop != NULL) {
+ ewscal_set_reccurence (msg, prop, &dtstart);
+ }
+
+ /* We have to cast these because libical puts a const pointer into the
+ * icaltimetype, but its basic read-only icaltimezone_foo() functions
+ * take a non-const pointer! */
+ if (e_ews_connection_satisfies_server_version (convert_data->connection, E_EWS_EXCHANGE_2010)) {
+ const gchar *ical_location;
+ const gchar *msdn_location;
+ icaltimezone *tzid;
+ GSList *msdn_locations = NULL;
+ GSList *tzds = NULL;
+
+ tzid = (icaltimezone *) (dtstart.zone ? dtstart.zone : convert_data->default_zone);
+ ical_location = icaltimezone_get_location (tzid);
+ msdn_location = e_cal_backend_ews_tz_util_get_msdn_equivalent (ical_location);
+
+ msdn_locations = g_slist_prepend (msdn_locations, (gchar *) msdn_location);
+
+ tzid = (icaltimezone *)
+ (dtend.zone ? dtend.zone : convert_data->default_zone);
+ ical_location = icaltimezone_get_location (tzid);
+ msdn_location = e_cal_backend_ews_tz_util_get_msdn_equivalent (ical_location);
+
+ msdn_locations = g_slist_prepend (msdn_locations, (gchar *) msdn_location);
+
+ msdn_locations = g_slist_reverse (msdn_locations);
+
+ if (e_ews_connection_get_server_time_zones_sync (
+ convert_data->connection,
+ EWS_PRIORITY_MEDIUM,
+ msdn_locations,
+ &tzds,
+ NULL,
+ NULL)) {
+ ewscal_set_timezone (msg, "StartTimeZone", tzds->data);
+ ewscal_set_timezone (msg, "EndTimeZone", tzds->data);
+ }
+
+ g_slist_free (msdn_locations);
+ g_slist_free_full (tzds, (GDestroyNotify) e_ews_calendar_time_zone_definition_free);
+ } else {
+ ewscal_set_meeting_timezone (
+ msg,
+ (icaltimezone *) (dtstart.zone ? dtstart.zone : convert_data->default_zone));
+ }
+
+ // end of "CalendarItem"
+ e_soap_message_end_element (msg);
+}
+
+static void
+convert_vtodo_calcomp_to_xml (ESoapMessage *msg,
+ gpointer user_data)
+{
+ EwsCalendarConvertData *convert_data = user_data;
+ icalcomponent *icalcomp = convert_data->icalcomp;
+ icalproperty *prop;
+ icaltimetype dt;
+ gint value;
+ gchar buffer[16];
+
+ e_soap_message_start_element (msg, "Task", NULL, NULL);
+
+ e_ews_message_write_string_parameter (msg, "Subject", NULL, icalcomponent_get_summary (icalcomp));
+
+ convert_sensitivity_calcomp_to_xml (msg, icalcomp);
+
+ e_ews_message_write_string_parameter_with_attribute (msg, "Body", NULL, icalcomponent_get_description
(icalcomp), "BodyType", "Text");
+
+ convert_categories_calcomp_to_xml (msg, NULL, icalcomp);
+
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_DUE_PROPERTY);
+ if (prop) {
+ dt = icalproperty_get_due (prop);
+ ewscal_set_time (msg, "DueDate", &dt, TRUE);
+ }
+
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_PERCENTCOMPLETE_PROPERTY);
+ if (prop) {
+ value = icalproperty_get_percentcomplete (prop);
+ snprintf (buffer, 16, "%d", value);
+ e_ews_message_write_string_parameter (msg, "PercentComplete", NULL, buffer);
+ }
+
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_DTSTART_PROPERTY);
+ if (prop) {
+ dt = icalproperty_get_dtstart (prop);
+ ewscal_set_time (msg, "StartDate", &dt, TRUE);
+ }
+
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_STATUS_PROPERTY);
+ if (prop) {
+ switch (icalproperty_get_status (prop)) {
+ case ICAL_STATUS_INPROCESS:
+ e_ews_message_write_string_parameter (msg, "Status", NULL, "InProgress");
+ break;
+ case ICAL_STATUS_COMPLETED:
+ e_ews_message_write_string_parameter (msg, "Status", NULL, "Completed");
+ break;
+ default:
+ break;
+ }
+ }
+
+ e_soap_message_end_element (msg); // "Task"
+}
+
+static void
+convert_vjournal_calcomp_to_xml (ESoapMessage *msg,
+ gpointer user_data)
+{
+ EwsCalendarConvertData *convert_data = user_data;
+ icalcomponent *icalcomp = convert_data->icalcomp;
+ const gchar *text;
+
+ e_soap_message_start_element (msg, "Message", NULL, NULL);
+ e_ews_message_write_string_parameter (msg, "ItemClass", NULL, "IPM.StickyNote");
+
+ e_ews_message_write_string_parameter (msg, "Subject", NULL, icalcomponent_get_summary (icalcomp));
+
+ convert_sensitivity_calcomp_to_xml (msg, icalcomp);
+
+ text = icalcomponent_get_description (icalcomp);
+ if (!text || !*text)
+ text = icalcomponent_get_summary (icalcomp);
+ e_ews_message_write_string_parameter_with_attribute (msg, "Body", NULL, text, "BodyType", "Text");
+
+ convert_categories_calcomp_to_xml (msg, NULL, icalcomp);
+
+ e_soap_message_end_element (msg); /* Message */
+}
+
+void
+e_cal_backend_ews_convert_calcomp_to_xml (ESoapMessage *msg,
+ gpointer user_data)
+{
+ EwsCalendarConvertData *convert_data = user_data;
+
+ switch (icalcomponent_isa (convert_data->icalcomp)) {
+ case ICAL_VEVENT_COMPONENT:
+ convert_vevent_calcomp_to_xml (msg, convert_data);
+ break;
+ case ICAL_VTODO_COMPONENT:
+ convert_vtodo_calcomp_to_xml (msg, convert_data);
+ break;
+ case ICAL_VJOURNAL_COMPONENT:
+ convert_vjournal_calcomp_to_xml (msg, convert_data);
+ break;
+ default:
+ g_warn_if_reached ();
+ break;
+ }
+}
+
+static void
+convert_component_categories_to_updatexml (ECalComponent *comp,
+ ESoapMessage *msg,
+ const gchar *base_elem_name)
+{
+ GSList *categ_list = NULL, *citer;
+
+ g_return_if_fail (comp != NULL);
+ g_return_if_fail (msg != NULL);
+ g_return_if_fail (base_elem_name != NULL);
+
+ e_cal_component_get_categories_list (comp, &categ_list);
+ e_ews_message_start_set_item_field (msg, "Categories", "item", base_elem_name);
+ e_soap_message_start_element (msg, "Categories", NULL, NULL);
+
+ for (citer = categ_list; citer; citer = g_slist_next (citer)) {
+ const gchar *category = citer->data;
+
+ if (!category || !*category)
+ continue;
+
+ e_ews_message_write_string_parameter (msg, "String", NULL, category);
+ }
+
+ e_soap_message_end_element (msg); /* Categories */
+ e_ews_message_end_set_item_field (msg);
+
+ e_cal_component_free_categories_list (categ_list);
+}
+
+static void
+convert_vevent_property_to_updatexml (ESoapMessage *msg,
+ const gchar *name,
+ const gchar *value,
+ const gchar *prefix,
+ const gchar *attr_name,
+ const gchar *attr_value)
+{
+ e_ews_message_start_set_item_field (msg, name, prefix, "CalendarItem");
+ e_ews_message_write_string_parameter_with_attribute (msg, name, NULL, value, attr_name, attr_value);
+ e_ews_message_end_set_item_field (msg);
+}
+
+static void
+convert_vevent_component_to_updatexml (ESoapMessage *msg,
+ gpointer user_data)
+{
+ EwsCalendarConvertData *convert_data = user_data;
+ icalcomponent *icalcomp = e_cal_component_get_icalcomponent (convert_data->comp);
+ icalcomponent *icalcomp_old = e_cal_component_get_icalcomponent (convert_data->old_comp);
+ GSList *required = NULL, *optional = NULL, *resource = NULL;
+ icaltimetype dtstart, dtend, dtstart_old, dtend_old;
+ icalproperty *prop, *transp;
+ const gchar *org_email_address = NULL, *value = NULL, *old_value = NULL;
+ gboolean has_alarms, has_alarms_old, dt_changed = FALSE;
+ gint alarm = 0, alarm_old = 0;
+ gchar *recid;
+ GError *error = NULL;
+
+ /* Modifying a recurring meeting ? */
+ if (icalcomponent_get_first_property (icalcomp_old, ICAL_RRULE_PROPERTY) != NULL) {
+ /* A single occurrence ? */
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_RECURRENCEID_PROPERTY);
+ if (prop != NULL) {
+ recid = icalproperty_get_value_as_string_r (prop);
+ e_ews_message_start_item_change (
+ msg,
+ E_EWS_ITEMCHANGE_TYPE_OCCURRENCEITEM,
+ convert_data->item_id,
+ convert_data->change_key,
+ e_cal_backend_ews_rid_to_index (
+ convert_data->default_zone,
+ recid,
+ icalcomp_old,
+ &error));
+ free (recid);
+ } else {
+ e_ews_message_start_item_change (
+ msg, E_EWS_ITEMCHANGE_TYPE_ITEM,
+ convert_data->item_id, convert_data->change_key, 0);
+ }
+ } else e_ews_message_start_item_change (msg, E_EWS_ITEMCHANGE_TYPE_ITEM,
+ convert_data->item_id, convert_data->change_key, 0);
+
+ /* subject */
+ value = icalcomponent_get_summary (icalcomp);
+ old_value = icalcomponent_get_summary (icalcomp_old);
+ if ((value && old_value && g_ascii_strcasecmp (value, old_value)) ||
+ (value && old_value == NULL)) {
+ convert_vevent_property_to_updatexml (msg, "Subject", value, "item", NULL, NULL);
+ } else if (!value && old_value)
+ convert_vevent_property_to_updatexml (msg, "Subject", "", "item", NULL, NULL);
+
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_CLASS_PROPERTY);
+ if (prop) {
+ icalproperty_class classify = icalproperty_get_class (prop);
+ if (classify == ICAL_CLASS_PUBLIC) {
+ convert_vevent_property_to_updatexml (msg, "Sensitivity", "Normal", "item", NULL,
NULL);
+ } else if (classify == ICAL_CLASS_PRIVATE) {
+ convert_vevent_property_to_updatexml (msg, "Sensitivity", "Private", "item", NULL,
NULL);
+ } else if (classify == ICAL_CLASS_CONFIDENTIAL) {
+ convert_vevent_property_to_updatexml (msg, "Sensitivity", "Personal", "item", NULL,
NULL);
+ }
+ }
+
+ /*description*/
+ value = icalcomponent_get_description (icalcomp);
+ old_value = icalcomponent_get_description (icalcomp_old);
+ if ((value && old_value && g_ascii_strcasecmp (value, old_value)) ||
+ (value && old_value == NULL)) {
+ convert_vevent_property_to_updatexml (msg, "Body", value, "item", "BodyType", "Text");
+ } else if (!value && old_value)
+ convert_vevent_property_to_updatexml (msg, "Body", "", "item", "BodyType", "Text");
+
+ /*update alarm items*/
+ has_alarms = e_cal_component_has_alarms (convert_data->comp);
+ if (has_alarms) {
+ alarm = ews_get_alarm (convert_data->comp);
+ has_alarms_old = e_cal_component_has_alarms (convert_data->old_comp);
+ if (has_alarms_old)
+ alarm_old = ews_get_alarm (convert_data->old_comp);
+ if (!(alarm == alarm_old)) {
+ gchar buf[20];
+ snprintf (buf, 20, "%d", alarm);
+ convert_vevent_property_to_updatexml (msg, "ReminderIsSet", "true", "item", NULL,
NULL);
+ convert_vevent_property_to_updatexml (msg, "ReminderMinutesBeforeStart", buf, "item",
NULL, NULL);
+ }
+ }
+ else convert_vevent_property_to_updatexml (msg, "ReminderIsSet", "false", "item", NULL, NULL);
+
+ /* Categories */
+ convert_component_categories_to_updatexml (convert_data->comp, msg, "CalendarItem");
+
+ /*location*/
+ value = icalcomponent_get_location (icalcomp);
+ old_value = icalcomponent_get_location (icalcomp_old);
+ if ((value && old_value && g_ascii_strcasecmp (value, old_value)) ||
+ (value && old_value == NULL)) {
+ convert_vevent_property_to_updatexml (msg, "Location", value, "calendar", NULL, NULL);
+ } else if (!value && old_value)
+ convert_vevent_property_to_updatexml (msg, "Location", "", "calendar", NULL, NULL);
+
+ /*freebusy*/
+ transp = icalcomponent_get_first_property (icalcomp, ICAL_TRANSP_PROPERTY);
+ value = icalproperty_get_value_as_string (transp);
+ transp = icalcomponent_get_first_property (icalcomp_old, ICAL_TRANSP_PROPERTY);
+ old_value = icalproperty_get_value_as_string (transp);
+ if (g_strcmp0 (value, old_value)) {
+ if (!g_strcmp0 (value, "TRANSPARENT"))
+ convert_vevent_property_to_updatexml (msg, "LegacyFreeBusyStatus","Free" ,
"calendar", NULL, NULL);
+ else
+ convert_vevent_property_to_updatexml (msg, "LegacyFreeBusyStatus","Busy" ,
"calendar", NULL, NULL);
+ }
+
+ org_email_address = e_ews_collect_organizer (icalcomp);
+ if (org_email_address && g_ascii_strcasecmp (org_email_address, convert_data->user_email)) {
+ e_ews_message_end_item_change (msg);
+ return;
+ }
+ /* Update other properties allowed only for meeting organizers*/
+ /*meeting dates*/
+ dtstart = icalcomponent_get_dtstart (icalcomp);
+ dtend = icalcomponent_get_dtend (icalcomp);
+ dtstart_old = icalcomponent_get_dtstart (icalcomp_old);
+ dtend_old = icalcomponent_get_dtend (icalcomp_old);
+ if (icaltime_compare (dtstart, dtstart_old) != 0) {
+ e_ews_message_start_set_item_field (msg, "Start", "calendar","CalendarItem");
+ ewscal_set_time (msg, "Start", &dtstart, FALSE);
+ e_ews_message_end_set_item_field (msg);
+ dt_changed = TRUE;
+ }
+
+ if (icaltime_compare (dtend, dtend_old) != 0) {
+ e_ews_message_start_set_item_field (msg, "End", "calendar", "CalendarItem");
+ ewscal_set_time (msg, "End", &dtend, FALSE);
+ e_ews_message_end_set_item_field (msg);
+ dt_changed = TRUE;
+ }
+
+ /*Check for All Day Event*/
+ if (dt_changed) {
+ if (icaltime_is_date (dtstart))
+ convert_vevent_property_to_updatexml (msg, "IsAllDayEvent", "true", "calendar", NULL,
NULL);
+ else
+ convert_vevent_property_to_updatexml (msg, "IsAllDayEvent", "false", "calendar",
NULL, NULL);
+ }
+
+ /*need to test it*/
+ e_ews_collect_attendees (icalcomp, &required, &optional, &resource);
+ if (required != NULL) {
+ e_ews_message_start_set_item_field (msg, "RequiredAttendees", "calendar", "CalendarItem");
+
+ add_attendees_list_to_message (msg, "RequiredAttendees", required);
+ g_slist_free (required);
+
+ e_ews_message_end_set_item_field (msg);
+ }
+ if (optional != NULL) {
+ e_ews_message_start_set_item_field (msg, "OptionalAttendees", "calendar", "CalendarItem");
+
+ add_attendees_list_to_message (msg, "OptionalAttendees", optional);
+ g_slist_free (optional);
+
+ e_ews_message_end_set_item_field (msg);
+ }
+ if (resource != NULL) {
+ e_ews_message_start_set_item_field (msg, "Resources", "calendar", "CalendarItem");
+
+ add_attendees_list_to_message (msg, "Resources", resource);
+ g_slist_free (resource);
+
+ e_ews_message_end_set_item_field (msg);
+ }
+
+ /* Recurrence */
+ value = NULL; old_value = NULL;
+ prop = icalcomponent_get_first_property (icalcomp_old, ICAL_RRULE_PROPERTY);
+ if (prop != NULL)
+ old_value = icalproperty_get_value_as_string (prop);
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
+ if (prop != NULL)
+ value = icalproperty_get_value_as_string (prop);
+
+ if (prop != NULL && g_strcmp0 (value, old_value)) {
+ e_ews_message_start_set_item_field (msg, "Recurrence", "calendar", "CalendarItem");
+ ewscal_set_reccurence (msg, prop, &dtstart);
+ e_ews_message_end_set_item_field (msg);
+ }
+
+ /* We have to cast these because libical puts a const pointer into the
+ * icaltimetype, but its basic read-only icaltimezone_foo() functions
+ * take a non-const pointer! */
+ if (e_ews_connection_satisfies_server_version (convert_data->connection, E_EWS_EXCHANGE_2010)) {
+ const gchar *ical_location;
+ const gchar *msdn_location;
+ icaltimezone *tzid;
+ GSList *msdn_locations = NULL;
+ GSList *tzds = NULL;
+
+ if (dtstart.zone != NULL) {
+ tzid = (icaltimezone *) dtstart.zone;
+ ical_location = icaltimezone_get_location (tzid);
+ msdn_location = e_cal_backend_ews_tz_util_get_msdn_equivalent (ical_location);
+ msdn_locations = g_slist_append (msdn_locations, (gchar *) msdn_location);
+ }
+
+ if (dtend.zone != NULL) {
+ tzid = (icaltimezone *) dtend.zone;
+ ical_location = icaltimezone_get_location (tzid);
+ msdn_location = e_cal_backend_ews_tz_util_get_msdn_equivalent (ical_location);
+ msdn_locations = g_slist_append (msdn_locations, (gchar *) msdn_location);
+ }
+
+ if (e_ews_connection_get_server_time_zones_sync (
+ convert_data->connection,
+ EWS_PRIORITY_MEDIUM,
+ msdn_locations,
+ &tzds,
+ NULL,
+ NULL)) {
+ GSList *tmp;
+
+ tmp = tzds;
+ if (dtstart.zone != NULL) {
+ e_ews_message_start_set_item_field (msg, "StartTimeZone", "calendar",
"CalendarItem");
+ ewscal_set_timezone (msg, "StartTimeZone", tmp->data);
+ e_ews_message_end_set_item_field (msg);
+
+ /*
+ * Exchange server is smart enough to return the list of
+ * ServerTimeZone without repeated elements
+ */
+ if (tmp->next != NULL)
+ tmp = tmp->next;
+ }
+
+ if (dtend.zone != NULL) {
+ e_ews_message_start_set_item_field (msg, "EndTimeZone", "calendar",
"CalendarItem");
+ ewscal_set_timezone (msg, "EndTimeZone", tmp->data);
+ e_ews_message_end_set_item_field (msg);
+ }
+ }
+
+ g_slist_free (msdn_locations);
+ g_slist_free_full (tzds, (GDestroyNotify) e_ews_calendar_time_zone_definition_free);
+ } else {
+ e_ews_message_start_set_item_field (msg, "MeetingTimeZone", "calendar", "CalendarItem");
+ ewscal_set_meeting_timezone (
+ msg,
+ (icaltimezone *) (dtstart.zone ? dtstart.zone : convert_data->default_zone));
+ e_ews_message_end_set_item_field (msg);
+ }
+
+ e_ews_message_end_item_change (msg);
+}
+
+static void
+convert_vtodo_property_to_updatexml (ESoapMessage *msg,
+ const gchar *name,
+ const gchar *value,
+ const gchar *prefix,
+ const gchar *attr_name,
+ const gchar *attr_value)
+{
+ e_ews_message_start_set_item_field (msg, name, prefix, "Task");
+ e_ews_message_write_string_parameter_with_attribute (msg, name, NULL, value, attr_name, attr_value);
+ e_ews_message_end_set_item_field (msg);
+}
+
+static void
+convert_vtodo_component_to_updatexml (ESoapMessage *msg,
+ gpointer user_data)
+{
+ EwsCalendarConvertData *convert_data = user_data;
+ icalcomponent *icalcomp = e_cal_component_get_icalcomponent (convert_data->comp);
+ icalproperty *prop;
+ icaltimetype dt;
+ gint value;
+ gchar buffer[16];
+
+ e_ews_message_start_item_change (
+ msg, E_EWS_ITEMCHANGE_TYPE_ITEM,
+ convert_data->item_id, convert_data->change_key, 0);
+
+ convert_vtodo_property_to_updatexml (msg, "Subject", icalcomponent_get_summary (icalcomp), "item",
NULL, NULL);
+
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_CLASS_PROPERTY);
+ if (prop) {
+ icalproperty_class classify = icalproperty_get_class (prop);
+ if (classify == ICAL_CLASS_PUBLIC) {
+ convert_vtodo_property_to_updatexml (msg, "Sensitivity", "Normal", "item", NULL,
NULL);
+ } else if (classify == ICAL_CLASS_PRIVATE) {
+ convert_vtodo_property_to_updatexml (msg, "Sensitivity", "Private", "item", NULL,
NULL);
+ } else if (classify == ICAL_CLASS_CONFIDENTIAL) {
+ convert_vtodo_property_to_updatexml (msg, "Sensitivity", "Personal", "item", NULL,
NULL);
+ }
+ }
+
+ convert_vtodo_property_to_updatexml (msg, "Body", icalcomponent_get_description (icalcomp), "item",
"BodyType", "Text");
+
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_DUE_PROPERTY);
+ if (prop) {
+ dt = icalproperty_get_due (prop);
+ e_ews_message_start_set_item_field (msg, "DueDate", "task", "Task");
+ ewscal_set_time (msg, "DueDate", &dt, TRUE);
+ e_ews_message_end_set_item_field (msg);
+ } else {
+ e_ews_message_add_delete_item_field (msg, "DueDate", "task");
+ }
+
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_PERCENTCOMPLETE_PROPERTY);
+ if (prop) {
+ value = icalproperty_get_percentcomplete (prop);
+ snprintf (buffer, 16, "%d", value);
+ e_ews_message_start_set_item_field (msg, "PercentComplete", "task", "Task");
+ e_ews_message_write_string_parameter (msg, "PercentComplete", NULL, buffer);
+ e_ews_message_end_set_item_field (msg);
+ }
+
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_DTSTART_PROPERTY);
+ if (prop) {
+ dt = icalproperty_get_dtstart (prop);
+ e_ews_message_start_set_item_field (msg, "StartDate", "task", "Task");
+ ewscal_set_time (msg, "StartDate", &dt, TRUE);
+ e_ews_message_end_set_item_field (msg);
+ } else {
+ e_ews_message_add_delete_item_field (msg, "StartDate", "task");
+ }
+
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_STATUS_PROPERTY);
+ if (prop) {
+ switch (icalproperty_get_status (prop)) {
+ case ICAL_STATUS_INPROCESS:
+ convert_vtodo_property_to_updatexml (msg, "Status", "InProgress", "task", NULL, NULL);
+ break;
+ case ICAL_STATUS_COMPLETED:
+ convert_vtodo_property_to_updatexml (msg, "Status", "Completed", "task", NULL, NULL);
+ break;
+ case ICAL_STATUS_NONE:
+ case ICAL_STATUS_NEEDSACTION:
+ convert_vtodo_property_to_updatexml (msg, "Status", "NotStarted", "task", NULL, NULL);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* Categories */
+ convert_component_categories_to_updatexml (convert_data->comp, msg, "Task");
+
+ e_ews_message_end_item_change (msg);
+}
+
+static void
+convert_vjournal_property_to_updatexml (ESoapMessage *msg,
+ const gchar *name,
+ const gchar *value,
+ const gchar *prefix,
+ const gchar *attr_name,
+ const gchar *attr_value)
+{
+ e_ews_message_start_set_item_field (msg, name, prefix, "Message");
+ e_ews_message_write_string_parameter_with_attribute (msg, name, NULL, value, attr_name, attr_value);
+ e_ews_message_end_set_item_field (msg);
+}
+
+static void
+convert_vjournal_component_to_updatexml (ESoapMessage *msg,
+ gpointer user_data)
+{
+ EwsCalendarConvertData *convert_data = user_data;
+ icalcomponent *icalcomp = e_cal_component_get_icalcomponent (convert_data->comp);
+ icalproperty *prop;
+ const gchar *text;
+
+ e_ews_message_start_item_change (
+ msg, E_EWS_ITEMCHANGE_TYPE_ITEM,
+ convert_data->item_id, convert_data->change_key, 0);
+
+ convert_vjournal_property_to_updatexml (msg, "ItemClass", "IPM.StickyNote", "item", NULL, NULL);
+ convert_vjournal_property_to_updatexml (msg, "Subject", icalcomponent_get_summary (icalcomp), "item",
NULL, NULL);
+
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_CLASS_PROPERTY);
+ if (prop) {
+ icalproperty_class classify = icalproperty_get_class (prop);
+ if (classify == ICAL_CLASS_PUBLIC) {
+ convert_vjournal_property_to_updatexml (msg, "Sensitivity", "Normal", "item", NULL,
NULL);
+ } else if (classify == ICAL_CLASS_PRIVATE) {
+ convert_vjournal_property_to_updatexml (msg, "Sensitivity", "Private", "item", NULL,
NULL);
+ } else if (classify == ICAL_CLASS_CONFIDENTIAL) {
+ convert_vjournal_property_to_updatexml (msg, "Sensitivity", "Personal", "item", NULL,
NULL);
+ }
+ }
+
+ text = icalcomponent_get_description (icalcomp);
+ if (!text || !*text)
+ text = icalcomponent_get_summary (icalcomp);
+
+ convert_vjournal_property_to_updatexml (msg, "Body", text, "item", "BodyType", "Text");
+
+ /* Categories */
+ convert_component_categories_to_updatexml (convert_data->comp, msg, "Message");
+
+ e_ews_message_end_item_change (msg);
+}
+
+void
+e_cal_backend_ews_convert_component_to_updatexml (ESoapMessage *msg,
+ gpointer user_data)
+{
+ EwsCalendarConvertData *convert_data = user_data;
+ icalcomponent *icalcomp = e_cal_component_get_icalcomponent (convert_data->comp);
+
+ switch (icalcomponent_isa (icalcomp)) {
+ case ICAL_VEVENT_COMPONENT:
+ convert_vevent_component_to_updatexml (msg, user_data);
+ break;
+ case ICAL_VTODO_COMPONENT:
+ convert_vtodo_component_to_updatexml (msg, user_data);
+ break;
+ case ICAL_VJOURNAL_COMPONENT:
+ convert_vjournal_component_to_updatexml (msg, user_data);
+ break;
+ default:
+ break;
+ }
+}
+
+guint
+e_cal_backend_ews_rid_to_index (icaltimezone *timezone,
+ const gchar *rid,
+ icalcomponent *comp,
+ GError **error)
+{
+ guint index = 1;
+ icalproperty *prop = icalcomponent_get_first_property (comp, ICAL_RRULE_PROPERTY);
+ struct icalrecurrencetype rule = icalproperty_get_rrule (prop);
+ struct icaltimetype dtstart = icalcomponent_get_dtstart (comp);
+ icalrecur_iterator * ritr;
+ icaltimetype next, o_time;
+
+ /* icalcomponent_get_datetime needs a fix to initialize ret.zone to NULL. If a timezone is not
+ * found in libical, it remains uninitialized in that function causing invalid read or crash. so
+ * we set the timezone as we cannot identify if it has a valid timezone or not */
+ dtstart.zone = timezone;
+ ritr = icalrecur_iterator_new (rule, dtstart);
+ next = icalrecur_iterator_next (ritr);
+ o_time = icaltime_from_string (rid);
+ o_time.zone = dtstart.zone;
+
+ for (; !icaltime_is_null_time (next); next = icalrecur_iterator_next (ritr), index++) {
+ if (icaltime_compare_date_only (o_time, next) == 0)
+ break;
+ }
+
+ icalrecur_iterator_free (ritr);
+
+ if (icaltime_is_null_time (next)) {
+ g_propagate_error (
+ error, EDC_ERROR_EX (OtherError,
+ "Invalid occurrence ID"));
+ }
+
+ return index;
+}
+
+void
+e_cal_backend_ews_clear_reminder_is_set (ESoapMessage *msg,
+ gpointer user_data)
+{
+ EwsCalendarConvertData *convert_data = user_data;
+
+ e_ews_message_start_item_change (
+ msg,
+ convert_data->change_type,
+ convert_data->item_id,
+ convert_data->change_key,
+ convert_data->index);
+
+ e_ews_message_start_set_item_field (msg, "ReminderIsSet","item", "CalendarItem");
+
+ e_ews_message_write_string_parameter (msg, "ReminderIsSet", NULL, "false");
+
+ e_ews_message_end_set_item_field (msg);
+
+ e_ews_message_end_item_change (msg);
+}
+
+void
+e_cal_backend_ews_prepare_free_busy_request (ESoapMessage *msg,
+ gpointer user_data)
+{
+ EwsCalendarConvertData *convert_data = user_data;
+ GSList *addr;
+ icaltimetype t_start, t_end;
+ icaltimezone *utc_zone = icaltimezone_get_utc_timezone ();
+
+ ewscal_set_availability_timezone (msg, utc_zone);
+
+ e_soap_message_start_element (msg, "MailboxDataArray", "messages", NULL);
+
+ for (addr = convert_data->users; addr; addr = addr->next) {
+ e_soap_message_start_element (msg, "MailboxData", NULL, NULL);
+
+ e_soap_message_start_element (msg, "Email", NULL, NULL);
+ e_ews_message_write_string_parameter (msg, "Address", NULL, addr->data);
+ e_soap_message_end_element (msg); /* "Email" */
+
+ e_ews_message_write_string_parameter (msg, "AttendeeType", NULL, "Required");
+ e_ews_message_write_string_parameter (msg, "ExcludeConflicts", NULL, "false");
+
+ e_soap_message_end_element (msg); /* "MailboxData" */
+ }
+
+ e_soap_message_end_element (msg); /* "MailboxDataArray" */
+
+ e_soap_message_start_element (msg, "FreeBusyViewOptions", NULL, NULL);
+
+ e_soap_message_start_element (msg, "TimeWindow", NULL, NULL);
+ t_start = icaltime_from_timet_with_zone (convert_data->start, 0, utc_zone);
+ t_end = icaltime_from_timet_with_zone (convert_data->end, 0, utc_zone);
+ ewscal_set_time (msg, "StartTime", &t_start, FALSE);
+ ewscal_set_time (msg, "EndTime", &t_end, FALSE);
+ e_soap_message_end_element (msg); /* "TimeWindow" */
+
+ e_ews_message_write_string_parameter (msg, "MergedFreeBusyIntervalInMinutes", NULL, "60");
+ e_ews_message_write_string_parameter (msg, "RequestedView", NULL, "DetailedMerged");
+
+ e_soap_message_end_element (msg); /* "FreeBusyViewOptions" */
+}
+
+void
+e_cal_backend_ews_prepare_set_free_busy_status (ESoapMessage *msg,
+ gpointer user_data)
+{
+ EwsCalendarConvertData *data = user_data;
+
+ e_ews_message_start_item_change (msg, E_EWS_ITEMCHANGE_TYPE_ITEM, data->item_id, data->change_key, 0);
+
+ e_ews_message_start_set_item_field (msg, "LegacyFreeBusyStatus", "calendar", "CalendarItem");
+
+ e_ews_message_write_string_parameter (msg, "LegacyFreeBusyStatus", NULL, "Free");
+
+ e_ews_message_end_set_item_field (msg);
+
+ e_ews_message_end_item_change (msg);
+}
+
+void
+e_cal_backend_ews_prepare_accept_item_request (ESoapMessage *msg,
+ gpointer user_data)
+{
+ EwsCalendarConvertData *data = user_data;
+ const gchar *response_type = data->response_type;
+
+ /* FORMAT OF A SAMPLE SOAP MESSAGE:
http://msdn.microsoft.com/en-us/library/aa566464%28v=exchg.140%29.aspx
+ * Accept and Decline meeting have same method code (10032)
+ * The real status is reflected at Attendee property PARTSTAT
+ * need to find current user as attendee and make a decision what to do.
+ * Prepare AcceptItem node in the SOAP message */
+
+ if (response_type && !g_ascii_strcasecmp (response_type, "ACCEPTED"))
+ e_soap_message_start_element (msg, "AcceptItem", NULL, NULL);
+ else if (response_type && !g_ascii_strcasecmp (response_type, "DECLINED"))
+ e_soap_message_start_element (msg, "DeclineItem", NULL, NULL);
+ else
+ e_soap_message_start_element (msg, "TentativelyAcceptItem", NULL, NULL);
+
+ e_soap_message_start_element (msg, "ReferenceItemId", NULL, NULL);
+ e_soap_message_add_attribute (msg, "Id", data->item_id, NULL, NULL);
+ e_soap_message_add_attribute (msg, "ChangeKey", data->change_key, NULL, NULL);
+ e_soap_message_end_element (msg); // "ReferenceItemId"
+
+ /* end of "AcceptItem" */
+ e_soap_message_end_element (msg);
+}
diff --git a/src/calendar/e-cal-backend-ews-utils.h b/src/calendar/e-cal-backend-ews-utils.h
index 8563749..d7b654d 100644
--- a/src/calendar/e-cal-backend-ews-utils.h
+++ b/src/calendar/e-cal-backend-ews-utils.h
@@ -26,13 +26,37 @@
#include <libical/icaltimezone.h>
#include "server/e-ews-connection.h"
+#include "server/e-ews-item-change.h"
#include "e-cal-backend-ews.h"
G_BEGIN_DECLS
+#define EDC_ERROR(_code) e_data_cal_create_error (_code, NULL)
+#define EDC_ERROR_EX(_code, _msg) e_data_cal_create_error (_code, _msg)
+
#define MINUTES_IN_HOUR 60
#define SECS_IN_MINUTE 60
+typedef struct {
+ EEwsConnection *connection;
+ icaltimezone *default_zone;
+ gchar *user_email;
+ gchar *response_type; /* Accept */
+ GSList *users;
+ ECalComponent *comp;
+ ECalComponent *old_comp;
+ icalcomponent *icalcomp;
+ gchar *item_id;
+ gchar *change_key;
+ EEwsItemChangeType change_type;
+ gint index;
+ time_t start;
+ time_t end;
+} EwsCalendarConvertData;
+
+EwsCalendarConvertData *ews_calendar_convert_data_new (void);
+void ews_calendar_convert_data_free (EwsCalendarConvertData *convert_data);
+
const gchar *e_ews_collect_organizer (icalcomponent *comp);
void e_ews_collect_attendees (icalcomponent *comp, GSList **required, GSList **optional, GSList **resource);
@@ -55,6 +79,15 @@ void e_cal_backend_ews_populate_tz_msdn_to_ical (void);
void e_cal_backend_ews_unref_tz_ical_to_msdn (void);
void e_cal_backend_ews_unref_tz_msdn_to_ical (void);
+void e_cal_backend_ews_convert_calcomp_to_xml (ESoapMessage *msg, gpointer user_data);
+void e_cal_backend_ews_convert_component_to_updatexml (ESoapMessage *msg, gpointer user_data);
+void e_cal_backend_ews_clear_reminder_is_set (ESoapMessage *msg, gpointer user_data);
+void e_cal_backend_ews_prepare_free_busy_request (ESoapMessage *msg, gpointer user_data);
+void e_cal_backend_ews_prepare_set_free_busy_status (ESoapMessage *msg,gpointer user_data);
+void e_cal_backend_ews_prepare_accept_item_request (ESoapMessage *msg, gpointer user_data);
+
+guint e_cal_backend_ews_rid_to_index (icaltimezone *timezone, const gchar *rid, icalcomponent *comp, GError
**error);
+
G_END_DECLS
#endif
diff --git a/src/calendar/e-cal-backend-ews.c b/src/calendar/e-cal-backend-ews.c
index 47abae6..120cab9 100644
--- a/src/calendar/e-cal-backend-ews.c
+++ b/src/calendar/e-cal-backend-ews.c
@@ -40,9 +40,6 @@
#include <libical/icalproperty.h>
#include <libical/icalparameter.h>
-#include "server/e-ews-item-change.h"
-#include "server/e-ews-message.h"
-#include "server/e-soap-response.h"
#include "server/e-source-ews-folder.h"
#include "utils/ews-camel-common.h"
@@ -91,9 +88,6 @@ struct _ECalBackendEwsPrivate {
#define PRIV_LOCK(p) (g_rec_mutex_lock (&(p)->rec_mutex))
#define PRIV_UNLOCK(p) (g_rec_mutex_unlock (&(p)->rec_mutex))
-#define EDC_ERROR(_code) e_data_cal_create_error (_code, NULL)
-#define EDC_ERROR_EX(_code, _msg) e_data_cal_create_error (_code, _msg)
-
#define SYNC_KEY "sync-state"
#define EWS_MAX_FETCH_COUNT 100
#define REFRESH_INTERVAL 600
@@ -136,7 +130,6 @@ struct _ECalBackendEwsPrivate {
/* Forward Declarations */
static void ews_cal_component_get_item_id (ECalComponent *comp, gchar **itemid, gchar **changekey);
static gboolean ews_start_sync (gpointer data);
-static icaltimezone * e_cal_get_timezone_from_ical_component (ECalBackend *backend, icalcomponent *comp);
static gpointer ews_start_sync_thread (gpointer data);
static void e_cal_backend_ews_authenticator_init
(ESourceAuthenticatorInterface *interface);
@@ -310,37 +303,47 @@ exit:
e_data_cal_respond_add_timezone (cal, context, error);
}
+typedef enum {
+ E_EWS_ATTACHMENT_TYPE_NOTHING = 0,
+ E_EWS_ATTACHMENT_TYPE_CREATE,
+ E_EWS_ATTACHMENT_TYPE_UPDATE
+} EEwsAttachmentType;
+
typedef struct {
- ECalBackendEws *cbews;
- EDataCal *cal;
- guint32 context;
- gchar *itemid;
- gchar *changekey;
- gboolean is_occurrence;
- gint instance_index;
-} EwsDiscardAlarmData;
-
-static void clear_reminder_is_set (ESoapMessage *msg, gpointer user_data)
-{
- EwsDiscardAlarmData *edad = user_data;
- EEwsItemChangeType change_type;
+ ECalBackendEws *cbews; /* Create, Remove, Modify, FreeBusy, Attachments, DiscardAlarm */
+ ECalComponent *comp; /* Create, Remove, Modify, FreeBusy, Attachments */
+ ECalComponent *extra_comp; /* Modify, Attachments: used as old_comp. Remove: used as parent_comp */
+ EDataCal *cal; /* Create, Remove, Modify, FreeBusy, Attachments, DiscardAlarm */
+ GSList *users; /* FreeBusy */
+ gchar *item_id; /* Accept, Remove, Modify, Attachments, DiscardAlarm */
+ gchar *rid; /* Remove */
+ EEwsAttachmentType cb_type; /* Attachments */
+ ECalObjModType mod; /* Remove */
+ guint32 context; /* Create, Remove, Modify, FreeBusy, Attachments, DiscardAlarm */
+} EwsCalendarAsyncData;
- if (edad->is_occurrence)
- change_type = E_EWS_ITEMCHANGE_TYPE_OCCURRENCEITEM;
- else
- change_type = E_EWS_ITEMCHANGE_TYPE_ITEM;
+static void
+e_cal_backend_ews_async_data_free (EwsCalendarAsyncData *async_data)
+{
+ if (async_data != NULL) {
+ if (async_data->cbews != NULL)
+ g_object_unref (async_data->cbews);
- e_ews_message_start_item_change (
- msg, change_type,
- edad->itemid, edad->changekey, edad->instance_index);
+ if (async_data->comp != NULL)
+ g_object_unref (async_data->comp);
- e_ews_message_start_set_item_field (msg, "ReminderIsSet","item", "CalendarItem");
+ if (async_data->extra_comp != NULL)
+ g_object_unref (async_data->extra_comp);
- e_ews_message_write_string_parameter (msg, "ReminderIsSet", NULL, "false");
+ if (async_data->cal != NULL)
+ g_object_unref (async_data->cal);
- e_ews_message_end_set_item_field (msg);
+ g_slist_free_full (async_data->users, g_free);
+ g_free (async_data->item_id);
+ g_free (async_data->rid);
- e_ews_message_end_item_change (msg);
+ g_free (async_data);
+ }
}
static void
@@ -349,7 +352,7 @@ ews_cal_discard_alarm_cb (GObject *object,
gpointer user_data)
{
EEwsConnection *cnc = E_EWS_CONNECTION (object);
- EwsDiscardAlarmData *edad = user_data;
+ EwsCalendarAsyncData *edad = user_data;
GError *error = NULL;
if (!e_ews_connection_update_items_finish (cnc, res, NULL, &error)) {
@@ -359,11 +362,7 @@ ews_cal_discard_alarm_cb (GObject *object,
convert_error_to_edc_error (&error);
e_data_cal_respond_discard_alarm (edad->cal, edad->context, error);
- g_free (edad->itemid);
- g_free (edad->changekey);
- g_object_unref (edad->cbews);
- g_object_unref (edad->cal);
- g_free (edad);
+ e_cal_backend_ews_async_data_free (edad);
}
static void
@@ -377,7 +376,8 @@ e_cal_backend_ews_discard_alarm (ECalBackend *backend,
{
ECalBackendEws *cbews = (ECalBackendEws *) backend;
ECalBackendEwsPrivate *priv;
- EwsDiscardAlarmData *edad;
+ EwsCalendarAsyncData *edad;
+ EwsCalendarConvertData convert_data;
ECalComponent *comp;
GError *local_error = NULL;
@@ -404,7 +404,7 @@ e_cal_backend_ews_discard_alarm (ECalBackend *backend,
/* FIXME: Can't there be multiple alarms for each event? Or does
* Exchange not support that? */
- edad = g_new0 (EwsDiscardAlarmData, 1);
+ edad = g_new0 (EwsCalendarAsyncData, 1);
edad->cbews = g_object_ref (cbews);
edad->cal = g_object_ref (cal);
edad->context = context;
@@ -412,31 +412,31 @@ e_cal_backend_ews_discard_alarm (ECalBackend *backend,
if (e_cal_component_has_recurrences (comp)) {
gint *index;
- edad->is_occurrence = TRUE;
+ convert_data.change_type = E_EWS_ITEMCHANGE_TYPE_OCCURRENCEITEM;
e_cal_component_get_sequence (comp, &index);
if (index != NULL) {
/*Microsoft is counting the occurrences starting from 1
where EcalComponent is starting from zerro */
- edad->instance_index = *index + 1;
+ convert_data.index = *index + 1;
e_cal_component_free_sequence (index);
} else {
- edad->is_occurrence = FALSE;
- edad->instance_index = -1;
+ convert_data.change_type = E_EWS_ITEMCHANGE_TYPE_ITEM;
+ convert_data.index = -1;
}
- }
- else {
- edad->is_occurrence = FALSE;
- edad->instance_index = -1;
+ } else {
+ convert_data.change_type = E_EWS_ITEMCHANGE_TYPE_ITEM;
+ convert_data.index = -1;
}
- ews_cal_component_get_item_id (comp, &edad->itemid, &edad->changekey);
+ ews_cal_component_get_item_id (comp, &convert_data.item_id, &convert_data.change_key);
e_ews_connection_update_items (
priv->cnc, EWS_PRIORITY_MEDIUM,
"AlwaysOverwrite", NULL,
"SendToNone", NULL,
- clear_reminder_is_set, edad,
+ e_cal_backend_ews_clear_reminder_is_set,
+ &convert_data,
priv->cancellable,
ews_cal_discard_alarm_cb,
edad);
@@ -1012,24 +1012,40 @@ ews_cal_append_exdate (ECalBackendEws *cbews,
g_object_unref (old_comp);
}
-typedef struct {
- ECalBackendEws *cbews;
- EDataCal *cal;
- ECalComponent *comp, *parent;
- guint32 context;
- EwsId item_id;
- guint index;
- gchar *rid;
- gboolean modified;
- ECalObjModType mod;
-} EwsRemoveData;
+static icaltimezone *
+e_cal_backend_ews_get_timezone_from_ical_component (ECalBackend *backend,
+ icalcomponent *comp)
+{
+ ETimezoneCache *timezone_cache;
+ icalproperty *prop;
+ icalparameter *param;
+
+ timezone_cache = E_TIMEZONE_CACHE (backend);
+
+ prop = icalcomponent_get_first_property (
+ comp, ICAL_DTSTART_PROPERTY);
+ param = icalproperty_get_first_parameter (
+ prop, ICAL_TZID_PARAMETER);
+
+ if (param != NULL) {
+ const gchar *tzid;
+
+ tzid = icalparameter_get_tzid (param);
+
+ return e_timezone_cache_get_timezone (timezone_cache, tzid);
+ }
+
+ g_warning ("EEE Cant figure the relevant timezone of the component\n");
+
+ return NULL;
+}
static void
ews_cal_remove_object_cb (GObject *object,
GAsyncResult *res,
gpointer user_data)
{
- EwsRemoveData *remove_data = user_data;
+ EwsCalendarAsyncData *remove_data = user_data;
GSimpleAsyncResult *simple;
GError *error = NULL;
@@ -1038,8 +1054,11 @@ ews_cal_remove_object_cb (GObject *object,
if (!g_simple_async_result_propagate_error (simple, &error) || error->code ==
EWS_CONNECTION_ERROR_ITEMNOTFOUND) {
/* FIXME: This is horrid. Will bite us when we start to delete
* more than one item at a time... */
- if (remove_data->comp) ews_cal_delete_comp (remove_data->cbews, remove_data->comp,
remove_data->item_id.id);
- if (remove_data->parent) ews_cal_append_exdate (remove_data->cbews, remove_data->parent,
remove_data->rid, remove_data->mod);
+ if (remove_data->comp != NULL)
+ ews_cal_delete_comp (remove_data->cbews, remove_data->comp, remove_data->item_id);
+ if (remove_data->extra_comp != NULL)
+ ews_cal_append_exdate (
+ remove_data->cbews, remove_data->extra_comp, remove_data->rid,
remove_data->mod);
}
convert_error_to_edc_error (&error);
@@ -1051,51 +1070,7 @@ ews_cal_remove_object_cb (GObject *object,
g_clear_error (&error);
}
- g_free (remove_data->item_id.id);
- g_free (remove_data->item_id.change_key);
- g_object_unref (remove_data->cbews);
- if (remove_data->comp) g_object_unref (remove_data->comp);
- if (remove_data->parent) g_object_unref (remove_data->parent);
- g_object_unref (remove_data->cal);
- if (remove_data->rid) g_free (remove_data->rid);
- g_free (remove_data);
-}
-
-static guint
-e_cal_rid_to_index (ECalBackend *backend,
- const gchar *rid,
- icalcomponent *comp,
- GError **error)
-{
- guint index = 1;
- icalproperty *prop = icalcomponent_get_first_property (comp, ICAL_RRULE_PROPERTY);
- struct icalrecurrencetype rule = icalproperty_get_rrule (prop);
- struct icaltimetype dtstart = icalcomponent_get_dtstart (comp);
- icalrecur_iterator * ritr;
- icaltimetype next, o_time;
-
- /* icalcomponent_get_datetime needs a fix to initialize ret.zone to NULL. If a timezone is not
- * found in libical, it remains uninitialized in that function causing invalid read or crash. so
- * we set the timezone as we cannot identify if it has a valid timezone or not */
- dtstart.zone = e_cal_get_timezone_from_ical_component (backend, comp);
- ritr = icalrecur_iterator_new (rule, dtstart);
- next = icalrecur_iterator_next (ritr);
- o_time = icaltime_from_string (rid);
- o_time.zone = dtstart.zone;
-
- for (; !icaltime_is_null_time (next); next = icalrecur_iterator_next (ritr), index++) {
- if (icaltime_compare_date_only (o_time, next) == 0) break;
- }
-
- icalrecur_iterator_free (ritr);
-
- if (icaltime_is_null_time (next)) {
- g_propagate_error (
- error, EDC_ERROR_EX (OtherError,
- "Invalid occurrence ID"));
- }
-
- return index;
+ e_cal_backend_ews_async_data_free (remove_data);
}
static void
@@ -1107,7 +1082,7 @@ e_cal_backend_ews_remove_object (ECalBackend *backend,
const gchar *rid,
ECalObjModType mod)
{
- EwsRemoveData *remove_data;
+ EwsCalendarAsyncData *remove_data;
ECalBackendEws *cbews = (ECalBackendEws *) backend;
ECalBackendEwsPrivate *priv;
ECalComponent *comp, *parent = NULL;
@@ -1152,7 +1127,7 @@ e_cal_backend_ews_remove_object (ECalBackend *backend,
g_warning ("EEE Cant find component with uid:%s & rid:%s\n", uid, rid);
g_propagate_error (&error, EDC_ERROR (ObjectNotFound));
PRIV_UNLOCK (priv);
- goto errorlvl1;
+ goto exit;
}
ews_cal_component_get_item_id ((comp ? comp : parent), &item_id.id, &item_id.change_key);
@@ -1163,45 +1138,54 @@ e_cal_backend_ews_remove_object (ECalBackend *backend,
g_propagate_error (
&error, EDC_ERROR_EX (OtherError,
"Cannot determine EWS ItemId"));
- goto errorlvl2;
+ goto exit;
}
if (parent && !comp) {
- index = e_cal_rid_to_index (backend, rid, e_cal_component_get_icalcomponent (parent), &error);
- if (error) goto errorlvl2;
+ index = e_cal_backend_ews_rid_to_index (
+ e_cal_backend_ews_get_timezone_from_ical_component (
+ backend,
+ e_cal_component_get_icalcomponent (comp)),
+ rid,
+ e_cal_component_get_icalcomponent (parent),
+ &error);
+
+ if (error != NULL)
+ goto exit;
}
- remove_data = g_new0 (EwsRemoveData, 1);
+ remove_data = g_new0 (EwsCalendarAsyncData, 1);
remove_data->cbews = g_object_ref (cbews);
remove_data->comp = comp;
- remove_data->parent = parent;
+ remove_data->extra_comp = parent;
remove_data->cal = g_object_ref (cal);
remove_data->context = context;
- remove_data->index = index;
- remove_data->item_id.id = item_id.id;
- remove_data->item_id.change_key = item_id.change_key;
+ remove_data->item_id = g_strdup (item_id.id);
remove_data->rid = (rid ? g_strdup (rid) : NULL);
remove_data->mod = mod;
e_ews_connection_delete_item (
- priv->cnc, EWS_PRIORITY_MEDIUM, &remove_data->item_id, index,
+ priv->cnc, EWS_PRIORITY_MEDIUM, &item_id, index,
EWS_HARD_DELETE, EWS_SEND_TO_NONE, EWS_ALL_OCCURRENCES,
priv->cancellable,
ews_cal_remove_object_cb,
remove_data);
+
return;
-errorlvl2:
- if (comp) g_object_unref (comp);
+exit:
+ if (comp != NULL)
+ g_object_unref (comp);
-errorlvl1:
- if (parent) g_object_unref (parent);
+ if (parent != NULL)
+ g_object_unref (parent);
-exit:
convert_error_to_edc_error (&error);
+
if (context)
e_data_cal_respond_remove_objects (cal, context, error, NULL, NULL, NULL);
- else if (error) {
+
+ if (error != NULL) {
g_warning ("Remove object error : %s\n", error->message);
g_clear_error (&error);
}
@@ -1249,376 +1233,6 @@ e_cal_backend_ews_remove_objects (ECalBackend *backend,
static icaltimezone * resolve_tzid (const gchar *tzid, gpointer user_data);
static void put_component_to_store (ECalBackendEws *cbews,ECalComponent *comp);
-typedef struct {
- ECalBackendEws *cbews;
- EDataCal *cal;
- ECalComponent *comp;
- guint32 context;
-} EwsCreateData;
-
-typedef struct {
- ECalBackendEws *cbews;
- icalcomponent *icalcomp;
-} EwsConvertData;
-
-static void
-add_attendees_list_to_message (ESoapMessage *msg,
- const gchar *listname,
- GSList *list)
-{
- GSList *item;
-
- e_soap_message_start_element (msg, listname, NULL, NULL);
-
- for (item = list; item != NULL; item = item->next) {
- e_soap_message_start_element (msg, "Attendee", NULL, NULL);
- e_soap_message_start_element (msg, "Mailbox", NULL, NULL);
-
- e_ews_message_write_string_parameter (msg, "EmailAddress", NULL, item->data);
-
- e_soap_message_end_element (msg); /* "Mailbox" */
- e_soap_message_end_element (msg); /* "Attendee" */
- }
-
- e_soap_message_end_element (msg);
-}
-
-static void
-convert_sensitivity_calcomp_to_xml (ESoapMessage *msg,
- icalcomponent *icalcomp)
-{
- icalproperty *prop;
-
- g_return_if_fail (msg != NULL);
- g_return_if_fail (icalcomp != NULL);
-
- prop = icalcomponent_get_first_property (icalcomp, ICAL_CLASS_PROPERTY);
- if (prop) {
- icalproperty_class classify = icalproperty_get_class (prop);
- if (classify == ICAL_CLASS_PUBLIC) {
- e_ews_message_write_string_parameter (msg, "Sensitivity", NULL, "Normal");
- } else if (classify == ICAL_CLASS_PRIVATE) {
- e_ews_message_write_string_parameter (msg, "Sensitivity", NULL, "Private");
- } else if (classify == ICAL_CLASS_CONFIDENTIAL) {
- e_ews_message_write_string_parameter (msg, "Sensitivity", NULL, "Personal");
- }
- }
-}
-
-static void
-convert_categories_calcomp_to_xml (ESoapMessage *msg,
- ECalComponent *comp,
- icalcomponent *icalcomp)
-{
- GSList *categ_list, *citer;
-
- g_return_if_fail (msg != NULL);
- g_return_if_fail (icalcomp != NULL);
-
- if (comp) {
- g_object_ref (comp);
- } else {
- icalcomponent *clone = icalcomponent_new_clone (icalcomp);
-
- comp = e_cal_component_new ();
- if (!e_cal_component_set_icalcomponent (comp, clone)) {
- icalcomponent_free (clone);
- g_object_unref (comp);
-
- return;
- }
- }
-
- e_cal_component_get_categories_list (comp, &categ_list);
-
- g_object_unref (comp);
-
- if (!categ_list)
- return;
-
- e_soap_message_start_element (msg, "Categories", NULL, NULL);
-
- for (citer = categ_list; citer; citer = g_slist_next (citer)) {
- const gchar *category = citer->data;
-
- if (!category || !*category)
- continue;
-
- e_ews_message_write_string_parameter (msg, "String", NULL, category);
- }
-
- e_soap_message_end_element (msg); /* Categories */
-
- e_cal_component_free_categories_list (categ_list);
-}
-
-static void
-convert_vevent_calcomp_to_xml (ESoapMessage *msg,
- gpointer user_data)
-{
- EwsConvertData *convert_data = user_data;
- icalcomponent *icalcomp = convert_data->icalcomp;
- ECalComponent *comp = e_cal_component_new ();
- GSList *required = NULL, *optional = NULL, *resource = NULL;
- icaltimetype dtstart, dtend;
- icalproperty *prop;
- gboolean has_alarms;
- const gchar *value;
-
- e_cal_component_set_icalcomponent (comp, icalcomp);
-
- /* FORMAT OF A SAMPLE SOAP MESSAGE: http://msdn.microsoft.com/en-us/library/aa564690.aspx */
-
- /* Prepare CalendarItem node in the SOAP message */
- e_soap_message_start_element (msg, "CalendarItem", NULL, NULL);
-
- /* subject */
- value = icalcomponent_get_summary (icalcomp);
- if (value)
- e_ews_message_write_string_parameter (msg, "Subject", NULL, value);
-
- convert_sensitivity_calcomp_to_xml (msg, icalcomp);
-
- /* description */
- value = icalcomponent_get_description (icalcomp);
- if (value)
- e_ews_message_write_string_parameter_with_attribute (msg, "Body", NULL, value, "BodyType",
"Text");
-
- convert_categories_calcomp_to_xml (msg, comp, icalcomp);
-
- /* set alarms */
- has_alarms = e_cal_component_has_alarms (comp);
- if (has_alarms)
- ews_set_alarm (msg, comp);
- else
- e_ews_message_write_string_parameter (msg, "ReminderIsSet", NULL, "false");
-
- /* start time, end time and meeting time zone */
- dtstart = icalcomponent_get_dtstart (icalcomp);
- dtend = icalcomponent_get_dtend (icalcomp);
-
- ewscal_set_time (msg, "Start", &dtstart, FALSE);
- ewscal_set_time (msg, "End", &dtend, FALSE);
- /* We have to do the time zone(s) later, or the server rejects the request */
-
- /* All day event ? */
- if (icaltime_is_date (dtstart))
- e_ews_message_write_string_parameter (msg, "IsAllDayEvent", NULL, "true");
-
- /*freebusy*/
- prop = icalcomponent_get_first_property (icalcomp, ICAL_TRANSP_PROPERTY);
- if (!g_strcmp0 (icalproperty_get_value_as_string (prop), "TRANSPARENT"))
- e_ews_message_write_string_parameter (msg, "LegacyFreeBusyStatus",NULL,"Free");
- else
- e_ews_message_write_string_parameter (msg, "LegacyFreeBusyStatus",NULL,"Busy");
-
- /* location */
- value = icalcomponent_get_location (icalcomp);
- if (value)
- e_ews_message_write_string_parameter (msg, "Location", NULL, value);
-
- /* collect attendees */
- e_ews_collect_attendees (icalcomp, &required, &optional, &resource);
-
- if (required != NULL) {
- add_attendees_list_to_message (msg, "RequiredAttendees", required);
- g_slist_free (required);
- }
- if (optional != NULL) {
- add_attendees_list_to_message (msg, "OptionalAttendees", optional);
- g_slist_free (optional);
- }
- if (resource != NULL) {
- add_attendees_list_to_message (msg, "Resources", resource);
- g_slist_free (resource);
- }
- /* end of attendees */
-
- /* Recurrence */
- prop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
- if (prop != NULL) {
- ewscal_set_reccurence (msg, prop, &dtstart);
- }
-
- /* We have to cast these because libical puts a const pointer into the
- * icaltimetype, but its basic read-only icaltimezone_foo() functions
- * take a non-const pointer! */
- if (e_ews_connection_satisfies_server_version (convert_data->cbews->priv->cnc, E_EWS_EXCHANGE_2010)) {
- const gchar *ical_location;
- const gchar *msdn_location;
- icaltimezone *tzid;
- GSList *msdn_locations = NULL;
- GSList *tzds = NULL;
-
- tzid = (icaltimezone *)(dtstart.zone ? dtstart.zone :
convert_data->cbews->priv->default_zone);
- ical_location = icaltimezone_get_location (tzid);
- msdn_location = e_cal_backend_ews_tz_util_get_msdn_equivalent (ical_location);
-
- msdn_locations = g_slist_prepend (msdn_locations, (gchar *) msdn_location);
-
- tzid = (icaltimezone *)(dtend.zone ? dtend.zone : convert_data->cbews->priv->default_zone);
- ical_location = icaltimezone_get_location (tzid);
- msdn_location = e_cal_backend_ews_tz_util_get_msdn_equivalent (ical_location);
-
- msdn_locations = g_slist_prepend (msdn_locations, (gchar *) msdn_location);
-
- msdn_locations = g_slist_reverse (msdn_locations);
-
- if (e_ews_connection_get_server_time_zones_sync (
- convert_data->cbews->priv->cnc,
- EWS_PRIORITY_MEDIUM,
- msdn_locations,
- &tzds,
- NULL,
- NULL)) {
- ewscal_set_timezone (msg, "StartTimeZone", tzds->data);
- ewscal_set_timezone (msg, "EndTimeZone", tzds->data);
- }
-
- g_slist_free (msdn_locations);
- g_slist_free_full (tzds, (GDestroyNotify) e_ews_calendar_time_zone_definition_free);
- } else {
- ewscal_set_meeting_timezone (
- msg,
- (icaltimezone *)(dtstart.zone ? dtstart.zone :
convert_data->cbews->priv->default_zone));
- }
-
- // end of "CalendarItem"
- e_soap_message_end_element (msg);
-}
-
-static void
-convert_vtodo_calcomp_to_xml (ESoapMessage *msg,
- gpointer user_data)
-{
- EwsConvertData *convert_data = user_data;
- icalcomponent *icalcomp = convert_data->icalcomp;
- icalproperty *prop;
- icaltimetype dt;
- gint value;
- gchar buffer[16];
-
- e_soap_message_start_element (msg, "Task", NULL, NULL);
-
- e_ews_message_write_string_parameter (msg, "Subject", NULL, icalcomponent_get_summary (icalcomp));
-
- convert_sensitivity_calcomp_to_xml (msg, icalcomp);
-
- e_ews_message_write_string_parameter_with_attribute (msg, "Body", NULL, icalcomponent_get_description
(icalcomp), "BodyType", "Text");
-
- convert_categories_calcomp_to_xml (msg, NULL, icalcomp);
-
- prop = icalcomponent_get_first_property (icalcomp, ICAL_DUE_PROPERTY);
- if (prop) {
- dt = icalproperty_get_due (prop);
- ewscal_set_time (msg, "DueDate", &dt, TRUE);
- }
-
- prop = icalcomponent_get_first_property (icalcomp, ICAL_PERCENTCOMPLETE_PROPERTY);
- if (prop) {
- value = icalproperty_get_percentcomplete (prop);
- snprintf (buffer, 16, "%d", value);
- e_ews_message_write_string_parameter (msg, "PercentComplete", NULL, buffer);
- }
-
- prop = icalcomponent_get_first_property (icalcomp, ICAL_DTSTART_PROPERTY);
- if (prop) {
- dt = icalproperty_get_dtstart (prop);
- ewscal_set_time (msg, "StartDate", &dt, TRUE);
- }
-
- prop = icalcomponent_get_first_property (icalcomp, ICAL_STATUS_PROPERTY);
- if (prop) {
- switch (icalproperty_get_status (prop)) {
- case ICAL_STATUS_INPROCESS:
- e_ews_message_write_string_parameter (msg, "Status", NULL, "InProgress");
- break;
- case ICAL_STATUS_COMPLETED:
- e_ews_message_write_string_parameter (msg, "Status", NULL, "Completed");
- break;
- default:
- break;
- }
- }
-
- e_soap_message_end_element (msg); // "Task"
-}
-
-static void
-convert_vjournal_calcomp_to_xml (ESoapMessage *msg,
- gpointer user_data)
-{
- EwsConvertData *convert_data = user_data;
- icalcomponent *icalcomp = convert_data->icalcomp;
- const gchar *text;
-
- e_soap_message_start_element (msg, "Message", NULL, NULL);
- e_ews_message_write_string_parameter (msg, "ItemClass", NULL, "IPM.StickyNote");
-
- e_ews_message_write_string_parameter (msg, "Subject", NULL, icalcomponent_get_summary (icalcomp));
-
- convert_sensitivity_calcomp_to_xml (msg, icalcomp);
-
- text = icalcomponent_get_description (icalcomp);
- if (!text || !*text)
- text = icalcomponent_get_summary (icalcomp);
- e_ews_message_write_string_parameter_with_attribute (msg, "Body", NULL, text, "BodyType", "Text");
-
- convert_categories_calcomp_to_xml (msg, NULL, icalcomp);
-
- e_soap_message_end_element (msg); /* Message */
-}
-
-static void
-convert_calcomp_to_xml (ESoapMessage *msg,
- gpointer user_data)
-{
- EwsConvertData *convert_data = user_data;
-
- switch (icalcomponent_isa (convert_data->icalcomp)) {
- case ICAL_VEVENT_COMPONENT:
- convert_vevent_calcomp_to_xml (msg, user_data);
- break;
- case ICAL_VTODO_COMPONENT:
- convert_vtodo_calcomp_to_xml (msg, user_data);
- break;
- case ICAL_VJOURNAL_COMPONENT:
- convert_vjournal_calcomp_to_xml (msg, user_data);
- break;
- default:
- g_warn_if_reached ();
- break;
- }
-
- g_object_unref (convert_data->cbews);
- g_free (convert_data);
-}
-
-/*I will unate both type, they are same now*/
-typedef struct {
- ECalBackendEws *cbews;
- ECalComponent *comp;
- gint cb_type; /* 0 - nothing,
- 1 - create,
- 2 - update */
- EDataCal *cal;
- guint32 context;
- ECalComponent *oldcomp;
- gchar *itemid;
- gchar *changekey;
-
-} EwsAttachmentsData;
-
-typedef struct {
- ECalBackendEws *cbews;
- EDataCal *cal;
- ECalComponent *comp;
- ECalComponent *oldcomp;
- guint32 context;
- gchar *itemid;
- gchar *changekey;
-} EwsModifyData;
-
static void
e_cal_backend_ews_modify_object (ECalBackend *backend,
EDataCal *cal,
@@ -1627,8 +1241,6 @@ e_cal_backend_ews_modify_object (ECalBackend *backend,
const gchar *calobj,
ECalObjModType mod);
-static void convert_component_to_updatexml (ESoapMessage *msg,
- gpointer user_data);
static void ews_cal_modify_object_cb (GObject *object,
GAsyncResult *res,
gpointer user_data);
@@ -1639,7 +1251,7 @@ ews_create_attachments_cb (GObject *object,
gpointer user_data)
{
EEwsConnection *cnc = E_EWS_CONNECTION (object);
- EwsAttachmentsData *create_data = user_data;
+ EwsCalendarAsyncData *create_data = user_data;
ECalBackendEwsPrivate *priv = create_data->cbews->priv;
gchar *change_key;
GSList *ids, *i;
@@ -1687,26 +1299,27 @@ ews_create_attachments_cb (GObject *object,
e_cal_backend_store_thaw_changes (priv->store);
e_cal_component_get_uid (create_data->comp, &comp_uid);
- if (create_data->cb_type == 1) {
- /*In case we have attendees we have to fake update items,
- * this is the only way to pass attachments in meeting invite mail*/
- if (e_cal_component_has_attendees (create_data->comp)) {
- icalcomponent *icalcomp = e_cal_component_get_icalcomponent (create_data->comp);
- e_cal_backend_ews_modify_object ((ECalBackend *) create_data->cbews,
create_data->cal, 0, NULL, icalcomponent_as_ical_string (icalcomp), E_CAL_OBJ_MOD_ALL);
- }
- } else if (create_data->cb_type == 2) {
+ if (create_data->cb_type == E_EWS_ATTACHMENT_TYPE_UPDATE) {
const gchar *send_meeting_invitations;
const gchar *send_or_save;
- EwsModifyData * modify_data;
+ EwsCalendarAsyncData *modify_data;
+ EwsCalendarConvertData convert_data;
- modify_data = g_new0 (EwsModifyData, 1);
+ modify_data = g_new0 (EwsCalendarAsyncData, 1);
modify_data->cbews = g_object_ref (create_data->cbews);
modify_data->comp = create_data->comp;
- modify_data->oldcomp = create_data->oldcomp;
+ modify_data->extra_comp = create_data->extra_comp;
modify_data->cal = g_object_ref (create_data->cal);
modify_data->context = create_data->context;
- modify_data->itemid = create_data->itemid;
- modify_data->changekey = change_key;
+ modify_data->item_id = create_data->item_id;
+
+ convert_data.connection = create_data->cbews->priv->cnc;
+ convert_data.user_email = create_data->cbews->priv->user_email;
+ convert_data.comp = create_data->comp;
+ convert_data.old_comp = create_data->extra_comp;
+ convert_data.item_id = create_data->item_id;
+ convert_data.change_key = change_key;
+ convert_data.default_zone = create_data->cbews->priv->default_zone;
if (e_cal_component_has_attendees (create_data->comp)) {
send_meeting_invitations = "SendToAllAndSaveCopy";
@@ -1723,20 +1336,30 @@ ews_create_attachments_cb (GObject *object,
send_or_save,
send_meeting_invitations,
priv->folder_id,
- convert_component_to_updatexml,
- modify_data,
+ e_cal_backend_ews_convert_component_to_updatexml,
+ &convert_data,
priv->cancellable,
ews_cal_modify_object_cb,
- modify_data);
+ create_data);
+ } else {
+ if (create_data->cb_type == E_EWS_ATTACHMENT_TYPE_CREATE) {
+ /*In case we have attendees we have to fake update items,
+ * this is the only way to pass attachments in meeting invite mail*/
+ if (e_cal_component_has_attendees (create_data->comp)) {
+ icalcomponent *icalcomp = e_cal_component_get_icalcomponent
(create_data->comp);
+ e_cal_backend_ews_modify_object (
+ E_CAL_BACKEND (create_data->cbews),
+ create_data->cal,
+ 0,
+ NULL,
+ icalcomponent_as_ical_string (icalcomp),
+ E_CAL_OBJ_MOD_ALL);
+ }
+ }
+ e_cal_backend_ews_async_data_free (create_data);
}
g_slist_free (ids);
-
- g_object_unref (create_data->cbews);
- g_object_unref (create_data->cal);
- g_object_unref (create_data->comp);
- if (create_data->oldcomp) g_object_unref (create_data->oldcomp);
- g_free (create_data);
}
static void
@@ -1745,7 +1368,7 @@ ews_create_object_cb (GObject *object,
gpointer user_data)
{
EEwsConnection *cnc = E_EWS_CONNECTION (object);
- EwsCreateData *create_data = user_data;
+ EwsCalendarAsyncData *create_data = user_data;
ECalBackendEws *cbews = create_data->cbews;
ECalBackendEwsPrivate *priv = cbews->priv;
GError *error = NULL;
@@ -1815,7 +1438,7 @@ ews_create_object_cb (GObject *object,
n_attach = e_cal_component_get_num_attachments (create_data->comp);
if (n_attach > 0) {
GSList *info_attachments = NULL;
- EwsAttachmentsData *attach_data = g_new0 (EwsAttachmentsData, 1);
+ EwsCalendarAsyncData *attach_data = g_new0 (EwsCalendarAsyncData, 1);
attach_data->cbews = g_object_ref (create_data->cbews);
attach_data->comp = g_object_ref (create_data->comp);
@@ -1905,13 +1528,7 @@ ews_create_object_cb (GObject *object,
g_slist_free_full (exceptions, g_free);
}
- /* no need to keep reference to the object */
- g_object_unref (create_data->comp);
-
- /* free memory allocated for create_data & unref contained objects */
- g_object_unref (create_data->cbews);
- g_object_unref (create_data->cal);
- g_free (create_data);
+ e_cal_backend_ews_async_data_free (create_data);
}
struct TzidCbData {
@@ -1948,8 +1565,8 @@ e_cal_backend_ews_create_objects (ECalBackend *backend,
GCancellable *cancellable,
const GSList *calobjs)
{
- EwsCreateData *create_data;
- EwsConvertData *convert_data;
+ EwsCalendarAsyncData *create_data;
+ EwsCalendarConvertData convert_data;
EwsFolderId *fid;
ECalBackendEws *cbews;
ECalBackendEwsPrivate *priv;
@@ -1989,7 +1606,7 @@ e_cal_backend_ews_create_objects (ECalBackend *backend,
}
/* parse ical data */
- comp = e_cal_component_new_from_string (calobj);
+ comp = e_cal_component_new_from_string (calobj);
if (comp == NULL) {
g_propagate_error (&error, EDC_ERROR (InvalidObject));
goto exit;
@@ -2021,29 +1638,32 @@ e_cal_backend_ews_create_objects (ECalBackend *backend,
e_cal_component_set_created (comp, ¤t);
e_cal_component_set_last_modified (comp, ¤t);
- create_data = g_new0 (EwsCreateData, 1);
+ create_data = g_new0 (EwsCalendarAsyncData, 1);
create_data->cbews = g_object_ref (cbews);
create_data->comp = comp;
create_data->cal = g_object_ref (cal);
create_data->context = context;
- convert_data = g_new0 (EwsConvertData, 1);
- convert_data->cbews = g_object_ref (cbews);
- convert_data->icalcomp = icalcomp;
+ convert_data.connection = cbews->priv->cnc;
+ convert_data.icalcomp = icalcomp;
+ convert_data.default_zone = cbews->priv->default_zone;
- /*In case we are creating a meeting with attendees and attachments.
+ /*
+ * In case we are creating a meeting with attendees and attachments.
* We have to preform 3 steps in order to allow attendees to receive attachments in their invite
mails.
* 1. create meeting and do not send invites
* 2. create attachments
- * 3. dummy update meeting and send invites to all*/
+ * 3. dummy update meeting and send invites to all
+ */
if (e_cal_component_has_attendees (comp)) {
if (e_cal_component_has_attachments (comp))
send_meeting_invitations = "SendToNone";
else
send_meeting_invitations = "SendToAllAndSaveCopy";
- } else
+ } else {
/*In case of appointment we have to set SendMeetingInvites to SendToNone */
send_meeting_invitations = "SendToNone";
+ }
fid = e_ews_folder_id_new (priv->folder_id, NULL, FALSE);
@@ -2053,8 +1673,8 @@ e_cal_backend_ews_create_objects (ECalBackend *backend,
"SaveOnly",
send_meeting_invitations,
fid,
- convert_calcomp_to_xml,
- convert_data,
+ e_cal_backend_ews_convert_calcomp_to_xml,
+ &convert_data,
cancellable,
ews_create_object_cb,
create_data);
@@ -2074,7 +1694,7 @@ ews_cal_modify_object_cb (GObject *object,
gpointer user_data)
{
EEwsConnection *cnc = E_EWS_CONNECTION (object);
- EwsModifyData *modify_data = user_data;
+ EwsCalendarAsyncData *modify_data = user_data;
ECalBackendEws *cbews = modify_data->cbews;
ECalBackendEwsPrivate *priv = cbews->priv;
GError *error = NULL;
@@ -2093,7 +1713,7 @@ ews_cal_modify_object_cb (GObject *object,
}
g_object_ref (modify_data->comp);
- g_object_ref (modify_data->oldcomp);
+ g_object_ref (modify_data->extra_comp);
e_cal_backend_store_freeze_changes (priv->store);
@@ -2119,9 +1739,9 @@ ews_cal_modify_object_cb (GObject *object,
if (modify_data->context) {
GSList *old_components, *new_components;
- e_cal_backend_notify_component_modified (E_CAL_BACKEND (cbews), modify_data->oldcomp,
modify_data->comp);
+ e_cal_backend_notify_component_modified (E_CAL_BACKEND (cbews), modify_data->extra_comp,
modify_data->comp);
- old_components = g_slist_append (NULL, modify_data->oldcomp);
+ old_components = g_slist_append (NULL, modify_data->extra_comp);
new_components = g_slist_append (NULL, modify_data->comp);
convert_error_to_edc_error (&error);
@@ -2136,7 +1756,7 @@ ews_cal_modify_object_cb (GObject *object,
} else ews_start_sync (modify_data->cbews);
PRIV_LOCK (priv);
- g_hash_table_replace (priv->item_id_hash, g_strdup (modify_data->itemid), g_object_ref
(modify_data->comp));
+ g_hash_table_replace (priv->item_id_hash, g_strdup (modify_data->item_id), g_object_ref
(modify_data->comp));
PRIV_UNLOCK (priv);
e_cal_backend_store_thaw_changes (priv->store);
@@ -2145,474 +1765,7 @@ ews_cal_modify_object_cb (GObject *object,
e_cal_component_free_id (id);
exit:
- g_free (modify_data->itemid);
- g_free (modify_data->changekey);
- g_object_unref (modify_data->comp);
- g_object_unref (modify_data->oldcomp);
- g_object_unref (modify_data->cbews);
- g_object_unref (modify_data->cal);
- g_free (modify_data);
-}
-
-static void
-convert_component_categories_to_updatexml (ECalComponent *comp,
- ESoapMessage *msg,
- const gchar *base_elem_name)
-{
- GSList *categ_list = NULL, *citer;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (msg != NULL);
- g_return_if_fail (base_elem_name != NULL);
-
- e_cal_component_get_categories_list (comp, &categ_list);
- e_ews_message_start_set_item_field (msg, "Categories", "item", base_elem_name);
- e_soap_message_start_element (msg, "Categories", NULL, NULL);
-
- for (citer = categ_list; citer; citer = g_slist_next (citer)) {
- const gchar *category = citer->data;
-
- if (!category || !*category)
- continue;
-
- e_ews_message_write_string_parameter (msg, "String", NULL, category);
- }
-
- e_soap_message_end_element (msg); /* Categories */
- e_ews_message_end_set_item_field (msg);
-
- e_cal_component_free_categories_list (categ_list);
-}
-
-static void
-convert_vevent_property_to_updatexml (ESoapMessage *msg,
- const gchar *name,
- const gchar *value,
- const gchar *prefix,
- const gchar *attr_name,
- const gchar *attr_value)
-{
- e_ews_message_start_set_item_field (msg, name, prefix, "CalendarItem");
- e_ews_message_write_string_parameter_with_attribute (msg, name, NULL, value, attr_name, attr_value);
- e_ews_message_end_set_item_field (msg);
-}
-
-static void
-convert_vevent_component_to_updatexml (ESoapMessage *msg,
- gpointer user_data)
-{
- EwsModifyData *modify_data = user_data;
- icalcomponent *icalcomp = e_cal_component_get_icalcomponent (modify_data->comp);
- icalcomponent *icalcomp_old = e_cal_component_get_icalcomponent (modify_data->oldcomp);
- GSList *required = NULL, *optional = NULL, *resource = NULL;
- icaltimetype dtstart, dtend, dtstart_old, dtend_old;
- icalproperty *prop, *transp;
- const gchar *org_email_address = NULL, *value = NULL, *old_value = NULL;
- gboolean has_alarms, has_alarms_old, dt_changed = FALSE;
- gint alarm = 0, alarm_old = 0;
- gchar *recid;
- GError *error = NULL;
-
- /* Modifying a recurring meeting ? */
- if (icalcomponent_get_first_property (icalcomp_old, ICAL_RRULE_PROPERTY) != NULL) {
- /* A single occurrence ? */
- prop = icalcomponent_get_first_property (icalcomp, ICAL_RECURRENCEID_PROPERTY);
- if (prop != NULL) {
- recid = icalproperty_get_value_as_string_r (prop);
- e_ews_message_start_item_change (
- msg, E_EWS_ITEMCHANGE_TYPE_OCCURRENCEITEM,
- modify_data->itemid, modify_data->changekey, e_cal_rid_to_index
(E_CAL_BACKEND (modify_data->cbews), recid, icalcomp_old, &error));
- free (recid);
- } else {
- e_ews_message_start_item_change (
- msg, E_EWS_ITEMCHANGE_TYPE_ITEM,
- modify_data->itemid, modify_data->changekey, 0);
- }
- } else e_ews_message_start_item_change (msg, E_EWS_ITEMCHANGE_TYPE_ITEM,
- modify_data->itemid, modify_data->changekey, 0);
-
- /* subject */
- value = icalcomponent_get_summary (icalcomp);
- old_value = icalcomponent_get_summary (icalcomp_old);
- if ((value && old_value && g_ascii_strcasecmp (value, old_value)) ||
- (value && old_value == NULL)) {
- convert_vevent_property_to_updatexml (msg, "Subject", value, "item", NULL, NULL);
- } else if (!value && old_value)
- convert_vevent_property_to_updatexml (msg, "Subject", "", "item", NULL, NULL);
-
- prop = icalcomponent_get_first_property (icalcomp, ICAL_CLASS_PROPERTY);
- if (prop) {
- icalproperty_class classify = icalproperty_get_class (prop);
- if (classify == ICAL_CLASS_PUBLIC) {
- convert_vevent_property_to_updatexml (msg, "Sensitivity", "Normal", "item", NULL,
NULL);
- } else if (classify == ICAL_CLASS_PRIVATE) {
- convert_vevent_property_to_updatexml (msg, "Sensitivity", "Private", "item", NULL,
NULL);
- } else if (classify == ICAL_CLASS_CONFIDENTIAL) {
- convert_vevent_property_to_updatexml (msg, "Sensitivity", "Personal", "item", NULL,
NULL);
- }
- }
-
- /*description*/
- value = icalcomponent_get_description (icalcomp);
- old_value = icalcomponent_get_description (icalcomp_old);
- if ((value && old_value && g_ascii_strcasecmp (value, old_value)) ||
- (value && old_value == NULL)) {
- convert_vevent_property_to_updatexml (msg, "Body", value, "item", "BodyType", "Text");
- } else if (!value && old_value)
- convert_vevent_property_to_updatexml (msg, "Body", "", "item", "BodyType", "Text");
-
- /*update alarm items*/
- has_alarms = e_cal_component_has_alarms (modify_data->comp);
- if (has_alarms) {
- alarm = ews_get_alarm (modify_data->comp);
- has_alarms_old = e_cal_component_has_alarms (modify_data->oldcomp);
- if (has_alarms_old)
- alarm_old = ews_get_alarm (modify_data->oldcomp);
- if (!(alarm == alarm_old)) {
- gchar buf[20];
- snprintf (buf, 20, "%d", alarm);
- convert_vevent_property_to_updatexml (msg, "ReminderIsSet", "true", "item", NULL,
NULL);
- convert_vevent_property_to_updatexml (msg, "ReminderMinutesBeforeStart", buf, "item",
NULL, NULL);
- }
- }
- else convert_vevent_property_to_updatexml (msg, "ReminderIsSet", "false", "item", NULL, NULL);
-
- /* Categories */
- convert_component_categories_to_updatexml (modify_data->comp, msg, "CalendarItem");
-
- /*location*/
- value = icalcomponent_get_location (icalcomp);
- old_value = icalcomponent_get_location (icalcomp_old);
- if ((value && old_value && g_ascii_strcasecmp (value, old_value)) ||
- (value && old_value == NULL)) {
- convert_vevent_property_to_updatexml (msg, "Location", value, "calendar", NULL, NULL);
- } else if (!value && old_value)
- convert_vevent_property_to_updatexml (msg, "Location", "", "calendar", NULL, NULL);
-
- /*freebusy*/
- transp = icalcomponent_get_first_property (icalcomp, ICAL_TRANSP_PROPERTY);
- value = icalproperty_get_value_as_string (transp);
- transp = icalcomponent_get_first_property (icalcomp_old, ICAL_TRANSP_PROPERTY);
- old_value = icalproperty_get_value_as_string (transp);
- if (g_strcmp0 (value, old_value)) {
- if (!g_strcmp0 (value, "TRANSPARENT"))
- convert_vevent_property_to_updatexml (msg, "LegacyFreeBusyStatus","Free" ,
"calendar", NULL, NULL);
- else
- convert_vevent_property_to_updatexml (msg, "LegacyFreeBusyStatus","Busy" ,
"calendar", NULL, NULL);
- }
-
- org_email_address = e_ews_collect_organizer (icalcomp);
- if (org_email_address && g_ascii_strcasecmp (org_email_address,
modify_data->cbews->priv->user_email)) {
- e_ews_message_end_item_change (msg);
- return;
- }
- /* Update other properties allowed only for meeting organizers*/
- /*meeting dates*/
- dtstart = icalcomponent_get_dtstart (icalcomp);
- dtend = icalcomponent_get_dtend (icalcomp);
- dtstart_old = icalcomponent_get_dtstart (icalcomp_old);
- dtend_old = icalcomponent_get_dtend (icalcomp_old);
- if (icaltime_compare (dtstart, dtstart_old) != 0) {
- e_ews_message_start_set_item_field (msg, "Start", "calendar","CalendarItem");
- ewscal_set_time (msg, "Start", &dtstart, FALSE);
- e_ews_message_end_set_item_field (msg);
- dt_changed = TRUE;
- }
-
- if (icaltime_compare (dtend, dtend_old) != 0) {
- e_ews_message_start_set_item_field (msg, "End", "calendar", "CalendarItem");
- ewscal_set_time (msg, "End", &dtend, FALSE);
- e_ews_message_end_set_item_field (msg);
- dt_changed = TRUE;
- }
-
- /*Check for All Day Event*/
- if (dt_changed) {
- if (icaltime_is_date (dtstart))
- convert_vevent_property_to_updatexml (msg, "IsAllDayEvent", "true", "calendar", NULL,
NULL);
- else
- convert_vevent_property_to_updatexml (msg, "IsAllDayEvent", "false", "calendar",
NULL, NULL);
- }
-
- /*need to test it*/
- e_ews_collect_attendees (icalcomp, &required, &optional, &resource);
- if (required != NULL) {
- e_ews_message_start_set_item_field (msg, "RequiredAttendees", "calendar", "CalendarItem");
-
- add_attendees_list_to_message (msg, "RequiredAttendees", required);
- g_slist_free (required);
-
- e_ews_message_end_set_item_field (msg);
- }
- if (optional != NULL) {
- e_ews_message_start_set_item_field (msg, "OptionalAttendees", "calendar", "CalendarItem");
-
- add_attendees_list_to_message (msg, "OptionalAttendees", optional);
- g_slist_free (optional);
-
- e_ews_message_end_set_item_field (msg);
- }
- if (resource != NULL) {
- e_ews_message_start_set_item_field (msg, "Resources", "calendar", "CalendarItem");
-
- add_attendees_list_to_message (msg, "Resources", resource);
- g_slist_free (resource);
-
- e_ews_message_end_set_item_field (msg);
- }
-
- /* Recurrence */
- value = NULL; old_value = NULL;
- prop = icalcomponent_get_first_property (icalcomp_old, ICAL_RRULE_PROPERTY);
- if (prop != NULL)
- old_value = icalproperty_get_value_as_string (prop);
- prop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
- if (prop != NULL)
- value = icalproperty_get_value_as_string (prop);
-
- if (prop != NULL && g_strcmp0 (value, old_value)) {
- e_ews_message_start_set_item_field (msg, "Recurrence", "calendar", "CalendarItem");
- ewscal_set_reccurence (msg, prop, &dtstart);
- e_ews_message_end_set_item_field (msg);
- }
-
- /* We have to cast these because libical puts a const pointer into the
- * icaltimetype, but its basic read-only icaltimezone_foo() functions
- * take a non-const pointer! */
- if (e_ews_connection_satisfies_server_version (modify_data->cbews->priv->cnc, E_EWS_EXCHANGE_2010)) {
- const gchar *ical_location;
- const gchar *msdn_location;
- icaltimezone *tzid;
- GSList *msdn_locations = NULL;
- GSList *tzds = NULL;
-
- if (dtstart.zone != NULL) {
- tzid = (icaltimezone *) dtstart.zone;
- ical_location = icaltimezone_get_location (tzid);
- msdn_location = e_cal_backend_ews_tz_util_get_msdn_equivalent (ical_location);
- msdn_locations = g_slist_append (msdn_locations, (gchar *) msdn_location);
- }
-
- if (dtend.zone != NULL) {
- tzid = (icaltimezone *) dtend.zone;
- ical_location = icaltimezone_get_location (tzid);
- msdn_location = e_cal_backend_ews_tz_util_get_msdn_equivalent (ical_location);
- msdn_locations = g_slist_append (msdn_locations, (gchar *) msdn_location);
- }
-
- if (e_ews_connection_get_server_time_zones_sync (
- modify_data->cbews->priv->cnc,
- EWS_PRIORITY_MEDIUM,
- msdn_locations,
- &tzds,
- NULL,
- NULL)) {
- GSList *tmp;
-
- tmp = tzds;
- if (dtstart.zone != NULL) {
- e_ews_message_start_set_item_field (msg, "StartTimeZone", "calendar",
"CalendarItem");
- ewscal_set_timezone (msg, "StartTimeZone", tmp->data);
- e_ews_message_end_set_item_field (msg);
-
- /*
- * Exchange server is smart enough to return the list of
- * ServerTimeZone without repeated elements
- */
- if (tmp->next != NULL)
- tmp = tmp->next;
- }
-
- if (dtend.zone != NULL) {
- e_ews_message_start_set_item_field (msg, "EndTimeZone", "calendar",
"CalendarItem");
- ewscal_set_timezone (msg, "EndTimeZone", tmp->data);
- e_ews_message_end_set_item_field (msg);
- }
- }
-
- g_slist_free (msdn_locations);
- g_slist_free_full (tzds, (GDestroyNotify) e_ews_calendar_time_zone_definition_free);
- } else {
- e_ews_message_start_set_item_field (msg, "MeetingTimeZone", "calendar", "CalendarItem");
- ewscal_set_meeting_timezone (
- msg,
- (icaltimezone *)(dtstart.zone ? dtstart.zone :
modify_data->cbews->priv->default_zone));
- e_ews_message_end_set_item_field (msg);
- }
-
- e_ews_message_end_item_change (msg);
-}
-
-static void
-convert_vtodo_property_to_updatexml (ESoapMessage *msg,
- const gchar *name,
- const gchar *value,
- const gchar *prefix,
- const gchar *attr_name,
- const gchar *attr_value)
-{
- e_ews_message_start_set_item_field (msg, name, prefix, "Task");
- e_ews_message_write_string_parameter_with_attribute (msg, name, NULL, value, attr_name, attr_value);
- e_ews_message_end_set_item_field (msg);
-}
-
-static void
-convert_vtodo_component_to_updatexml (ESoapMessage *msg,
- gpointer user_data)
-{
- EwsModifyData *modify_data = user_data;
- icalcomponent *icalcomp = e_cal_component_get_icalcomponent (modify_data->comp);
- icalproperty *prop;
- icaltimetype dt;
- gint value;
- gchar buffer[16];
-
- e_ews_message_start_item_change (
- msg, E_EWS_ITEMCHANGE_TYPE_ITEM,
- modify_data->itemid, modify_data->changekey, 0);
-
- convert_vtodo_property_to_updatexml (msg, "Subject", icalcomponent_get_summary (icalcomp), "item",
NULL, NULL);
-
- prop = icalcomponent_get_first_property (icalcomp, ICAL_CLASS_PROPERTY);
- if (prop) {
- icalproperty_class classify = icalproperty_get_class (prop);
- if (classify == ICAL_CLASS_PUBLIC) {
- convert_vtodo_property_to_updatexml (msg, "Sensitivity", "Normal", "item", NULL,
NULL);
- } else if (classify == ICAL_CLASS_PRIVATE) {
- convert_vtodo_property_to_updatexml (msg, "Sensitivity", "Private", "item", NULL,
NULL);
- } else if (classify == ICAL_CLASS_CONFIDENTIAL) {
- convert_vtodo_property_to_updatexml (msg, "Sensitivity", "Personal", "item", NULL,
NULL);
- }
- }
-
- convert_vtodo_property_to_updatexml (msg, "Body", icalcomponent_get_description (icalcomp), "item",
"BodyType", "Text");
-
- prop = icalcomponent_get_first_property (icalcomp, ICAL_DUE_PROPERTY);
- if (prop) {
- dt = icalproperty_get_due (prop);
- e_ews_message_start_set_item_field (msg, "DueDate", "task", "Task");
- ewscal_set_time (msg, "DueDate", &dt, TRUE);
- e_ews_message_end_set_item_field (msg);
- } else {
- e_ews_message_add_delete_item_field (msg, "DueDate", "task");
- }
-
- prop = icalcomponent_get_first_property (icalcomp, ICAL_PERCENTCOMPLETE_PROPERTY);
- if (prop) {
- value = icalproperty_get_percentcomplete (prop);
- snprintf (buffer, 16, "%d", value);
- e_ews_message_start_set_item_field (msg, "PercentComplete", "task", "Task");
- e_ews_message_write_string_parameter (msg, "PercentComplete", NULL, buffer);
- e_ews_message_end_set_item_field (msg);
- }
-
- prop = icalcomponent_get_first_property (icalcomp, ICAL_DTSTART_PROPERTY);
- if (prop) {
- dt = icalproperty_get_dtstart (prop);
- e_ews_message_start_set_item_field (msg, "StartDate", "task", "Task");
- ewscal_set_time (msg, "StartDate", &dt, TRUE);
- e_ews_message_end_set_item_field (msg);
- } else {
- e_ews_message_add_delete_item_field (msg, "StartDate", "task");
- }
-
- prop = icalcomponent_get_first_property (icalcomp, ICAL_STATUS_PROPERTY);
- if (prop) {
- switch (icalproperty_get_status (prop)) {
- case ICAL_STATUS_INPROCESS:
- convert_vtodo_property_to_updatexml (msg, "Status", "InProgress", "task", NULL, NULL);
- break;
- case ICAL_STATUS_COMPLETED:
- convert_vtodo_property_to_updatexml (msg, "Status", "Completed", "task", NULL, NULL);
- break;
- case ICAL_STATUS_NONE:
- case ICAL_STATUS_NEEDSACTION:
- convert_vtodo_property_to_updatexml (msg, "Status", "NotStarted", "task", NULL, NULL);
- break;
- default:
- break;
- }
- }
-
- /* Categories */
- convert_component_categories_to_updatexml (modify_data->comp, msg, "Task");
-
- e_ews_message_end_item_change (msg);
-}
-
-static void
-convert_vjournal_property_to_updatexml (ESoapMessage *msg,
- const gchar *name,
- const gchar *value,
- const gchar *prefix,
- const gchar *attr_name,
- const gchar *attr_value)
-{
- e_ews_message_start_set_item_field (msg, name, prefix, "Message");
- e_ews_message_write_string_parameter_with_attribute (msg, name, NULL, value, attr_name, attr_value);
- e_ews_message_end_set_item_field (msg);
-}
-
-static void
-convert_vjournal_component_to_updatexml (ESoapMessage *msg,
- gpointer user_data)
-{
- EwsModifyData *modify_data = user_data;
- icalcomponent *icalcomp = e_cal_component_get_icalcomponent (modify_data->comp);
- icalproperty *prop;
- const gchar *text;
-
- e_ews_message_start_item_change (
- msg, E_EWS_ITEMCHANGE_TYPE_ITEM,
- modify_data->itemid, modify_data->changekey, 0);
-
- convert_vjournal_property_to_updatexml (msg, "ItemClass", "IPM.StickyNote", "item", NULL, NULL);
- convert_vjournal_property_to_updatexml (msg, "Subject", icalcomponent_get_summary (icalcomp), "item",
NULL, NULL);
-
- prop = icalcomponent_get_first_property (icalcomp, ICAL_CLASS_PROPERTY);
- if (prop) {
- icalproperty_class classify = icalproperty_get_class (prop);
- if (classify == ICAL_CLASS_PUBLIC) {
- convert_vjournal_property_to_updatexml (msg, "Sensitivity", "Normal", "item", NULL,
NULL);
- } else if (classify == ICAL_CLASS_PRIVATE) {
- convert_vjournal_property_to_updatexml (msg, "Sensitivity", "Private", "item", NULL,
NULL);
- } else if (classify == ICAL_CLASS_CONFIDENTIAL) {
- convert_vjournal_property_to_updatexml (msg, "Sensitivity", "Personal", "item", NULL,
NULL);
- }
- }
-
- text = icalcomponent_get_description (icalcomp);
- if (!text || !*text)
- text = icalcomponent_get_summary (icalcomp);
-
- convert_vjournal_property_to_updatexml (msg, "Body", text, "item", "BodyType", "Text");
-
- /* Categories */
- convert_component_categories_to_updatexml (modify_data->comp, msg, "Message");
-
- e_ews_message_end_item_change (msg);
-}
-
-static void
-convert_component_to_updatexml (ESoapMessage *msg,
- gpointer user_data)
-{
- EwsModifyData *modify_data = user_data;
- icalcomponent *icalcomp = e_cal_component_get_icalcomponent (modify_data->comp);
-
- switch (icalcomponent_isa (icalcomp)) {
- case ICAL_VEVENT_COMPONENT:
- convert_vevent_component_to_updatexml (msg, user_data);
- break;
- case ICAL_VTODO_COMPONENT:
- convert_vtodo_component_to_updatexml (msg, user_data);
- break;
- case ICAL_VJOURNAL_COMPONENT:
- convert_vjournal_component_to_updatexml (msg, user_data);
- break;
- default:
- break;
- }
+ e_cal_backend_ews_async_data_free (modify_data);
}
static void
@@ -2652,7 +1805,7 @@ e_cal_backend_ews_modify_object (ECalBackend *backend,
const gchar *calobj,
ECalObjModType mod)
{
- EwsModifyData *modify_data;
+ EwsCalendarAsyncData *modify_data;
ECalBackendEws *cbews;
ECalBackendEwsPrivate *priv;
icalcomponent_kind kind;
@@ -2662,7 +1815,7 @@ e_cal_backend_ews_modify_object (ECalBackend *backend,
struct icaltimetype current;
GError *error = NULL;
GSList *original_attachments = NULL, *modified_attachments = NULL, *added_attachments = NULL,
*removed_attachments = NULL, *removed_attachments_ids = NULL, *i;
- EwsAttachmentsData *attach_data;
+ EwsCalendarAsyncData *attach_data;
struct TzidCbData cbd;
e_data_cal_error_if_fail (E_IS_CAL_BACKEND_EWS (backend), InvalidArg);
@@ -2780,16 +1933,15 @@ e_cal_backend_ews_modify_object (ECalBackend *backend,
EwsId *item_id = g_new0 (EwsId, 1);
item_id->id = itemid;
item_id->change_key = changekey;
- attach_data = g_new0 (EwsAttachmentsData, 1);
+ attach_data = g_new0 (EwsCalendarAsyncData, 1);
attach_data->cbews = g_object_ref (cbews);
attach_data->comp = g_object_ref (comp);
- attach_data->cb_type = 2;
- attach_data->oldcomp = g_object_ref (oldcomp);
+ attach_data->cb_type = E_EWS_ATTACHMENT_TYPE_UPDATE;
+ attach_data->extra_comp = g_object_ref (oldcomp);
attach_data->cal = g_object_ref (cal);
attach_data->context = 0;
- attach_data->itemid = itemid;
- attach_data->changekey = changekey;
+ attach_data->item_id = itemid;
e_cal_component_get_uid (oldcomp, &old_uid);
if (old_uid)
@@ -2833,17 +1985,25 @@ e_cal_backend_ews_modify_object (ECalBackend *backend,
g_free (item_id);
} else {
+ EwsCalendarConvertData convert_data;
const gchar *send_meeting_invitations;
const gchar *send_or_save;
- modify_data = g_new0 (EwsModifyData, 1);
+ modify_data = g_new0 (EwsCalendarAsyncData, 1);
modify_data->cbews = g_object_ref (cbews);
modify_data->comp = g_object_ref (comp);
- modify_data->oldcomp = g_object_ref (oldcomp);
+ modify_data->extra_comp = g_object_ref (oldcomp);
modify_data->cal = g_object_ref (cal);
modify_data->context = context;
- modify_data->itemid = itemid;
- modify_data->changekey = changekey;
+ modify_data->item_id = itemid;
+
+ convert_data.connection = cbews->priv->cnc;
+ convert_data.user_email = cbews->priv->user_email;
+ convert_data.comp = comp;
+ convert_data.old_comp = oldcomp;
+ convert_data.item_id = itemid;
+ convert_data.change_key = changekey;
+ convert_data.default_zone = cbews->priv->default_zone;
if (e_cal_component_has_attendees (comp)) {
send_meeting_invitations = "SendToAllAndSaveCopy";
@@ -2860,8 +2020,8 @@ e_cal_backend_ews_modify_object (ECalBackend *backend,
send_or_save,
send_meeting_invitations,
priv->folder_id,
- convert_component_to_updatexml,
- modify_data,
+ e_cal_backend_ews_convert_component_to_updatexml,
+ &convert_data,
cancellable,
ews_cal_modify_object_cb,
modify_data);
@@ -2878,12 +2038,6 @@ exit:
}
}
-typedef struct {
- const gchar *response_type;
- const gchar *item_id;
- const gchar *change_key;
-} EwsAcceptData;
-
static void
e_ews_receive_objects_no_exchange_mail (ECalBackendEws *cbews,
icalcomponent *subcomp,
@@ -2891,12 +2045,12 @@ e_ews_receive_objects_no_exchange_mail (ECalBackendEws *cbews,
GCancellable *cancellable,
GError **error)
{
- EwsConvertData *convert_data;
+ EwsCalendarConvertData convert_data;
EwsFolderId *fid;
- convert_data = g_new0 (EwsConvertData, 1);
- convert_data->cbews = g_object_ref (cbews);
- convert_data->icalcomp = subcomp;
+ convert_data.connection = cbews->priv->cnc;
+ convert_data.icalcomp = subcomp;
+ convert_data.default_zone = cbews->priv->default_zone;
fid = e_ews_folder_id_new (cbews->priv->folder_id, NULL, FALSE);
@@ -2906,8 +2060,8 @@ e_ews_receive_objects_no_exchange_mail (ECalBackendEws *cbews,
"SaveOnly",
"SendToNone",
fid,
- convert_calcomp_to_xml,
- convert_data,
+ e_cal_backend_ews_convert_calcomp_to_xml,
+ &convert_data,
ids,
cancellable,
error);
@@ -2951,49 +2105,155 @@ e_ews_get_current_user_meeting_reponse (icalcomponent *icalcomp,
}
static void
-prepare_accept_item_request (ESoapMessage *msg,
- gpointer user_data)
+ews_cal_do_method_request_publish_reply (ECalBackendEws *cbews,
+ ECalComponent *comp,
+ icalcomponent *subcomp,
+ const gchar *response_type,
+ GCancellable *cancellable,
+ GError **error)
{
- EwsAcceptData *data = user_data;
- const gchar *response_type = data->response_type;
-
- /* FORMAT OF A SAMPLE SOAP MESSAGE:
http://msdn.microsoft.com/en-us/library/aa566464%28v=exchg.140%29.aspx
- * Accept and Decline meeting have same method code (10032)
- * The real status is reflected at Attendee property PARTSTAT
- * need to find current user as attendee and make a decision what to do.
- * Prepare AcceptItem node in the SOAP message */
-
- if (response_type && !g_ascii_strcasecmp (response_type, "ACCEPTED"))
- e_soap_message_start_element (msg, "AcceptItem", NULL, NULL);
- else if (response_type && !g_ascii_strcasecmp (response_type, "DECLINED"))
- e_soap_message_start_element (msg, "DeclineItem", NULL, NULL);
- else
- e_soap_message_start_element (msg, "TentativelyAcceptItem", NULL, NULL);
+ GError *local_error = NULL;
+ gchar *item_id = NULL;
+ gchar *change_key = NULL;
+ gchar *mail_id = NULL;
+ gint pass = 0;
- e_soap_message_start_element (msg, "ReferenceItemId", NULL, NULL);
- e_soap_message_add_attribute (msg, "Id", data->item_id, NULL, NULL);
- e_soap_message_add_attribute (msg, "ChangeKey", data->change_key, NULL, NULL);
- e_soap_message_end_element (msg); // "ReferenceItemId"
+ ews_cal_component_get_calendar_item_accept_id (comp, &item_id, &change_key, &mail_id);
- /* end of "AcceptItem" */
- e_soap_message_end_element (msg);
-}
+ while (pass < 2) {
+ GSList *ids = NULL;
-static void
-prepare_set_free_busy_status (ESoapMessage *msg,
- gpointer user_data)
-{
- EwsAcceptData *data = user_data;
+ /*in case we do not have item id we will create item with mime content only*/
+ if (item_id == NULL) {
+ e_ews_receive_objects_no_exchange_mail (cbews, subcomp, &ids, cancellable,
&local_error);
+ } else {
+ EwsCalendarConvertData convert_data;
+
+ convert_data.response_type = (gchar *) response_type;
+ convert_data.item_id = item_id;
+ convert_data.change_key = change_key;
+
+ e_ews_connection_create_items_sync (
+ cbews->priv->cnc,
+ EWS_PRIORITY_MEDIUM,
+ "SendAndSaveCopy",
+ NULL,
+ NULL,
+ e_cal_backend_ews_prepare_accept_item_request,
+ &convert_data,
+ &ids,
+ cancellable,
+ &local_error);
+ }
+
+ if (pass == 0 && mail_id != NULL && item_id != NULL &&
+ g_error_matches (local_error, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_ITEMNOTFOUND)) {
+ /*
+ * maybe the associated accept calendar item changed
+ * on the server, thus retry with updated values
+ */
+ GSList *ids = NULL, *my_ids = NULL;
+
+ g_clear_error (&local_error);
+
+ my_ids = g_slist_append (my_ids, mail_id);
+
+ if (e_ews_connection_get_items_sync (
+ cbews->priv->cnc,
+ EWS_PRIORITY_MEDIUM,
+ my_ids,
+ "AllProperties",
+ NULL,
+ FALSE,
+ NULL,
+ E_EWS_BODY_TYPE_ANY,
+ &ids,
+ NULL,
+ NULL,
+ cancellable,
+ &local_error) &&
+ ids != NULL &&
+ ids->data != NULL) {
+ EEwsItem *item = ids->data;
+ const EwsId *id = e_ews_item_get_id (item);
+
+ if (id != NULL && g_strcmp0 (id->id, mail_id) == 0) {
+ const EwsId *cal_item_accepted_id;
+
+ cal_item_accepted_id = e_ews_item_get_calendar_item_accept_id (item);
+ if (cal_item_accepted_id != NULL) {
+ g_clear_error (&local_error);
+ pass++;
+
+ g_free (item_id);
+ g_free (change_key);
+
+ item_id = g_strdup (cal_item_accepted_id->id);
+ change_key = g_strdup (cal_item_accepted_id->change_key);
+ }
+ }
+ }
+
+ g_slist_free (my_ids);
+ g_slist_free_full (ids, g_object_unref);
+
+ if (pass == 0)
+ break;
+ } else {
+ break;
+ }
+ }
+
+ if (error == NULL) {
+ icalproperty *transp;
+
+ transp = icalcomponent_get_first_property (subcomp, ICAL_TRANSP_PROPERTY);
+
+ if (g_strcmp0 (icalproperty_get_value_as_string (transp), "TRANSPARENT") == 0 &&
+ g_strcmp0 (response_type, "ACCEPTED") == 0) {
+ EwsCalendarConvertData convert_data;
+ GSList *l, *ids = NULL;
+
+ /*
+ * user can accept meeting but mark it as free in it's calendar
+ * the following code is updating the exchange meeting status to free
+ */
+ for (l = ids; l != NULL; l = g_slist_next (l)) {
+ EEwsItem *item = l->data;
+
+ if (item != NULL) {
+ const EwsId *id = e_ews_item_get_id (item);
- e_ews_message_start_item_change (msg, E_EWS_ITEMCHANGE_TYPE_ITEM, data->item_id, data->change_key, 0);
+ convert_data.item_id = id->id;
+ convert_data.change_key = id->change_key;
+ break;
+ }
+ }
- e_ews_message_start_set_item_field (msg, "LegacyFreeBusyStatus", "calendar", "CalendarItem");
+ e_ews_connection_update_items_sync (
+ cbews->priv->cnc,
+ EWS_PRIORITY_MEDIUM,
+ "AlwaysOverwrite",
+ NULL,
+ "SendToNone",
+ NULL,
+ e_cal_backend_ews_prepare_set_free_busy_status,
+ &convert_data,
+ &ids,
+ cancellable,
+ &local_error);
+ }
+ }
- e_ews_message_write_string_parameter (msg, "LegacyFreeBusyStatus", NULL, "Free");
+ if (error != NULL)
+ g_propagate_error (error, local_error);
- e_ews_message_end_set_item_field (msg);
+ g_free (item_id);
+ g_free (change_key);
+ g_free (mail_id);
- e_ews_message_end_item_change (msg);
+ /*We have to run sync before any other operations */
+ ews_start_sync (cbews);
}
static void
@@ -3009,7 +2269,6 @@ e_cal_backend_ews_receive_objects (ECalBackend *backend,
icalcomponent *icalcomp, *subcomp;
GError *error = NULL;
icalproperty_method method;
- EwsAcceptData *accept_data;
cbews = E_CAL_BACKEND_EWS (backend);
priv = cbews->priv;
@@ -3046,115 +2305,26 @@ e_cal_backend_ews_receive_objects (ECalBackend *backend,
while (subcomp) {
ECalComponent *comp = e_cal_component_new ();
const gchar *response_type;
- gchar *item_id = NULL, *change_key = NULL, *mail_id = NULL;
- GSList *ids = NULL, *l;
- icalproperty *transp, *summary;
- gchar **split_subject;
- gint pass = 0;
/* duplicate the ical component */
e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (subcomp));
/*getting a data for meeting request response*/
- response_type = e_ews_get_current_user_meeting_reponse (e_cal_component_get_icalcomponent
(comp), priv->user_email);
- ews_cal_component_get_calendar_item_accept_id (comp, &item_id, &change_key, &mail_id);
+ response_type = e_ews_get_current_user_meeting_reponse (
+ e_cal_component_get_icalcomponent (comp),
+ priv->user_email);
switch (method) {
case ICAL_METHOD_REQUEST:
case ICAL_METHOD_PUBLISH:
case ICAL_METHOD_REPLY:
- accept_data = g_new0 (EwsAcceptData, 1);
- accept_data->response_type = response_type;
- accept_data->item_id = item_id;
- accept_data->change_key = change_key;
-
- while (pass < 2) {
- /*in case we do not have item id we will create item with mime
content only*/
- if (item_id == NULL)
- e_ews_receive_objects_no_exchange_mail (cbews, subcomp, &ids,
cancellable, &error);
- else
- e_ews_connection_create_items_sync (
- priv->cnc, EWS_PRIORITY_MEDIUM,
- "SendAndSaveCopy",
- NULL, NULL,
- prepare_accept_item_request,
- accept_data,
- &ids, cancellable, &error);
- if (pass == 0 && mail_id && item_id &&
- g_error_matches (error, EWS_CONNECTION_ERROR,
EWS_CONNECTION_ERROR_ITEMNOTFOUND)) {
- /* maybe the associated accept calendar item changed
- on the server, thus retry with updated values */
- GSList *my_ids;
-
- my_ids = g_slist_append (NULL, mail_id);
- ids = NULL;
- if (e_ews_connection_get_items_sync (priv->cnc,
EWS_PRIORITY_MEDIUM, my_ids,
- "AllProperties", NULL, FALSE, NULL,
E_EWS_BODY_TYPE_ANY, &ids, NULL, NULL,
- cancellable, NULL)
- && ids && ids->data) {
- EEwsItem *item = ids->data;
- if (e_ews_item_get_id (item) &&
- g_strcmp0 (e_ews_item_get_id (item)->id, mail_id)
== 0) {
- const EwsId *calendar_item_accept_id =
e_ews_item_get_calendar_item_accept_id (item);
-
- if (calendar_item_accept_id) {
- g_clear_error (&error);
- pass++;
-
- g_free (item_id);
- g_free (change_key);
- item_id = g_strdup
(calendar_item_accept_id->id);
- change_key = g_strdup
(calendar_item_accept_id->change_key);
-
- accept_data->item_id = item_id;
- accept_data->change_key = change_key;
- }
- }
- }
-
- g_slist_free (my_ids);
- g_slist_free_full (ids, g_object_unref);
- ids = NULL;
-
- if (pass == 0)
- break;
- } else {
- break;
- }
- }
- if (!error) {
- transp = icalcomponent_get_first_property (subcomp,
ICAL_TRANSP_PROPERTY);
- if (!g_strcmp0 (icalproperty_get_value_as_string (transp),
"TRANSPARENT") &&
- !g_strcmp0 (response_type, "ACCEPTED")) {
- /*user can accept meeting but mark it as free in it's calendar
- the following code is updating the exchange meeting status
to free */
- for (l = ids; l != NULL; l = g_slist_next (l)) {
- EEwsItem *item = (EEwsItem *) l->data;
- if (item) {
- accept_data->item_id = e_ews_item_get_id
(item)->id;
- accept_data->change_key = e_ews_item_get_id
(item)->change_key;
- break;
- }
- }
- e_ews_connection_update_items_sync (
- priv->cnc,
- EWS_PRIORITY_MEDIUM,
- "AlwaysOverwrite",
- NULL, "SendToNone",
- NULL,
- prepare_set_free_busy_status,
- accept_data,
- &ids,
- cancellable,
- &error);
- }
- }
- g_free (item_id);
- g_free (change_key);
- g_free (mail_id);
- g_free (accept_data);
- /*We have to run sync before any other operations */
- ews_start_sync (cbews);
+ ews_cal_do_method_request_publish_reply (
+ cbews,
+ comp,
+ subcomp,
+ response_type,
+ cancellable,
+ &error);
break;
case ICAL_METHOD_CANCEL: {
const gchar *uid = NULL;
@@ -3170,13 +2340,21 @@ e_cal_backend_ews_receive_objects (ECalBackend *backend,
break;
}
case ICAL_METHOD_COUNTER:
- /*this is a new time proposal mail from one of the attendees
+ /*
+ * this is a new time proposal mail from one of the attendees
* if we decline the proposal, nothing have to be done
- * if we accept it we will call to modify_object */
- if (!g_strcmp0 (response_type, "ACCEPTED")) {
- /*we have to edit the meeting subject to remove exchange header*/
+ * if we accept it we will call to modify_object
+ */
+ if (g_strcmp0 (response_type, "ACCEPTED") == 0) {
+ gchar **split_subject;
+ icalproperty *summary;
+
+ /*
+ * we have to edit the meeting subject to remove exchange header
+ */
summary = icalcomponent_get_first_property (subcomp,
ICAL_SUMMARY_PROPERTY);
- split_subject = g_strsplit (icalproperty_get_value_as_string
(summary), ":", -1);
+ split_subject =
+ g_strsplit (icalproperty_get_value_as_string (summary), ":",
-1);
icalproperty_set_value_from_string (summary, split_subject[1] , "NO");
g_strfreev (split_subject);
@@ -3186,6 +2364,7 @@ e_cal_backend_ews_receive_objects (ECalBackend *backend,
default:
break;
}
+
g_object_unref (comp);
subcomp = icalcomponent_get_next_component (icalcomp, kind);
}
@@ -3219,34 +2398,6 @@ e_cal_get_meeting_cancellation_comment (ECalComponent *comp)
return NULL;
}
-static icaltimezone *
-e_cal_get_timezone_from_ical_component (ECalBackend *backend,
- icalcomponent *comp)
-{
- ETimezoneCache *timezone_cache;
- icalproperty *prop;
- icalparameter *param;
-
- timezone_cache = E_TIMEZONE_CACHE (backend);
-
- prop = icalcomponent_get_first_property (
- comp, ICAL_DTSTART_PROPERTY);
- param = icalproperty_get_first_parameter (
- prop, ICAL_TZID_PARAMETER);
-
- if (param != NULL) {
- const gchar *tzid;
-
- tzid = icalparameter_get_tzid (param);
-
- return e_timezone_cache_get_timezone (timezone_cache, tzid);
- }
-
- g_warning ("EEE Cant figure the relevant timezone of the component\n");
-
- return NULL;
-}
-
static void
ewscal_send_cancellation_email (ECalBackend *backend,
EEwsConnection *cnc,
@@ -3277,7 +2428,8 @@ ewscal_send_cancellation_email (ECalBackend *backend,
prop = icalcomponent_get_first_property (vevent, ICAL_METHOD_PROPERTY);
if (prop != NULL) icalcomponent_remove_property (vevent, prop);
dt = icalcomponent_get_dtstart (vevent);
- icaltz = (icaltimezone *)(dt.zone ? dt.zone : e_cal_get_timezone_from_ical_component (backend,
vevent));
+ icaltz = (icaltimezone *)
+ (dt.zone ? dt.zone : e_cal_backend_ews_get_timezone_from_ical_component (backend, vevent));
vtz = icaltimezone_get_component (icaltz);
icalcomponent_add_component (vcal, icalcomponent_new_clone (vtz));
icalcomponent_add_component (vcal, vevent);
@@ -4370,65 +3522,13 @@ exit:
e_data_cal_respond_refresh (cal, context, error);
}
-typedef struct {
- ECalBackendEws *cbews;
- EDataCal *cal;
- guint32 context;
- GSList *users;
- time_t start;
- time_t end;
-} EwsFreeBusyData;
-
-static void
-prepare_free_busy_request (ESoapMessage *msg,
- gpointer user_data)
-{
- EwsFreeBusyData *free_busy_data = user_data;
- GSList *addr;
- icaltimetype t_start, t_end;
- icaltimezone *utc_zone = icaltimezone_get_utc_timezone ();
-
- ewscal_set_availability_timezone (msg, utc_zone);
-
- e_soap_message_start_element (msg, "MailboxDataArray", "messages", NULL);
-
- for (addr = free_busy_data->users; addr; addr = addr->next) {
- e_soap_message_start_element (msg, "MailboxData", NULL, NULL);
-
- e_soap_message_start_element (msg, "Email", NULL, NULL);
- e_ews_message_write_string_parameter (msg, "Address", NULL, addr->data);
- e_soap_message_end_element (msg); /* "Email" */
-
- e_ews_message_write_string_parameter (msg, "AttendeeType", NULL, "Required");
- e_ews_message_write_string_parameter (msg, "ExcludeConflicts", NULL, "false");
-
- e_soap_message_end_element (msg); /* "MailboxData" */
- }
-
- e_soap_message_end_element (msg); /* "MailboxDataArray" */
-
- e_soap_message_start_element (msg, "FreeBusyViewOptions", NULL, NULL);
-
- e_soap_message_start_element (msg, "TimeWindow", NULL, NULL);
- t_start = icaltime_from_timet_with_zone (free_busy_data->start, 0, utc_zone);
- t_end = icaltime_from_timet_with_zone (free_busy_data->end, 0, utc_zone);
- ewscal_set_time (msg, "StartTime", &t_start, FALSE);
- ewscal_set_time (msg, "EndTime", &t_end, FALSE);
- e_soap_message_end_element (msg); /* "TimeWindow" */
-
- e_ews_message_write_string_parameter (msg, "MergedFreeBusyIntervalInMinutes", NULL, "60");
- e_ews_message_write_string_parameter (msg, "RequestedView", NULL, "DetailedMerged");
-
- e_soap_message_end_element (msg); /* "FreeBusyViewOptions" */
-}
-
static void
ews_cal_get_free_busy_cb (GObject *obj,
GAsyncResult *res,
gpointer user_data)
{
EEwsConnection *cnc = (EEwsConnection *) obj;
- EwsFreeBusyData *free_busy_data = user_data;
+ EwsCalendarAsyncData *free_busy_data = user_data;
GSList *free_busy_sl = NULL, *i;
GSList *free_busy = NULL, *j;
GError *error = NULL;
@@ -4451,12 +3551,8 @@ done:
convert_error_to_edc_error (&error);
e_data_cal_respond_get_free_busy (free_busy_data->cal, free_busy_data->context, error);
- /* FIXME free free_busy_sl ? */
g_slist_free_full (free_busy, g_free);
- g_slist_free_full (free_busy_data->users, g_free);
- g_object_unref (free_busy_data->cal);
- g_object_unref (free_busy_data->cbews);
- g_free (free_busy_data);
+ e_cal_backend_ews_async_data_free (free_busy_data);
}
static void
@@ -4471,7 +3567,8 @@ e_cal_backend_ews_get_free_busy (ECalBackend *backend,
ECalBackendEws *cbews = E_CAL_BACKEND_EWS (backend);
ECalBackendEwsPrivate *priv = cbews->priv;
GError *error = NULL;
- EwsFreeBusyData *free_busy_data;
+ EwsCalendarAsyncData *free_busy_data;
+ EwsCalendarConvertData convert_data;
GSList *users_copy = NULL;
/* make sure we're not offline */
@@ -4495,19 +3592,21 @@ e_cal_backend_ews_get_free_busy (ECalBackend *backend,
for (; users; users = users->next)
users_copy = g_slist_append (users_copy, g_strdup (users->data));
- free_busy_data = g_new0 (EwsFreeBusyData, 1);
+ free_busy_data = g_new0 (EwsCalendarAsyncData, 1);
free_busy_data->cbews = g_object_ref (cbews);
free_busy_data->cal = g_object_ref (cal);
free_busy_data->context = context;
free_busy_data->users = users_copy;
- free_busy_data->start = start;
- free_busy_data->end = end;
+
+ convert_data.users = users_copy;
+ convert_data.start = start;
+ convert_data.end = end;
e_ews_connection_get_free_busy (
priv->cnc,
EWS_PRIORITY_MEDIUM,
- prepare_free_busy_request,
- free_busy_data,
+ e_cal_backend_ews_prepare_free_busy_request,
+ &convert_data,
cancellable,
ews_cal_get_free_busy_cb,
free_busy_data);
diff --git a/src/calendar/e-cal-backend-ews.h b/src/calendar/e-cal-backend-ews.h
index 0959405..48480f3 100644
--- a/src/calendar/e-cal-backend-ews.h
+++ b/src/calendar/e-cal-backend-ews.h
@@ -51,6 +51,15 @@ struct _ECalBackendEwsClass {
GType e_cal_backend_ews_get_type (void);
+const EEwsConnection *
+ e_cal_backend_ews_get_connection (ECalBackendEws *cbews);
+
+const icaltimezone *
+ e_cal_backend_ews_get_default_zone (ECalBackendEws *cbews);
+
+const gchar *
+ e_cal_backend_ews_get_user_email (ECalBackendEws *cbews);
+
G_END_DECLS
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]