Exemple #1
0
CamelMimePart *
mail_tool_make_message_attachment (CamelMimeMessage *message)
{
	CamelMimePart *part;
	const char *subject;
	struct _camel_header_raw *xev;
	char *desc;

	subject = camel_mime_message_get_subject (message);
	if (subject)
		desc = g_strdup_printf (_("Forwarded message - %s"), subject);
	else
		desc = g_strdup (_("Forwarded message"));

	/* rip off the X-Evolution headers */
	xev = mail_tool_remove_xevolution_headers (message);
	camel_header_raw_clear(&xev);

	/* remove Bcc headers */
	camel_medium_remove_header (CAMEL_MEDIUM (message), "Bcc");

	part = camel_mime_part_new ();
	camel_mime_part_set_disposition (part, "inline");
	camel_mime_part_set_description (part, desc);
	camel_medium_set_content_object (CAMEL_MEDIUM (part),
					 CAMEL_DATA_WRAPPER (message));
	camel_mime_part_set_content_type (part, "message/rfc822");
	g_free (desc);

	return part;
}
gboolean
mail_send_short_message (EGdbusSession *object,
		GDBusMethodInvocation *invocation, const char *account_uid,
		const char *text, const char **to,
		EMailDataSession *msession, GError **ret_error)
{
	EAccount *account;
	CamelMimeMessage *message;
	CamelService *service;
	gchar *transport_uid;
	CamelInternetAddress *recipients;
	CamelMessageInfo *info;
	GSimpleAsyncResult *simple;
	SendAsyncContext *context;
	CamelInternetAddress *from;
	GCancellable *ops;
	EMailDataOperation *mops;
	char *mops_path;
	gchar subject[MAX_SUBJECT_LENGTH + 4];
	GError *error = NULL;

	/* Check params. */

	if (account_uid == NULL || *account_uid == 0) {
		error = g_error_new (G_DBUS_ERROR,
						G_DBUS_ERROR_INVALID_ARGS,
						_("Invalid account"));
		goto on_error;
	}
	if (text == NULL || *text == 0) {
		error = g_error_new (G_DBUS_ERROR,
						G_DBUS_ERROR_INVALID_ARGS,
						_("Text is empty"));
		goto on_error;
	}
	if (to == NULL || *to == 0 || **to == 0) {
		error = g_error_new (G_DBUS_ERROR,
						G_DBUS_ERROR_INVALID_ARGS,
						_("No recipient"));
		goto on_error;
	}

	/* Get transport. */

	account = e_get_account_by_uid (account_uid);
	if (!account) {
		error = g_error_new (G_DBUS_ERROR,
						G_DBUS_ERROR_INVALID_ARGS,
						_("Invalid account %s"),
						account_uid);
		goto on_error;
	}

	transport_uid = g_strconcat (account->uid, "-transport", NULL);
	service = camel_session_ref_service (CAMEL_SESSION (session),
								transport_uid);
	if (!CAMEL_IS_TRANSPORT (service)) {
		error = g_error_new(G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
					_("Invalid account %s"), account_uid);
		g_object_unref (account);
		g_free (transport_uid);
		goto on_error;
	}

	/* Prepare message. */

	message = camel_mime_message_new ();
	strncpy (subject, text, MAX_SUBJECT_LENGTH + 1);
	if (strlen(text) > MAX_SUBJECT_LENGTH)
		strcpy (subject + MAX_SUBJECT_LENGTH, "...");
	camel_mime_message_set_subject (message, subject);
	from = camel_internet_address_new ();
	camel_internet_address_add (from, NULL, "sms");
	recipients = camel_internet_address_new ();
	while (*to) {
		camel_internet_address_add (recipients, NULL, *to);
		to++;
	}
	camel_mime_message_set_from (message, from);
	camel_mime_message_set_recipients (message, CAMEL_RECIPIENT_TYPE_TO,
								recipients);
	camel_mime_message_set_date (message, CAMEL_MESSAGE_DATE_CURRENT, 0);
	camel_mime_part_set_content_type (CAMEL_MIME_PART(message),
								"text/plain");
	camel_mime_part_set_content (CAMEL_MIME_PART(message), text,
						strlen(text), "text/plain");

	info = camel_message_info_new (NULL);
	camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, ~0);

	/* Return the new operation */

	ops = camel_operation_new ();
	mops = e_mail_data_operation_new ((CamelOperation *) ops);

	mops_path = e_mail_data_operation_register_gdbus_object (mops,
			g_dbus_method_invocation_get_connection(invocation),
			NULL);
	egdbus_session_complete_send_short_message (object, invocation,
								mops_path);

	/* The rest of the processing happens in a thread. */

	context = g_slice_new0 (SendAsyncContext);
	context->message = message;
	context->io_priority = G_PRIORITY_DEFAULT;
	context->from = CAMEL_ADDRESS (from);
	context->recipients = CAMEL_ADDRESS (recipients);
	context->info = info;
	context->transport = service;
	context->sent_folder_uri = g_strdup (account->sent_folder_uri);
	context->cancellable = ops;
	context->ops_path = mops_path;
	context->result = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);

	/* Failure here emits a runtime warning but is non-fatal. */
	context->driver = camel_session_get_filter_driver (
				CAMEL_SESSION (session), "outgoing", &error);
	if (error != NULL) {
		g_warn_if_fail (context->driver == NULL);
		g_warning ("%s", error->message);
		g_error_free (error);
	}

	/* This gets popped in async_context_free(). */
	camel_operation_push_message (context->cancellable,
							_("Sending message"));

	simple = g_simple_async_result_new (
			G_OBJECT (session), mail_send_short_message_completed,
			context, mail_send_short_message);

	g_simple_async_result_set_op_res_gpointer (
			simple, context, (GDestroyNotify) async_context_free);

	g_simple_async_result_run_in_thread (
			simple,
			(GSimpleAsyncThreadFunc) mail_send_short_to_thread,
			context->io_priority, context->cancellable);

	g_object_unref (simple);

	return TRUE;

