static gboolean
matches_attendee (ECalComponent *comp,
                  const gchar *str)
{
	GSList *a_list = NULL, *l;
	gboolean matches = FALSE;

	e_cal_component_get_attendee_list (comp, &a_list);

	for (l = a_list; l; l = l->next) {
		ECalComponentAttendee *att = l->data;

		if ((att->value && e_util_strstrcase (att->value, str)) || (att->cn != NULL &&
					e_util_strstrcase (att->cn, str))) {
			matches = TRUE;
			break;
		}
	}

	e_cal_component_free_attendee_list (a_list);

	return matches;

}
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;
}
Beispiel #3
0
static void
do_save_calendar_rdf (FormatHandler *handler,
                      ESourceSelector *selector,
                      ECalClientSourceType type,
                      gchar *dest_uri)
{

	/*
	 * According to some documentation about CSV, newlines 'are' allowed
	 * in CSV-files. But you 'do' have to put the value between quotes.
	 * The helper 'string_needsquotes' will check for that
	 *
	 * http://www.creativyst.com/Doc/Articles/CSV/CSV01.htm
	 * http://www.creativyst.com/cgi-bin/Prod/15/eg/csv2xml.pl
	 */

	ESource *primary_source;
	EClient *source_client;
	GError *error = NULL;
	GSList *objects = NULL;
	gchar *temp = NULL;
	GOutputStream *stream;

	if (!dest_uri)
		return;

	/* open source client */
	primary_source = e_source_selector_ref_primary_selection (selector);
	source_client = e_cal_client_connect_sync (
		primary_source, type, NULL, &error);
	g_object_unref (primary_source);

	/* Sanity check. */
	g_return_if_fail (
		((source_client != NULL) && (error == NULL)) ||
		((source_client == NULL) && (error != NULL)));

	if (source_client == NULL) {
		display_error_message (
			gtk_widget_get_toplevel (GTK_WIDGET (selector)),
			error->message);
		g_error_free (error);
		return;
	}

	stream = open_for_writing (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (selector))), dest_uri, &error);

	if (stream && e_cal_client_get_object_list_as_comps_sync (E_CAL_CLIENT (source_client), "#t", &objects, NULL, NULL)) {
		GSList *iter;

		xmlBufferPtr buffer = xmlBufferCreate ();
		xmlDocPtr doc = xmlNewDoc ((xmlChar *) "1.0");
		xmlNodePtr fnode;

		doc->children = xmlNewDocNode (doc, NULL, (const guchar *)"rdf:RDF", NULL);
		xmlSetProp (doc->children, (const guchar *)"xmlns:rdf", (const guchar *)"http://www.w3.org/1999/02/22-rdf-syntax-ns#");
		xmlSetProp (doc->children, (const guchar *)"xmlns", (const guchar *)"http://www.w3.org/2002/12/cal/ical#");

		fnode = xmlNewChild (doc->children, NULL, (const guchar *)"Vcalendar", NULL);

		/* Should Evolution publicise these? */
		xmlSetProp (fnode, (const guchar *)"xmlns:x-wr", (const guchar *)"http://www.w3.org/2002/12/cal/prod/Apple_Comp_628d9d8459c556fa#");
		xmlSetProp (fnode, (const guchar *)"xmlns:x-lic", (const guchar *)"http://www.w3.org/2002/12/cal/prod/Apple_Comp_628d9d8459c556fa#");

		/* Not sure if it's correct like this */
		xmlNewChild (fnode, NULL, (const guchar *)"prodid", (const guchar *)"-//" PACKAGE_STRING "//iCal 1.0//EN");

		/* Assuming GREGORIAN is the only supported calendar scale */
		xmlNewChild (fnode, NULL, (const guchar *)"calscale", (const guchar *)"GREGORIAN");

		temp = calendar_config_get_timezone ();
		xmlNewChild (fnode, NULL, (const guchar *)"x-wr:timezone", (guchar *) temp);
		g_free (temp);

		xmlNewChild (fnode, NULL, (const guchar *)"method", (const guchar *)"PUBLISH");

		xmlNewChild (fnode, NULL, (const guchar *)"x-wr:relcalid", (guchar *) e_source_get_uid (primary_source));

		xmlNewChild (fnode, NULL, (const guchar *)"x-wr:calname", (guchar *) e_source_get_display_name (primary_source));

		/* Version of this RDF-format */
		xmlNewChild (fnode, NULL, (const guchar *)"version", (const guchar *)"2.0");

		for (iter = objects; iter; iter = iter->next) {
			ECalComponent *comp = iter->data;
			const gchar *temp_constchar;
			gchar *tmp_str = NULL;
			GSList *temp_list;
			ECalComponentDateTime temp_dt;
			struct icaltimetype *temp_time;
			gint *temp_int;
			ECalComponentText temp_comptext;
			xmlNodePtr c_node = xmlNewChild (fnode, NULL, (const guchar *)"component", NULL);
			xmlNodePtr node = xmlNewChild (c_node, NULL, (const guchar *)"Vevent", NULL);

			/* Getting the stuff */
			e_cal_component_get_uid (comp, &temp_constchar);
			tmp_str = g_strdup_printf ("#%s", temp_constchar);
			xmlSetProp (node, (const guchar *)"about", (guchar *) tmp_str);
			g_free (tmp_str);
			add_string_to_rdf (node, "uid",temp_constchar);

			e_cal_component_get_summary (comp, &temp_comptext);
			add_string_to_rdf (node, "summary", temp_comptext.value);

			e_cal_component_get_description_list (comp, &temp_list);
			add_list_to_rdf (node, "description", temp_list, ECALCOMPONENTTEXT);
			if (temp_list)
				e_cal_component_free_text_list (temp_list);

			e_cal_component_get_categories_list (comp, &temp_list);
			add_list_to_rdf (node, "categories", temp_list, CONSTCHAR);
			if (temp_list)
				e_cal_component_free_categories_list (temp_list);

			e_cal_component_get_comment_list (comp, &temp_list);
			add_list_to_rdf (node, "comment", temp_list, ECALCOMPONENTTEXT);

			if (temp_list)
				e_cal_component_free_text_list (temp_list);

			e_cal_component_get_completed (comp, &temp_time);
			add_time_to_rdf (node, "completed", temp_time);
			if (temp_time)
				e_cal_component_free_icaltimetype (temp_time);

			e_cal_component_get_created (comp, &temp_time);
			add_time_to_rdf (node, "created", temp_time);
			if (temp_time)
				e_cal_component_free_icaltimetype (temp_time);

			e_cal_component_get_contact_list (comp, &temp_list);
			add_list_to_rdf (node, "contact", temp_list, ECALCOMPONENTTEXT);
			if (temp_list)
				e_cal_component_free_text_list (temp_list);

			e_cal_component_get_dtstart (comp, &temp_dt);
			add_time_to_rdf (node, "dtstart", temp_dt.value ? temp_dt.value : NULL);
			e_cal_component_free_datetime (&temp_dt);

			e_cal_component_get_dtend (comp, &temp_dt);
			add_time_to_rdf (node, "dtend", temp_dt.value ? temp_dt.value : NULL);
			e_cal_component_free_datetime (&temp_dt);

			e_cal_component_get_due (comp, &temp_dt);
			add_time_to_rdf (node, "due", temp_dt.value ? temp_dt.value : NULL);
			e_cal_component_free_datetime (&temp_dt);

			e_cal_component_get_percent (comp, &temp_int);
			add_nummeric_to_rdf (node, "percentComplete", temp_int);

			e_cal_component_get_priority (comp, &temp_int);
			add_nummeric_to_rdf (node, "priority", temp_int);

			e_cal_component_get_url (comp, &temp_constchar);
			add_string_to_rdf (node, "URL", temp_constchar);

			if (e_cal_component_has_attendees (comp)) {
				e_cal_component_get_attendee_list (comp, &temp_list);
				add_list_to_rdf (node, "attendee", temp_list, ECALCOMPONENTATTENDEE);
				if (temp_list)
					e_cal_component_free_attendee_list (temp_list);
			}

			e_cal_component_get_location (comp, &temp_constchar);
			add_string_to_rdf (node, "location", temp_constchar);

			e_cal_component_get_last_modified (comp, &temp_time);
			add_time_to_rdf (node, "lastModified",temp_time);

			/* Important note!
			 * The documentation is not requiring this!
			 *
			 * if (temp_time) e_cal_component_free_icaltimetype (temp_time);
			 *
			 * Please uncomment and fix documentation if untrue
			 * http://www.gnome.org/projects/evolution/developer-doc/libecal/ECalComponent.html
			 *	#e-cal-component-get-last-modified
			 */
		}

		/* I used a buffer rather than xmlDocDump: I want gio support */
		xmlNodeDump (buffer, doc, doc->children, 2, 1);

		g_output_stream_write_all (stream, xmlBufferContent (buffer), xmlBufferLength (buffer), NULL, NULL, &error);
		g_output_stream_close (stream, NULL, NULL);

		e_cal_client_free_ecalcomp_slist (objects);

		xmlBufferFree (buffer);
		xmlFreeDoc (doc);
	}

	if (stream)
		g_object_unref (stream);

	g_object_unref (source_client);

	if (error != NULL) {
		display_error_message (
			gtk_widget_get_toplevel (GTK_WIDGET (selector)),
			error->message);
		g_error_free (error);
	}
}
Beispiel #4
0
static void
do_save_calendar_csv (FormatHandler *handler,
                      ESourceSelector *selector,
                      ECalClientSourceType type,
                      gchar *dest_uri)
{

	/*
	 * According to some documentation about CSV, newlines 'are' allowed
	 * in CSV-files. But you 'do' have to put the value between quotes.
	 * The helper 'string_needsquotes' will check for that
	 *
	 * http://www.creativyst.com/Doc/Articles/CSV/CSV01.htm
	 * http://www.creativyst.com/cgi-bin/Prod/15/eg/csv2xml.pl
	 */

	ESource *primary_source;
	EClient *source_client;
	GError *error = NULL;
	GSList *objects = NULL;
	GOutputStream *stream;
	GString *line = NULL;
	CsvConfig *config = NULL;
	CsvPluginData *d = handler->data;
	const gchar *tmp = NULL;

	if (!dest_uri)
		return;

	/* open source client */
	primary_source = e_source_selector_ref_primary_selection (selector);
	source_client = e_cal_client_connect_sync (
		primary_source, type, NULL, &error);
	g_object_unref (primary_source);

	/* Sanity check. */
	g_return_if_fail (
		((source_client != NULL) && (error == NULL)) ||
		((source_client == NULL) && (error != NULL)));

	if (source_client == NULL) {
		display_error_message (
			gtk_widget_get_toplevel (GTK_WIDGET (selector)),
			error);
		g_error_free (error);
		return;
	}

	config = g_new (CsvConfig, 1);

	tmp = gtk_entry_get_text (GTK_ENTRY (d->delimiter_entry));
	config->delimiter = userstring_to_systemstring (tmp ? tmp:", ");
	tmp = gtk_entry_get_text (GTK_ENTRY (d->newline_entry));
	config->newline = userstring_to_systemstring (tmp ? tmp:"\\n");
	tmp = gtk_entry_get_text (GTK_ENTRY (d->quote_entry));
	config->quote = userstring_to_systemstring (tmp ? tmp:"\"");
	config->header = gtk_toggle_button_get_active (
		GTK_TOGGLE_BUTTON (d->header_check));

	stream = open_for_writing (
		GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (selector))),
		dest_uri, &error);

	if (stream && e_cal_client_get_object_list_as_comps_sync (E_CAL_CLIENT (source_client), "#t", &objects, NULL, NULL)) {
		GSList *iter;

		if (config->header) {

			gint i = 0;

			static const gchar *labels[] = {
				 N_("UID"),
				 N_("Summary"),
				 N_("Description List"),
				 N_("Categories List"),
				 N_("Comment List"),
				 N_("Completed"),
				 N_("Created"),
				 N_("Contact List"),
				 N_("Start"),
				 N_("End"),
				 N_("Due"),
				 N_("percent Done"),
				 N_("Priority"),
				 N_("URL"),
				 N_("Attendees List"),
				 N_("Location"),
				 N_("Modified"),
			};

			line = g_string_new ("");
			for (i = 0; i < G_N_ELEMENTS (labels); i++) {
				if (i > 0)
					g_string_append (line, config->delimiter);
				g_string_append (line, _(labels[i]));
			}

			g_string_append (line, config->newline);

			g_output_stream_write_all (
				stream, line->str, line->len,
				NULL, NULL, NULL);
			g_string_free (line, TRUE);
		}

		for (iter = objects; iter; iter = iter->next) {
			ECalComponent *comp = iter->data;
			gchar *delimiter_temp = NULL;
			const gchar *temp_constchar;
			GSList *temp_list;
			ECalComponentDateTime temp_dt;
			struct icaltimetype *temp_time;
			gint *temp_int;
			ECalComponentText temp_comptext;

			line = g_string_new ("");

			/* Getting the stuff */
			e_cal_component_get_uid (comp, &temp_constchar);
			line = add_string_to_csv (line, temp_constchar, config);

			e_cal_component_get_summary (comp, &temp_comptext);
			line = add_string_to_csv (
				line, temp_comptext.value, config);

			e_cal_component_get_description_list (comp, &temp_list);
			line = add_list_to_csv (
				line, temp_list, config, ECALCOMPONENTTEXT);
			if (temp_list)
				e_cal_component_free_text_list (temp_list);

			e_cal_component_get_categories_list (comp, &temp_list);
			line = add_list_to_csv (
				line, temp_list, config, CONSTCHAR);
			if (temp_list)
				e_cal_component_free_categories_list (temp_list);

			e_cal_component_get_comment_list (comp, &temp_list);
			line = add_list_to_csv (
				line, temp_list, config, ECALCOMPONENTTEXT);
			if (temp_list)
				e_cal_component_free_text_list (temp_list);

			e_cal_component_get_completed (comp, &temp_time);
			line = add_time_to_csv (line, temp_time, config);
			if (temp_time)
				e_cal_component_free_icaltimetype (temp_time);

			e_cal_component_get_created (comp, &temp_time);
			line = add_time_to_csv (line, temp_time, config);
			if (temp_time)
				e_cal_component_free_icaltimetype (temp_time);

			e_cal_component_get_contact_list (comp, &temp_list);
			line = add_list_to_csv (
				line, temp_list, config, ECALCOMPONENTTEXT);
			if (temp_list)
				e_cal_component_free_text_list (temp_list);

			e_cal_component_get_dtstart (comp, &temp_dt);
			line = add_time_to_csv (
				line, temp_dt.value ?
				temp_dt.value : NULL, config);
			e_cal_component_free_datetime (&temp_dt);

			e_cal_component_get_dtend (comp, &temp_dt);
			line = add_time_to_csv (
				line, temp_dt.value ?
				temp_dt.value : NULL, config);
			e_cal_component_free_datetime (&temp_dt);

			e_cal_component_get_due (comp, &temp_dt);
			line = add_time_to_csv (
				line, temp_dt.value ?
				temp_dt.value : NULL, config);
			e_cal_component_free_datetime (&temp_dt);

			e_cal_component_get_percent (comp, &temp_int);
			line = add_nummeric_to_csv (line, temp_int, config);

			e_cal_component_get_priority (comp, &temp_int);
			line = add_nummeric_to_csv (line, temp_int, config);

			e_cal_component_get_url (comp, &temp_constchar);
			line = add_string_to_csv (line, temp_constchar, config);

			if (e_cal_component_has_attendees (comp)) {
				e_cal_component_get_attendee_list (comp, &temp_list);
				line = add_list_to_csv (
					line, temp_list, config,
					ECALCOMPONENTATTENDEE);
				if (temp_list)
					e_cal_component_free_attendee_list (temp_list);
			} else {
				line = add_list_to_csv (
					line, NULL, config,
					ECALCOMPONENTATTENDEE);
			}

			e_cal_component_get_location (comp, &temp_constchar);
			line = add_string_to_csv (line, temp_constchar, config);

			e_cal_component_get_last_modified (comp, &temp_time);

			/* Append a newline (record delimiter) */
			delimiter_temp = config->delimiter;
			config->delimiter = config->newline;

			line = add_time_to_csv (line, temp_time, config);

			/* And restore for the next record */
			config->delimiter = delimiter_temp;

			/* Important note!
			 * The documentation is not requiring this!
			 *
			 * if (temp_time)
			 *     e_cal_component_free_icaltimetype (temp_time);
			 *
			 * Please uncomment and fix documentation if untrue
			 * http://www.gnome.org/projects/evolution/
			 *	developer-doc/libecal/ECalComponent.html
			 *	#e-cal-component-get-last-modified
			 */
			g_output_stream_write_all (
				stream, line->str, line->len,
				NULL, NULL, &error);

			/* It's written, so we can free it */
			g_string_free (line, TRUE);
		}

		g_output_stream_close (stream, NULL, NULL);

		e_cal_client_free_ecalcomp_slist (objects);
	}

	if (stream)
		g_object_unref (stream);

	g_object_unref (source_client);

	g_free (config->delimiter);
	g_free (config->quote);
	g_free (config->newline);
	g_free (config);

	if (error != NULL) {
		display_error_message (
			gtk_widget_get_toplevel (GTK_WIDGET (selector)),
			error);
		g_error_free (error);
	}
}
/** Collect recipients from the iTip (based on the METHOD).
 *
 * To exclude username from the list, pass his name using @a sender
 * parameter.
 *
 * @param icomp iCal component.
 * @param sender Username to exclude from the list.
 * @param recipients Pointer to the list of recipients' emails. It will be
 * appended to.
 */
