static char * scalix_appointment_to_string (ScalixObject * object) { ScalixAppointment *app; char *str; app = SCALIX_APPOINTMENT (object); e_cal_component_commit_sequence (E_CAL_COMPONENT (app)); str = e_cal_component_get_as_string (E_CAL_COMPONENT (app)); return str; }
static gboolean deserialize (ScalixObject * object, const char *string) { ScalixAppointmentPrivate *priv; icalcomponent *icomp, *subcomp; icalcomponent_kind kind; icaltimezone *zone; priv = SCALIX_APPOINTMENT_GET_PRIVATE (SCALIX_APPOINTMENT (object)); icomp = icalparser_parse_string (string); if (icalcomponent_isa (icomp) != ICAL_VCALENDAR_COMPONENT) { g_warning ("No VCALENAR while deserializing! (%s)\n", string); icalcomponent_free (icomp); return FALSE; } /* Grab the timezone if any */ subcomp = icalcomponent_get_first_component (icomp, ICAL_VTIMEZONE_COMPONENT); if (subcomp != NULL) { zone = icaltimezone_new (); icalcomponent_remove_component (icomp, subcomp); if (icaltimezone_set_component (zone, subcomp)) priv->timezone = zone; } kind = ICAL_VEVENT_COMPONENT; /* Grab the main VEVENT */ subcomp = icalcomponent_get_first_component (icomp, kind); if (subcomp == NULL) { icalcomponent_free (icomp); return FALSE; } icalcomponent_remove_component (icomp, subcomp); e_cal_component_set_icalcomponent (E_CAL_COMPONENT (object), subcomp); e_cal_component_commit_sequence (E_CAL_COMPONENT (object)); priv->exceptions = NULL; while ((subcomp = icalcomponent_get_next_component (icomp, kind))) { icalcomponent_remove_component (icomp, subcomp); priv->exceptions = g_slist_prepend (priv->exceptions, subcomp); } icalcomponent_free (icomp); return TRUE; }
void scalix_appointment_set (ScalixAppointment * comp, const char *key, const char *value) { icalcomponent *icomp; icalproperty *icalprop; e_cal_component_commit_sequence (E_CAL_COMPONENT (comp)); icomp = e_cal_component_get_icalcomponent (E_CAL_COMPONENT (comp)); icalprop = icalproperty_new_x (value); icalproperty_set_x_name (icalprop, key); icalcomponent_add_property (icomp, icalprop); }
static gchar * test_get_free_busy (ECal *client) { /* TODO uses NULL for users and currently specific to file backend. */ GList *l, *freebusy = NULL; GError *error = NULL; icaltimezone *utc; time_t start, end; utc = icaltimezone_get_utc_timezone (); start = time_from_isodate ("20040212T000000Z"); end = time_add_day_with_zone (start, 2, utc); if (!e_cal_get_free_busy (client, NULL, start, end, &freebusy, &error)) { cl_printf (client, "Test free/busy : Could not retrieve free busy information : %s\n", error->message); return error->message; } if (freebusy) { cl_printf (client, "Printing free busy information\n"); for (l = freebusy; l; l = l->next) { gchar *comp_string; ECalComponent *comp = E_CAL_COMPONENT (l->data); comp_string = e_cal_component_get_as_string (comp); cl_printf (client, "%s\n\n", comp_string); g_object_unref (comp); g_free (comp_string); } } else { cl_printf (client, "free_busy was returned but NULL"); } return NULL; }
ScalixAppointment * scalix_appointment_new (const char *calobj) { ScalixAppointment *comp; icalcomponent *icalcomp = NULL; ECalComponent *ecomp; if (calobj != NULL) { icalcomp = icalparser_parse_string (calobj); if (icalcomp == NULL) { return NULL; } } comp = g_object_new (SCALIX_TYPE_APPOINTMENT, NULL); ecomp = E_CAL_COMPONENT (comp); if (icalcomp != NULL) { e_cal_component_set_icalcomponent (ecomp, icalcomp); } return comp; }
void scalix_appointment_unset (ScalixAppointment * comp, const char *key) { icalcomponent *icomp; icalproperty *icalprop; const char *x_val; GSList *list, *iter; list = NULL; icomp = e_cal_component_get_icalcomponent (E_CAL_COMPONENT (comp)); icalprop = icalcomponent_get_first_property (icomp, ICAL_X_PROPERTY); while (icalprop) { const char *x_name; x_name = icalproperty_get_x_name (icalprop); x_val = icalproperty_get_x (icalprop); if (!strcmp (x_name, key)) { list = g_slist_prepend (list, icalprop); } icalprop = icalcomponent_get_next_property (icomp, ICAL_X_PROPERTY); } for (iter = list; iter; iter = iter->next) { icalprop = iter->data; icalcomponent_remove_property (icomp, icalprop); icalproperty_free (icalprop); } return; }
/** * e_cal_util_generate_alarms_for_list: * @comps: (element-type ECalComponent): List of #ECalComponent<!-- -->s * @start: Start time * @end: End time * @omit: Alarm types to omit * @comp_alarms: (out) (transfer full) (element-type ECalComponentAlarms): List * to be returned * @resolve_tzid: (closure user_data) (scope call): Callback for resolving * timezones * @user_data: (closure): Data to be passed to the resolve_tzid callback * @default_timezone: The timezone used to resolve DATE and floating DATE-TIME * values. * * Iterates through all the components in the @comps list and generates alarm * instances for them; putting them in the @comp_alarms list. * * Returns: the number of elements it added to the list */ gint e_cal_util_generate_alarms_for_list (GList *comps, time_t start, time_t end, ECalComponentAlarmAction *omit, GSList **comp_alarms, ECalRecurResolveTimezoneFn resolve_tzid, gpointer user_data, icaltimezone *default_timezone) { GList *l; gint n; n = 0; for (l = comps; l; l = l->next) { ECalComponent *comp; ECalComponentAlarms *alarms; comp = E_CAL_COMPONENT (l->data); alarms = e_cal_util_generate_alarms_for_comp ( comp, start, end, omit, resolve_tzid, user_data, default_timezone); if (alarms) { *comp_alarms = g_slist_prepend (*comp_alarms, alarms); n++; } } return n; }
gboolean scalix_appointment_get (ScalixAppointment * comp, const char *key, char **value) { icalcomponent *icomp; icalproperty *icalprop; const char *x_val; icomp = e_cal_component_get_icalcomponent (E_CAL_COMPONENT (comp)); icalprop = icalcomponent_get_first_property (icomp, ICAL_X_PROPERTY); while (icalprop) { const char *x_name; x_name = icalproperty_get_x_name (icalprop); x_val = icalproperty_get_x (icalprop); if (!strcmp (x_name, key)) { break; } icalprop = icalcomponent_get_next_property (icomp, ICAL_X_PROPERTY); } if (icalprop) { *value = g_strdup (x_val); return TRUE; } *value = NULL; return FALSE; }
static ScalixObject * iclone (ScalixObject * object) { char *str; ScalixObject *cloned; g_return_val_if_fail (object != NULL, NULL); e_cal_component_commit_sequence (E_CAL_COMPONENT (object)); str = e_cal_component_get_as_string (E_CAL_COMPONENT (object)); g_assert (str != NULL); cloned = SCALIX_OBJECT (scalix_appointment_new (str)); g_free (str); return cloned; }
static void scalix_appointment_init (ScalixAppointment * comp) { ECalComponent *ecomp; ScalixAppointmentPrivate *priv; priv = SCALIX_APPOINTMENT_GET_PRIVATE (comp); ecomp = E_CAL_COMPONENT (comp); e_cal_component_set_new_vtype (ecomp, E_CAL_COMPONENT_EVENT); priv->exceptions = NULL; }
/* Get_objects_in_range handler for the file backend */ static void e_cal_backend_http_get_object_list (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *sexp, GSList **objects, GError **perror) { ECalBackendHttp *cbhttp; ECalBackendHttpPrivate *priv; GSList *components, *l; ECalBackendSExp *cbsexp; ETimezoneCache *timezone_cache; time_t occur_start = -1, occur_end = -1; gboolean prunning_by_time; cbhttp = E_CAL_BACKEND_HTTP (backend); priv = cbhttp->priv; timezone_cache = E_TIMEZONE_CACHE (backend); if (!priv->store) { g_propagate_error (perror, EDC_ERROR (NoSuchCal)); return; } /* process all components in the cache */ cbsexp = e_cal_backend_sexp_new (sexp); *objects = NULL; prunning_by_time = e_cal_backend_sexp_evaluate_occur_times ( cbsexp, &occur_start, &occur_end); components = prunning_by_time ? e_cal_backend_store_get_components_occuring_in_range (priv->store, occur_start, occur_end) : e_cal_backend_store_get_components (priv->store); for (l = components; l != NULL; l = g_slist_next (l)) { if (e_cal_backend_sexp_match_comp (cbsexp, E_CAL_COMPONENT (l->data), timezone_cache)) { *objects = g_slist_append (*objects, e_cal_component_get_as_string (l->data)); } } g_slist_foreach (components, (GFunc) g_object_unref, NULL); g_slist_free (components); g_object_unref (cbsexp); }
static gboolean set_ical_from_mime_part (CamelMimePart * part, ScalixObject * object) { CamelDataWrapper *content; CamelStream *stream; GByteArray *data; icalcomponent *icomp = NULL; icalcomponent *subcomp = NULL; ScalixAppointmentPrivate *priv; priv = SCALIX_APPOINTMENT_GET_PRIVATE (SCALIX_APPOINTMENT (object)); content = camel_medium_get_content_object (CAMEL_MEDIUM (part)); data = g_byte_array_new (); stream = camel_stream_mem_new_with_byte_array (data); camel_data_wrapper_decode_to_stream (content, stream); if (data == NULL || data->data == NULL) { g_print ("Found corrupt ical data\n"); return FALSE; } icomp = icalparser_parse_string ((const char *) data->data); if (icalcomponent_isa (icomp) != ICAL_VCALENDAR_COMPONENT) { icalcomponent_free (icomp); return FALSE; } /* Grab the timezone if any */ subcomp = icalcomponent_get_first_component (icomp, ICAL_VTIMEZONE_COMPONENT); if (subcomp != NULL) { icaltimezone *zone; zone = icaltimezone_new (); icaltimezone_set_component (zone, subcomp); priv->timezone = zone; } /* Grab the main VEVENT */ subcomp = icalcomponent_get_first_component (icomp, ICAL_VEVENT_COMPONENT); e_cal_component_set_icalcomponent (E_CAL_COMPONENT (object), subcomp); return TRUE; }
static char * serialize (ScalixObject * object) { ScalixAppointmentPrivate *priv; icalcomponent *icomp, *toplevel_comp; ECalComponent *comp; GSList *iter; char *result = NULL; priv = SCALIX_APPOINTMENT_GET_PRIVATE (SCALIX_APPOINTMENT (object)); scalix_appointment_unset (SCALIX_APPOINTMENT (object), "X-SCALIX-DESCRIPTION-CHANGED"); comp = E_CAL_COMPONENT (object); e_cal_component_commit_sequence (comp); icomp = e_cal_component_get_icalcomponent (comp); if (icomp) { toplevel_comp = e_cal_util_new_top_level (); /* add timezone if one exists */ if (priv->timezone) { icalcomponent_add_component (toplevel_comp, icalcomponent_new_clone (icaltimezone_get_component (priv->timezone))); } /* add the main vevent */ icalcomponent_add_component (toplevel_comp, icalcomponent_new_clone (icomp)); /* add exceptions if they exist */ for (iter = priv->exceptions; iter; iter = iter->next) { icalcomponent_add_component (toplevel_comp, icalcomponent_new_clone ((icalcomponent*) iter->data)); } result = icalcomponent_as_ical_string (toplevel_comp); if (result != NULL) { result = g_strdup (result); } icalcomponent_free (toplevel_comp); } return result; }
gint main (gint argc, gchar **argv) { ECal *ecal; GList *l, *objects; g_type_init (); if (argc < 3) { printf ("usage: test-search <uid> <query>\n"); exit (0); } /* FIXME We don't build ECals from URIs anymore. */ /* ecal = e_cal_new_from_uri (argv[1], E_CAL_SOURCE_TYPE_EVENT); */ ecal = NULL; if (!e_cal_open (ecal, TRUE, NULL)) { printf ("failed to open calendar\n"); exit (0); } if (!e_cal_get_object_list_as_comp (ecal, argv[2], &objects, NULL)) { printf ("failed to get objects\n"); exit (0); } printf ("Received %d objects\n", g_list_length (objects)); for (l = objects; l; l = l->next) { ECalComponent *comp = E_CAL_COMPONENT (l->data); gchar *str; str = e_cal_component_get_as_string (comp); printf ("%s\n", str); g_free (str); g_object_unref (comp); } g_list_free (objects); g_object_unref (ecal); return 0; }
static void scalix_appointment_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { ScalixAppointment *app; char *str; const char *uid; ScalixAppointmentPrivate *priv; priv = SCALIX_APPOINTMENT_GET_PRIVATE (SCALIX_APPOINTMENT (object)); app = SCALIX_APPOINTMENT (object); switch (prop_id) { case PROP_ICAL: str = scalix_appointment_to_string (SCALIX_OBJECT (object)); g_value_take_string (value, str); break; case PROP_TIMEZONE: g_value_set_pointer (value, priv->timezone); break; case PROP_EXCEPTIONS: g_value_set_pointer (value, priv->exceptions); break; case PROP_UID: e_cal_component_get_uid (E_CAL_COMPONENT (app), &uid); g_value_set_string (value, uid); break; case PROP_IPM_TYPE: g_value_set_int (value, IPM_APPOINTMENT); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } }
static gboolean scalix_appointment_from_string (ScalixObject * object, const char *string) { icalcomponent *icomp, *subcomp; icomp = icalparser_parse_string (string); if (icalcomponent_isa (icomp) == ICAL_VCALENDAR_COMPONENT) { subcomp = icalcomponent_get_first_component (icomp, ICAL_VEVENT_COMPONENT); icalcomponent_remove_component (icomp, subcomp); icalcomponent_free (icomp); icomp = subcomp; } e_cal_component_set_icalcomponent (E_CAL_COMPONENT (object), icomp); return TRUE; }
/** Wrapper for e_cal_backend_cache_get_components_by_uid(). * * Get master components and all detached instances for given UID. * Components/detached instances with cache state * E_CAL_COMPONENT_CACHE_STATE_REMOVED will be omitted. * * @param cb 3E calendar backend. * @param cache Calendar backend cache object. * @param uid UID of the calendar components. * * @return List of matching ECalComponent objects. */ GSList *e_cal_backend_3e_cache_get_components_by_uid(ECalBackend3e *cb, ECalBackendCache *cache, const char *uid) { GSList *iter, *iter_next; GSList *list; g_static_rw_lock_reader_lock(&cb->priv->cache_lock); list = e_cal_backend_cache_get_components_by_uid(cache, uid); g_static_rw_lock_reader_unlock(&cb->priv->cache_lock); for (iter = list; iter; iter = iter_next) { ECalComponent *comp = E_CAL_COMPONENT(iter->data); iter_next = iter->next; if (e_cal_component_get_cache_state(comp) == E_CAL_COMPONENT_CACHE_STATE_REMOVED) { list = g_slist_remove_link(list, iter); g_object_unref(comp); } } return list; }
/** Sync cache changes to the server and unmark them. * * @param cb 3E calendar backend. * * @return TRUE on success. * * @todo Conflict resolution. */ gboolean e_cal_backend_3e_sync_cache_to_server(ECalBackend3e *cb) { GError *local_err = NULL; GList *components, *iter; if (!e_cal_backend_3e_open_connection(cb, &local_err)) { g_warning("Sync failed. Can't open connection to the 3e server. (%s)", local_err ? local_err->message : "Unknown error"); g_clear_error(&local_err); return FALSE; } sync_timezones_to_server(cb); g_static_rw_lock_reader_lock(&cb->priv->cache_lock); components = e_cal_backend_cache_get_components(cb->priv->cache); g_static_rw_lock_reader_unlock(&cb->priv->cache_lock); for (iter = components; iter && !e_cal_backend_3e_sync_should_stop(cb); iter = iter->next) { ECalComponent *comp = E_CAL_COMPONENT(iter->data); ECalComponent *remote_comp; ECalComponentId *id = e_cal_component_get_id(comp); ECalComponentCacheState state = e_cal_component_get_cache_state(comp); /* remove client properties before sending component to the server */ e_cal_component_set_x_property(comp, "X-EVOLUTION-STATUS", NULL); e_cal_component_set_cache_state(comp, E_CAL_COMPONENT_CACHE_STATE_NONE); e_cal_component_set_x_property(comp, "X-3E-DELETED", NULL); remote_comp = e_cal_component_clone(comp); gboolean attachments_converted = e_cal_backend_3e_convert_attachment_uris_to_remote(cb, remote_comp); char *remote_object = e_cal_component_get_as_string(remote_comp); char *object = e_cal_component_get_as_string(comp); if (!attachments_converted) { goto next; } if (state == E_CAL_COMPONENT_CACHE_STATE_CREATED || state == E_CAL_COMPONENT_CACHE_STATE_MODIFIED) { if (!e_cal_backend_3e_upload_attachments(cb, remote_comp, &local_err)) { e_cal_backend_notify_gerror_error(E_CAL_BACKEND(cb), "3e attachemnts sync failure", local_err); g_clear_error(&local_err); goto next; } } switch (state) { case E_CAL_COMPONENT_CACHE_STATE_CREATED: { ESClient_addObject(cb->priv->conn, cb->priv->calspec, remote_object, &local_err); if (local_err) { e_cal_backend_notify_gerror_error(E_CAL_BACKEND(cb), "3e sync failure", local_err); g_clear_error(&local_err); break; } char *new_object = e_cal_component_get_as_string(comp); e_cal_backend_notify_object_modified(E_CAL_BACKEND(cb), object, new_object); g_free(new_object); g_static_rw_lock_writer_lock(&cb->priv->cache_lock); e_cal_backend_cache_put_component(cb->priv->cache, comp); g_static_rw_lock_writer_unlock(&cb->priv->cache_lock); break; } case E_CAL_COMPONENT_CACHE_STATE_MODIFIED: { ESClient_updateObject(cb->priv->conn, cb->priv->calspec, remote_object, &local_err); if (local_err) { e_cal_backend_notify_gerror_error(E_CAL_BACKEND(cb), "3e sync failure", local_err); g_clear_error(&local_err); break; } char *new_object = e_cal_component_get_as_string(comp); e_cal_backend_notify_object_modified(E_CAL_BACKEND(cb), object, new_object); g_free(new_object); g_static_rw_lock_writer_lock(&cb->priv->cache_lock); e_cal_backend_cache_put_component(cb->priv->cache, comp); g_static_rw_lock_writer_unlock(&cb->priv->cache_lock); break; } case E_CAL_COMPONENT_CACHE_STATE_REMOVED: { char *oid = id->rid ? g_strdup_printf("%s@%s", id->uid, id->rid) : g_strdup(id->uid); ESClient_deleteObject(cb->priv->conn, cb->priv->calspec, oid, &local_err); g_free(oid); if (local_err) { // ignore the error if component doesn't exist anymore if (local_err->code == ES_XMLRPC_ERROR_UNKNOWN_COMPONENT) { g_clear_error(&local_err); local_err = NULL; } else { e_cal_backend_notify_gerror_error(E_CAL_BACKEND(cb), "3e sync failure", local_err); g_clear_error(&local_err); break; } } g_static_rw_lock_writer_lock(&cb->priv->cache_lock); e_cal_backend_cache_remove_component(cb->priv->cache, id->uid, id->rid); g_static_rw_lock_writer_unlock(&cb->priv->cache_lock); break; } case E_CAL_COMPONENT_CACHE_STATE_NONE: default: break; } next: g_object_unref(comp); g_object_unref(remote_comp); e_cal_component_free_id(id); g_free(object); g_free(remote_object); } g_list_free(components); e_cal_backend_3e_close_connection(cb); return TRUE; }
gboolean scalix_appointment_init_from_mime_message (ScalixObject * object, CamelMimeMessage * msg) { const char *msgid; const char *attachment_store; const char *mime_type, *alternative_mime_type; const char *content_disposition; const char *mime_filename; const char *cid; const char *cuid; const char *attachment_file_url; GSList *attachments = NULL; GSList *attachments_new = NULL; GSList *siter = NULL; CamelMimePart *part, *alternative; CamelMultipart *multipart, *nested_multipart; CamelDataWrapper *content, *alternative_content; int i, j, num_parts, num_alternatives; gboolean found_ical = FALSE; attachment_store = g_object_get_data (G_OBJECT (object), "attachment-store"); part = CAMEL_MIME_PART (msg); content = camel_medium_get_content_object (CAMEL_MEDIUM (part)); if (content == NULL) { return FALSE; } mime_type = camel_content_type_simple (content->mime_type); if (CAMEL_IS_MULTIPART (content)) { multipart = (CamelMultipart *) content; num_parts = (int) camel_multipart_get_number (multipart); for (i = 0; i < num_parts; i++) { part = camel_multipart_get_part (multipart, i); content = camel_medium_get_content_object (CAMEL_MEDIUM (part)); mime_type = camel_content_type_simple (content->mime_type); mime_filename = camel_mime_part_get_filename (part); content_disposition = camel_mime_part_get_disposition (part); if (CAMEL_IS_MULTIPART (content)) { nested_multipart = (CamelMultipart *) content; num_alternatives = (int) camel_multipart_get_number (nested_multipart); for (j = 0; j < num_alternatives; j++) { alternative = camel_multipart_get_part (nested_multipart, j); alternative_content = camel_medium_get_content_object (CAMEL_MEDIUM (alternative)); alternative_mime_type = camel_content_type_simple (alternative_content-> mime_type); if (g_str_equal (alternative_mime_type, "text/calendar") && found_ical == FALSE) { if (set_ical_from_mime_part (alternative, object) == TRUE) { e_cal_component_get_uid (E_CAL_COMPONENT (object), &cuid); e_cal_component_get_attachment_list (E_CAL_COMPONENT (object), &attachments); /* we are only interested in the first ical body part */ found_ical = TRUE; } } } } else if (g_str_equal (mime_type, "text/calendar") && found_ical == FALSE) { if (set_ical_from_mime_part (part, object) == TRUE) { e_cal_component_get_uid (E_CAL_COMPONENT (object), &cuid); e_cal_component_get_attachment_list (E_CAL_COMPONENT (object), &attachments); /* we are only interested in the first ical body part */ found_ical = TRUE; } } else if (content_disposition && strcmp (content_disposition, "attachment") == 0) { cid = camel_mime_part_get_content_id (part); if (cid != NULL) { for (siter = attachments; siter; siter = siter->next) { if (strstr (siter->data, cid) == (char *) (siter->data) + 4) { attachment_file_url = save_attachment (part, cuid, attachment_store); if (attachment_file_url != NULL) { attachments_new = g_slist_append (attachments_new, g_strdup (attachment_file_url)); } } } } } else { g_print ("XXXXX Unhandled mime part: %s\n", mime_type); } } } else { /* just a simple ical message */ if (g_str_equal (mime_type, "text/calendar")) { set_ical_from_mime_part (part, object); } } if (attachments_new != NULL) { e_cal_component_set_attachment_list (E_CAL_COMPONENT (object), attachments_new); } msgid = camel_mime_message_get_message_id (msg); scalix_appointment_unset (SCALIX_APPOINTMENT (object), X_SCALIX_MSG_ID); scalix_appointment_set (SCALIX_APPOINTMENT (object), X_SCALIX_MSG_ID, msgid); return TRUE; }
CamelMimeMessage * scalix_appointment_to_mime_message (ScalixObject * object) { CamelMimeMessage *message; CamelMultipart *multipart; CamelMimePart *part; CamelMedium *medium; CamelStream *stream; CamelDataWrapper *wrapper; ECalComponentDateTime dtstart, dtend; ECalComponent *comp; ECalComponentText text; icalcomponent_kind kind; icalcomponent *icalcomp, *toplevel_comp; icaltimezone *zone = NULL; GSList *attachment_list = NULL; GSList *attachment_list_new = NULL; GSList *siter = NULL; GList *part_list = NULL; GList *iter = NULL; char *msgid; char *str, *meeting_status; const char *ouid = NULL; char *file_contents = NULL; char *full_path, *filename, *mime_filename; char *cid; int size; g_object_get (SCALIX_APPOINTMENT (object), "timezone", &zone, NULL); comp = E_CAL_COMPONENT (scalix_object_clone (object)); message = camel_mime_message_new (); medium = CAMEL_MEDIUM (message); camel_medium_add_header (medium, "X-Scalix-Class", "IPM.Appointment"); /* Preserve msg id if there is already one */ if (scalix_appointment_get (SCALIX_APPOINTMENT (comp), X_SCALIX_MSG_ID, &msgid)) { scalix_appointment_unset (SCALIX_APPOINTMENT (comp), X_SCALIX_MSG_ID); } else { msgid = camel_header_msgid_generate (); } camel_mime_message_set_message_id (message, msgid); /* subject */ e_cal_component_get_summary (comp, &text); if (text.value != NULL) { camel_mime_message_set_subject (message, text.value); } /* start day */ e_cal_component_get_dtstart (comp, &dtstart); if (!icaltime_get_timezone (*dtstart.value)) icaltime_set_timezone (dtstart.value, icaltimezone_get_builtin_timezone_from_tzid (dtstart.tzid)); /* end day */ e_cal_component_get_dtend (comp, &dtend); if (!icaltime_get_timezone (*dtend.value)) icaltime_set_timezone (dtend.value, icaltimezone_get_builtin_timezone_from_tzid (dtend.tzid)); /* set From: and Sender: */ if (e_cal_component_has_organizer (comp)) { ECalComponentOrganizer organizer; e_cal_component_get_organizer (comp, &organizer); if (!strncasecmp (organizer.value, "MAILTO:", 7)) { camel_medium_add_header (medium, "Sender", organizer.value + 7); camel_medium_add_header (medium, "From", organizer.value + 7); } } /* set the appropriate recipient headers from the recipient table */ if (e_cal_component_has_attendees (comp) && e_cal_component_has_organizer (comp)) { GSList *iter, *attendees = NULL; CamelInternetAddress *recipients_to = NULL; CamelInternetAddress *recipients_cc = NULL; meeting_status = "1"; e_cal_component_get_attendee_list (comp, &attendees); for (iter = attendees; iter; iter = iter->next) { ECalComponentAttendee *attendee = iter->data; const char *mail = NULL; /* attendee entries must start with MAILTO: */ if (strncasecmp (attendee->value, "MAILTO:", 7)) { continue; } mail = attendee->value + 7; if (attendee->role == ICAL_ROLE_REQPARTICIPANT) { if (recipients_to == NULL) { recipients_to = camel_internet_address_new (); } camel_internet_address_add (recipients_to, attendee->cn, mail); } else if (attendee->role == ICAL_ROLE_OPTPARTICIPANT) { if (recipients_cc == NULL) { recipients_cc = camel_internet_address_new (); } camel_internet_address_add (recipients_cc, attendee->cn, mail); } else { continue; } } if (recipients_to != NULL) { camel_mime_message_set_recipients (message, "To", recipients_to); camel_object_unref (recipients_to); } if (recipients_cc != NULL) { camel_mime_message_set_recipients (message, "Cc", recipients_cc); camel_object_unref (recipients_cc); } } else { meeting_status = "0"; } /* Clear properties */ scalix_appointment_unset (SCALIX_APPOINTMENT (comp), X_SCALIX_IMAP_UID); /* Render the text/calendar */ e_cal_component_commit_sequence (comp); icalcomp = e_cal_component_get_icalcomponent (comp); kind = icalcomponent_isa (icalcomp); if (kind != ICAL_VCALENDAR_COMPONENT) { /* If its not a VCALENDAR, make it one to simplify below */ toplevel_comp = e_cal_util_new_top_level (); icalcomponent_add_component (toplevel_comp, icalcomp); icalcomp = toplevel_comp; } /* set METHOD to PUSBLISH */ icalcomponent_set_method (icalcomp, ICAL_METHOD_PUBLISH); /* Add the VTIMEZONE components for start- and/or end-times */ if (zone) { icalcomponent_add_component (icalcomp, icaltimezone_get_component (zone)); } else if (dtstart.tzid) { icalcomponent_add_component (icalcomp, icaltimezone_get_component (icaltimezone_get_builtin_timezone_from_tzid (dtstart.tzid))); } if (dtstart.tzid && dtend.tzid && strcmp (dtstart.tzid, dtend.tzid) != 0) { icalcomponent_add_component (icalcomp, icaltimezone_get_component (icaltimezone_get_builtin_timezone_from_tzid (dtend.tzid))); } /* FIXME: do we leek icalcomponents here? */ if (e_cal_component_has_attachments (comp)) { multipart = camel_multipart_new (); camel_multipart_set_boundary (multipart, NULL); e_cal_component_get_uid (comp, &ouid); e_cal_component_get_attachment_list (comp, &attachment_list); for (siter = attachment_list; siter; siter = siter->next) { if (siter->data == NULL) continue; if (strstr (siter->data, "file://") != siter->data) continue; full_path = ((char *) siter->data) + strlen ("file://"); filename = g_strrstr (full_path, "/") + 1; mime_filename = filename + strlen (ouid) + 1; size = 0; file_contents = get_file_contents (full_path, &size); if (file_contents == NULL) continue; stream = camel_stream_mem_new_with_buffer (file_contents, size); wrapper = camel_data_wrapper_new (); camel_data_wrapper_construct_from_stream (wrapper, stream); camel_object_unref (stream); part = camel_mime_part_new (); camel_medium_set_content_object (CAMEL_MEDIUM (part), wrapper); camel_mime_part_set_filename (part, mime_filename); camel_mime_part_set_encoding (part, CAMEL_TRANSFER_ENCODING_BASE64); cid = camel_header_msgid_generate (); camel_mime_part_set_content_id (part, cid); camel_mime_part_set_description (part, mime_filename); camel_mime_part_set_disposition (part, "attachment"); part_list = g_list_append (part_list, part); attachment_list_new = g_slist_append (attachment_list_new, g_strdup_printf ("CID:%s", cid)); g_free (cid); } e_cal_component_set_attachment_list (comp, attachment_list_new); str = icalcomponent_as_ical_string (icalcomp); part = camel_mime_part_new (); camel_mime_part_set_content (part, str, strlen (str), "text/calendar; method=PUBLISH; charset=UTF-8"); part_list = g_list_prepend (part_list, part); for (iter = part_list; iter; iter = iter->next) { part = (CamelMimePart *) iter->data; camel_multipart_add_part (multipart, part); camel_object_unref (part); } camel_medium_set_content_object (CAMEL_MEDIUM (message), CAMEL_DATA_WRAPPER (multipart)); camel_object_unref (multipart); g_slist_free (attachment_list); g_slist_free (attachment_list_new); g_list_free (part_list); } else { str = icalcomponent_as_ical_string (icalcomp); camel_mime_part_set_content (CAMEL_MIME_PART (message), str, strlen (str), "text/calendar; method=PUBLISH; charset=UTF-8"); } scalix_appointment_set (SCALIX_APPOINTMENT (object), X_SCALIX_MSG_ID, msgid); return message; }