[geary] Attach inline parts to outgoing messages. Bug 712995.
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary] Attach inline parts to outgoing messages. Bug 712995.
- Date: Mon, 3 Oct 2016 23:47:47 +0000 (UTC)
commit 4b946847f3ce5bd9d68fa45bc2ce182567d541c2
Author: Michael James Gratton <mike vee net>
Date: Thu Sep 29 13:35:19 2016 +1000
Attach inline parts to outgoing messages. Bug 712995.
* src/engine/rfc822/rfc822-message.vala (Message::from_composed_email):
Check for inline files on the ComposedEmail, if found create a new
related multipart to encapsulate the HTML and its images.
(Message::coalesce_related): New method that sets the Type header for
multipart/related parts.
(Message.get_file_part): Renamed from get_attachment_part, add
disposition type arg to allow specifying if content disposition of the
new part.
* src/engine/api/geary-composed-email.vala (ComposedEmail): Replace
attachment_files field with both attached_files and inline_files, so
that inline attachments can be passed through to RFC822.Message.
* src/client/composer/composer-widget.vala
(ComposerWidget::get_composed_email): Set both attached and inline
files on the composed email.
src/client/composer/composer-widget.vala | 4 +-
src/engine/api/geary-composed-email.vala | 7 ++-
src/engine/rfc822/rfc822-message.vala | 67 ++++++++++++++++++++++++------
3 files changed, 61 insertions(+), 17 deletions(-)
---
diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala
index 92a6c9f..d95371e 100644
--- a/src/client/composer/composer-widget.vala
+++ b/src/client/composer/composer-widget.vala
@@ -978,8 +978,8 @@ public class ComposerWidget : Gtk.EventBox {
if (!Geary.String.is_empty(this.subject))
email.subject = this.subject;
- email.attachment_files.add_all(this.attached_files);
- //email.inline_files.add_all(this.inline_files);
+ email.attached_files.add_all(this.attached_files);
+ email.inline_files.add_all(this.inline_files);
if (actions.get_action_state(ACTION_COMPOSE_AS_HTML).get_boolean() || only_html)
email.body_html = get_html();
diff --git a/src/engine/api/geary-composed-email.vala b/src/engine/api/geary-composed-email.vala
index 9e9683f..3678893 100644
--- a/src/engine/api/geary-composed-email.vala
+++ b/src/engine/api/geary-composed-email.vala
@@ -31,9 +31,12 @@ public class Geary.ComposedEmail : BaseObject {
public string? body_text { get; set; default = null; }
public string? body_html { get; set; default = null; }
public string? mailer { get; set; default = null; }
- public Gee.Set<File> attachment_files { get; private set;
+
+ public Gee.Set<File> attached_files { get; private set;
default = new Gee.HashSet<File>(Geary.Files.nullable_hash, Geary.Files.nullable_equal); }
-
+ public Gee.Set<File> inline_files { get; private set;
+ default = new Gee.HashSet<File>(Geary.Files.nullable_hash, Geary.Files.nullable_equal); }
+
public ComposedEmail(DateTime date, RFC822.MailboxAddresses from,
RFC822.MailboxAddresses? to = null, RFC822.MailboxAddresses? cc = null,
RFC822.MailboxAddresses? bcc = null, string? subject = null,
diff --git a/src/engine/rfc822/rfc822-message.vala b/src/engine/rfc822/rfc822-message.vala
index b2f4923..a3322e3 100644
--- a/src/engine/rfc822/rfc822-message.vala
+++ b/src/engine/rfc822/rfc822-message.vala
@@ -168,7 +168,7 @@ public class Geary.RFC822.Message : BaseObject {
}
// Body: HTML format (also optional)
- GMime.Part? body_html = null;
+ GMime.Object? body_html = null;
if (email.body_html != null) {
body_html = body_data_to_part(email.body_html.data,
ref body_charset,
@@ -179,19 +179,50 @@ public class Geary.RFC822.Message : BaseObject {
// Build the message's mime part.
Gee.List<GMime.Object> main_parts = new Gee.LinkedList<GMime.Object>();
-
+
Gee.List<GMime.Object> body_parts = new Gee.LinkedList<GMime.Object>();
if (body_text != null)
body_parts.add(body_text);
- if (body_html != null)
+
+ if (body_html != null) {
+ Gee.List<GMime.Object> related_parts =
+ new Gee.LinkedList<GMime.Object>();
+ if (!email.inline_files.is_empty) {
+ // Check inline images to be attached
+ uint index = 0;
+ foreach (File file in email.inline_files) {
+ GMime.Object? inline_part = get_file_part(
+ file, Geary.Mime.DispositionType.INLINE
+ );
+ if (inline_part != null) {
+ inline_part.set_content_id(
+ "inline_%u@geary".printf(index++)
+ );
+ related_parts.add(inline_part);
+ }
+ }
+ }
+
+ if (!related_parts.is_empty) {
+ related_parts.insert(0, body_html);
+ GMime.Object? related_part =
+ coalesce_related(related_parts, "text/html");
+ if (related_part != null)
+ body_html = related_part;
+ }
+
body_parts.add(body_html);
+ }
+
GMime.Object? body_part = coalesce_parts(body_parts, "alternative");
if (body_part != null)
main_parts.add(body_part);
-
+
Gee.List<GMime.Object> attachment_parts = new Gee.LinkedList<GMime.Object>();
- foreach (File attachment_file in email.attachment_files) {
- GMime.Object? attachment_part = get_attachment_part(attachment_file);
+ foreach (File file in email.attached_files) {
+ GMime.Object? attachment_part = get_file_part(
+ file, Geary.Mime.DispositionType.ATTACHMENT
+ );
if (attachment_part != null)
attachment_parts.add(attachment_part);
}
@@ -235,7 +266,16 @@ public class Geary.RFC822.Message : BaseObject {
message.set_mime_part(original_mime_part);
}
-
+
+ private GMime.Object? coalesce_related(Gee.List<GMime.Object> parts,
+ string type) {
+ GMime.Object? part = coalesce_parts(parts, "related");
+ if (parts.size > 1) {
+ part.set_header("Type", type);
+ }
+ return part;
+ }
+
private GMime.Object? coalesce_parts(Gee.List<GMime.Object> parts, string subtype) {
if (parts.size == 0) {
return null;
@@ -248,11 +288,12 @@ public class Geary.RFC822.Message : BaseObject {
return multipart;
}
}
-
- private GMime.Part? get_attachment_part(File file) {
+
+ private GMime.Part? get_file_part(File file,
+ Geary.Mime.DispositionType disposition) {
if (!file.query_exists())
return null;
-
+
FileInfo file_info;
try {
file_info = file.query_info(FileAttribute.STANDARD_CONTENT_TYPE, FileQueryInfoFlags.NONE);
@@ -260,12 +301,12 @@ public class Geary.RFC822.Message : BaseObject {
debug("Error querying info from file: %s", err.message);
return null;
}
-
+
GMime.Part part = new GMime.Part();
- part.set_disposition("attachment");
+ part.set_disposition(disposition.serialize());
part.set_filename(file.get_basename());
part.set_content_type(new GMime.ContentType.from_string(file_info.get_content_type()));
-
+
// This encoding is the initial encoding of the stream.
GMime.StreamGIO stream = new GMime.StreamGIO(file);
stream.set_owner(false);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]