void icalcomponent_collect_recipients(icalcomponent *icomp, const char *sender, GSList * *recipients)
{
    GSList *to_list = NULL, *attendees = NULL, *iter;
    ECalComponentOrganizer organizer;
    icalproperty_method method;
    icalcomponent *payload;
    ECalComponent *ecomp = NULL;

    payload = icalcomponent_get_itip_payload(icomp);
    method = icalcomponent_get_itip_method(icomp);

    if (payload == NULL)
    {
        goto out;
    }

    ecomp = e_cal_component_new();
    e_cal_component_set_icalcomponent(ecomp, icalcomponent_new_clone(payload));
    e_cal_component_get_attendee_list(ecomp, &attendees);
    e_cal_component_get_organizer(ecomp, &organizer);
    if (organizer.value == NULL)
    {
        goto out;
    }

    switch (method)
    {
    case ICAL_METHOD_REQUEST:
    case ICAL_METHOD_CANCEL:
        for (iter = attendees; iter; iter = iter->next)
        {
            ECalComponentAttendee *att = iter->data;

            if (!g_ascii_strcasecmp(att->value, organizer.value))
            {
                continue;
            }
            else if (att->sentby && !g_ascii_strcasecmp(att->sentby, organizer.sentby))
            {
                continue;
            }
            else if (!g_ascii_strcasecmp(strip_mailto(att->value), sender))
            {
                continue;
            }
            else if (att->status == ICAL_PARTSTAT_DELEGATED && (att->delto && *att->delto)
                     && !(att->rsvp) && method == ICAL_METHOD_REQUEST)
            {
                continue;
            }

            to_list = g_slist_append(to_list, g_strdup(strip_mailto(att->value)));
        }
        break;

    case ICAL_METHOD_REPLY:
        to_list = g_slist_append(to_list, g_strdup(strip_mailto(organizer.value)));
        break;

    case ICAL_METHOD_ADD:
    case ICAL_METHOD_REFRESH:
    case ICAL_METHOD_COUNTER:
    case ICAL_METHOD_DECLINECOUNTER:
        to_list = g_slist_append(to_list, g_strdup(strip_mailto(organizer.value)));
        // send the status to delegatee to the delegate also is missing
        break;

    case ICAL_METHOD_PUBLISH:
    default:
        break;
    }

out:
    e_cal_component_free_attendee_list(attendees);
    if (ecomp)
    {
        g_object_unref(ecomp);
    }
    if (recipients)
    {
        *recipients = to_list;
    }
}
static void
preview_comp (EWebViewPreview *preview,
              ECalComponent *comp)
{
	ECalComponentText text = { 0 };
	ECalComponentDateTime dt;
	ECalComponentClassification classif;
	const gchar *str;
	gchar *tmp;
	gint percent;
	gboolean have;
	GHashTable *timezones;
	icaltimezone *users_zone;
	GSList *slist, *l;

	g_return_if_fail (preview != NULL);
	g_return_if_fail (comp != NULL);

	timezones = g_object_get_data (G_OBJECT (preview), "iCalImp-timezones");
	users_zone = g_object_get_data (G_OBJECT (preview), "iCalImp-userszone");

	str = NULL;
	switch (e_cal_component_get_vtype (comp)) {
	case E_CAL_COMPONENT_EVENT:
		str = e_cal_component_has_attendees (comp) ? C_("iCalImp", "Meeting") : C_("iCalImp", "Event");
		break;
	case E_CAL_COMPONENT_TODO:
		str = C_("iCalImp", "Task");
		break;
	case E_CAL_COMPONENT_JOURNAL:
		str = C_("iCalImp", "Memo");
		break;
	default:
		str = "??? Other ???";
		break;
	}

	have = FALSE;
	if (e_cal_component_has_recurrences (comp)) {
		e_web_view_preview_add_section (preview, have ? NULL : str, C_("iCalImp", "has recurrences"));
		have = TRUE;
	}

	if (e_cal_component_is_instance (comp)) {
		e_web_view_preview_add_section (preview, have ? NULL : str, C_("iCalImp", "is an instance"));
		have = TRUE;
	}

	if (e_cal_component_has_alarms (comp)) {
		e_web_view_preview_add_section (preview, have ? NULL : str, C_("iCalImp", "has reminders"));
		have = TRUE;
	}

	if (e_cal_component_has_attachments (comp)) {
		e_web_view_preview_add_section (preview, have ? NULL : str, C_("iCalImp", "has attachments"));
		have = TRUE;
	}

	if (!have) {
		e_web_view_preview_add_section (preview, str, "");
	}

	str = NULL;
	classif = E_CAL_COMPONENT_CLASS_NONE;
	e_cal_component_get_classification (comp, &classif);
	if (classif == E_CAL_COMPONENT_CLASS_PUBLIC) {
		/* Translators: Appointment's classification */
		str = C_("iCalImp", "Public");
	} else if (classif == E_CAL_COMPONENT_CLASS_PRIVATE) {
		/* Translators: Appointment's classification */
		str = C_("iCalImp", "Private");
	} else if (classif == E_CAL_COMPONENT_CLASS_CONFIDENTIAL) {
		/* Translators: Appointment's classification */
		str = C_("iCalImp", "Confidential");
	}
	if (str)
		/* Translators: Appointment's classification section name */
		e_web_view_preview_add_section (preview, C_("iCalImp", "Classification"), str);

	e_cal_component_get_summary (comp, &text);
	if ((text.value && *text.value) || (text.altrep && *text.altrep))
		/* Translators: Appointment's summary */
		e_web_view_preview_add_section (preview, C_("iCalImp", "Summary"), (text.value && *text.value) ? text.value : text.altrep);

	str = NULL;
	e_cal_component_get_location (comp, &str);
	if (str && *str)
		/* Translators: Appointment's location */
		e_web_view_preview_add_section (preview, C_("iCalImp", "Location"), str);

	dt.value = NULL;
	e_cal_component_get_dtstart (comp, &dt);
	if (dt.value) {
		tmp = format_dt (&dt, timezones, users_zone);
		if (tmp)
			/* Translators: Appointment's start time */
			e_web_view_preview_add_section (preview, C_("iCalImp", "Start"), tmp);
		g_free (tmp);
	}
	e_cal_component_free_datetime (&dt);

	dt.value = NULL;
	e_cal_component_get_due (comp, &dt);
	if (dt.value) {
		tmp = format_dt (&dt, timezones, users_zone);
		if (tmp)
			/* Translators: 'Due' like the time due a task should be finished */
			e_web_view_preview_add_section (preview, C_("iCalImp", "Due"), tmp);
		g_free (tmp);
	} else {
		e_cal_component_free_datetime (&dt);

		dt.value = NULL;
		e_cal_component_get_dtend (comp, &dt);
		if (dt.value) {
			tmp = format_dt (&dt, timezones, users_zone);

			if (tmp)
				/* Translators: Appointment's end time */
				e_web_view_preview_add_section (preview, C_("iCalImp", "End"), tmp);
			g_free (tmp);
		}
	}
	e_cal_component_free_datetime (&dt);

	str = NULL;
	e_cal_component_get_categories (comp, &str);
	if (str && *str)
		/* Translators: Appointment's categories */
		e_web_view_preview_add_section (preview, C_("iCalImp", "Categories"), str);

	percent = e_cal_component_get_percent_as_int (comp);
	if (percent >= 0) {
		tmp = NULL;
		if (percent == 100) {
			icaltimetype *completed = NULL;

			e_cal_component_get_completed (comp, &completed);

			if (completed) {
				dt.tzid = "UTC";
				dt.value = completed;

				tmp = format_dt (&dt, timezones, users_zone);

				e_cal_component_free_icaltimetype (completed);
			}
		}

		if (!tmp)
			tmp = g_strdup_printf ("%d%%", percent);

		/* Translators: Appointment's complete value (either percentage, or a date/time of a completion) */
		e_web_view_preview_add_section (preview, C_("iCalImp", "Completed"), tmp);
		g_free (tmp);
	}

	str = NULL;
	e_cal_component_get_url (comp, &str);
	if (str && *str)
		/* Translators: Appointment's URL */
		e_web_view_preview_add_section (preview, C_("iCalImp", "URL"), str);

	if (e_cal_component_has_organizer (comp)) {
		ECalComponentOrganizer organizer = { 0 };

		e_cal_component_get_organizer (comp, &organizer);

		if (organizer.value && *organizer.value) {
			if (organizer.cn && *organizer.cn) {
				tmp = g_strconcat (organizer.cn, " <", strip_mailto (organizer.value), ">", NULL);
				/* Translators: Appointment's organizer */
				e_web_view_preview_add_section (preview, C_("iCalImp", "Organizer"), tmp);
				g_free (tmp);
			} else {
				e_web_view_preview_add_section (preview, C_("iCalImp", "Organizer"), strip_mailto (organizer.value));
			}
		}
	}

	if (e_cal_component_has_attendees (comp)) {
		GSList *attendees = NULL, *a;
		have = FALSE;

		e_cal_component_get_attendee_list (comp, &attendees);

		for (a = attendees; a; a = a->next) {
			ECalComponentAttendee *attnd = a->data;

			if (!attnd || !attnd->value || !*attnd->value)
				continue;

			if (attnd->cn && *attnd->cn) {
				tmp = g_strconcat (attnd->cn, " <", strip_mailto (attnd->value), ">", NULL);
				/* Translators: Appointment's attendees */
				e_web_view_preview_add_section (preview, have ? NULL : C_("iCalImp", "Attendees"), tmp);
				g_free (tmp);
			} else {
				e_web_view_preview_add_section (preview, have ? NULL : C_("iCalImp", "Attendees"), strip_mailto (attnd->value));
			}

			have = TRUE;
		}

		e_cal_component_free_attendee_list (attendees);
	}

	slist = NULL;
	e_cal_component_get_description_list (comp, &slist);
	for (l = slist; l; l = l->next) {
		ECalComponentText *txt = l->data;

		e_web_view_preview_add_section (preview, l != slist ? NULL : C_("iCalImp", "Description"), (txt && txt->value) ? txt->value : "");
	}

	e_cal_component_free_text_list (slist);
}