on_error:

	*ret_error = error;

	return FALSE;
}
static void
mail_attachment_handler_x_uid_list (EAttachmentView *view,
                                    GdkDragContext *drag_context,
                                    gint x,
                                    gint y,
                                    GtkSelectionData *selection_data,
                                    guint info,
                                    guint time,
                                    EAttachmentHandler *handler)
{
	static GdkAtom atom = GDK_NONE;
	EMailAttachmentHandlerPrivate *priv;
	CamelDataWrapper *wrapper;
	CamelMimeMessage *message;
	CamelMultipart *multipart;
	CamelMimePart *mime_part;
	CamelFolder *folder = NULL;
	EAttachment *attachment;
	EAttachmentStore *store;
	EMailSession *session;
	GPtrArray *uids;
	const gchar *data;
	const gchar *cp, *end;
	gchar *description;
	gpointer parent;
	gint length;
	guint ii;
	GError *local_error = NULL;

	if (G_UNLIKELY (atom == GDK_NONE))
		atom = gdk_atom_intern_static_string ("x-uid-list");

	if (gtk_selection_data_get_target (selection_data) != atom)
		return;

	store = e_attachment_view_get_store (view);
	priv = E_MAIL_ATTACHMENT_HANDLER_GET_PRIVATE (handler);

	parent = gtk_widget_get_toplevel (GTK_WIDGET (view));
	parent = gtk_widget_is_toplevel (parent) ? parent : NULL;

	uids = g_ptr_array_new ();

	data = (const gchar *) gtk_selection_data_get_data (selection_data);
	length = gtk_selection_data_get_length (selection_data);

	/* The UID list is delimited by NUL characters.
	 * Brilliant.  So we can't use g_strsplit(). */

	cp = data;
	end = data + length;

	while (cp < end) {
		const gchar *start = cp;

		while (cp < end && *cp != '\0')
			cp++;

		/* Skip the first string. */
		if (start > data)
			g_ptr_array_add (uids, g_strndup (start, cp - start));

		cp++;
	}

	if (uids->len == 0)
		goto exit;

	session = e_mail_backend_get_session (priv->backend);

	/* The first string is the folder URI. */
	/* FIXME Not passing a GCancellable here. */
	folder = e_mail_session_uri_to_folder_sync (
		session, data, 0, NULL, &local_error);
	if (folder == NULL)
		goto exit;

	/* Handle one message. */
	if (uids->len == 1) {
		const gchar *message_uid;

		message_uid = g_ptr_array_index (uids, 0);

		/* FIXME Not passing a GCancellable here. */
		message = camel_folder_get_message_sync (
			folder, message_uid, NULL, &local_error);
		if (message == NULL)
			goto exit;

		attachment = e_attachment_new_for_message (message);
		e_attachment_store_add_attachment (store, attachment);
		e_attachment_load_async (
			attachment, (GAsyncReadyCallback)
			call_attachment_load_handle_error, parent ? g_object_ref (parent) : NULL);

		g_object_unref (attachment);

		g_object_unref (message);
		goto exit;
	}

	/* Build a multipart/digest message out of the UIDs. */

	multipart = camel_multipart_new ();
	wrapper = CAMEL_DATA_WRAPPER (multipart);
	camel_data_wrapper_set_mime_type (wrapper, "multipart/digest");
	camel_multipart_set_boundary (multipart, NULL);

	for (ii = 0; ii < uids->len; ii++) {
		/* FIXME Not passing a GCancellable here. */
		message = camel_folder_get_message_sync (
			folder, uids->pdata[ii], NULL, &local_error);
		if (message == NULL) {
			g_object_unref (multipart);
			goto exit;
		}

		mime_part = camel_mime_part_new ();
		wrapper = CAMEL_DATA_WRAPPER (message);
		camel_mime_part_set_disposition (mime_part, "inline");
		camel_medium_set_content (
			CAMEL_MEDIUM (mime_part), wrapper);
		camel_mime_part_set_content_type (mime_part, "message/rfc822");
		camel_multipart_add_part (multipart, mime_part);
		g_object_unref (mime_part);

		g_object_unref (message);
	}

	mime_part = camel_mime_part_new ();
	wrapper = CAMEL_DATA_WRAPPER (multipart);
	camel_medium_set_content (CAMEL_MEDIUM (mime_part), wrapper);

	description = g_strdup_printf (
		ngettext (
			"%d attached message",
			"%d attached messages",
			uids->len),
		uids->len);
	camel_mime_part_set_description (mime_part, description);
	g_free (description);

	attachment = e_attachment_new ();
	e_attachment_set_mime_part (attachment, mime_part);
	e_attachment_store_add_attachment (store, attachment);
	e_attachment_load_async (
		attachment, (GAsyncReadyCallback)
		call_attachment_load_handle_error, parent ? g_object_ref (parent) : NULL);
	g_object_unref (attachment);

	g_object_unref (mime_part);
	g_object_unref (multipart);

exit:
	if (local_error != NULL) {
		const gchar *folder_name = data;

		if (folder != NULL)
			folder_name = camel_folder_get_display_name (folder);

		e_alert_run_dialog_for_args (
			parent, "mail-composer:attach-nomessages",
			folder_name, local_error->message, NULL);

		g_clear_error (&local_error);
	}

	if (folder != NULL)
		g_object_unref (folder);

	g_ptr_array_free (uids, TRUE);

	g_signal_stop_emission_by_name (view, "drag-data-received");
}