diff --git a/po/POTFILES.in b/po/POTFILES.in index 6fc3bc1b..58fd048c 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -115,6 +115,7 @@ src/engine/api/geary-contact.vala src/engine/api/geary-credentials-mediator.vala src/engine/api/geary-credentials.vala src/engine/api/geary-email-flags.vala +src/engine/api/geary-email-header-set.vala src/engine/api/geary-email-identifier.vala src/engine/api/geary-email-properties.vala src/engine/api/geary-email.vala diff --git a/src/engine/api/geary-email-header-set.vala b/src/engine/api/geary-email-header-set.vala new file mode 100644 index 00000000..ea4a885b --- /dev/null +++ b/src/engine/api/geary-email-header-set.vala @@ -0,0 +1,46 @@ +/* + * Copyright 2019 Michael Gratton + * + * This software is licensed under the GNU Lesser General Public License + * (version 2.1 or later). See the COPYING file in this distribution. + */ + +/** + * Denotes an object that has a set of RFC822 headers. + */ +public interface Geary.EmailHeaderSet : BaseObject { + + /** Value of the RFC 822 Date header. */ + public abstract RFC822.Date? date { get; protected set; } + + /** Value of the RFC 822 From header, an originator field. */ + public abstract RFC822.MailboxAddresses? from { get; protected set; } + + /** Value of the RFC 822 Sender header, an originator field. */ + public abstract RFC822.MailboxAddress? sender { get; protected set; } + + /** Value of the RFC 822 Reply-To header, an originator field. */ + public abstract RFC822.MailboxAddresses? reply_to { get; protected set; } + + /** Value of the RFC 822 To header, a recipient field. */ + public abstract RFC822.MailboxAddresses? to { get; protected set; } + + /** Value of the RFC 822 Cc header, a recipient field. */ + public abstract RFC822.MailboxAddresses? cc { get; protected set; } + + /** Value of the RFC 822 Bcc header, a recipient field. */ + public abstract RFC822.MailboxAddresses? bcc { get; protected set; } + + /** Value of the RFC 822 Message-Id header, a reference field. */ + public abstract RFC822.MessageID? message_id { get; protected set; } + + /** Value of the RFC 822 In-Reply-To header, a reference field. */ + public abstract RFC822.MessageIDList? in_reply_to { get; protected set; } + + /** Value of the RFC 822 References header, a reference field. */ + public abstract RFC822.MessageIDList? references { get; protected set; } + + /** Value of the RFC 822 Subject header. */ + public abstract RFC822.Subject? subject { get; protected set; } + +} diff --git a/src/engine/api/geary-email.vala b/src/engine/api/geary-email.vala index 4242faf1..e22d5762 100644 --- a/src/engine/api/geary-email.vala +++ b/src/engine/api/geary-email.vala @@ -26,7 +26,7 @@ * property, and if the currently loaded fields are not sufficient, * then additional fields can be loaded via a folder. */ -public class Geary.Email : BaseObject { +public class Geary.Email : BaseObject, EmailHeaderSet { /** * The maximum expected length of message body preview text. @@ -183,42 +183,124 @@ public class Geary.Email : BaseObject { */ public Geary.EmailIdentifier id { get; private set; } - // DATE - public Geary.RFC822.Date? date { get; private set; default = null; } + /** + * {@inheritDoc} + * + * Value will be valid if {@link Field.DATE} is set. + */ + public Geary.RFC822.Date? date { get; protected set; default = null; } - // ORIGINATORS - public Geary.RFC822.MailboxAddresses? from { get; private set; default = null; } - public Geary.RFC822.MailboxAddress? sender { get; private set; default = null; } - public Geary.RFC822.MailboxAddresses? reply_to { get; private set; default = null; } + /** + * {@inheritDoc} + * + * Value will be valid if {@link Field.ORIGINATORS} is set. + */ + public Geary.RFC822.MailboxAddresses? from { get; protected set; default = null; } - // RECEIVERS - public Geary.RFC822.MailboxAddresses? to { get; private set; default = null; } - public Geary.RFC822.MailboxAddresses? cc { get; private set; default = null; } - public Geary.RFC822.MailboxAddresses? bcc { get; private set; default = null; } + /** + * {@inheritDoc} + * + * Value will be valid if {@link Field.ORIGINATORS} is set. + */ + public Geary.RFC822.MailboxAddress? sender { get; protected set; default = null; } - // REFERENCES - public Geary.RFC822.MessageID? message_id { get; private set; default = null; } - public Geary.RFC822.MessageIDList? in_reply_to { get; private set; default = null; } - public Geary.RFC822.MessageIDList? references { get; private set; default = null; } + /** + * {@inheritDoc} + * + * Value will be valid if {@link Field.ORIGINATORS} is set. + */ + public Geary.RFC822.MailboxAddresses? reply_to { get; protected set; default = null; } - // SUBJECT - public Geary.RFC822.Subject? subject { get; private set; default = null; } + /** + * {@inheritDoc} + * + * Value will be valid if {@link Field.RECEIVERS} is set. + */ + public Geary.RFC822.MailboxAddresses? to { get; protected set; default = null; } - // HEADER - public RFC822.Header? header { get; private set; default = null; } + /** + * {@inheritDoc} + * + * Value will be valid if {@link Field.RECEIVERS} is set. + */ + public Geary.RFC822.MailboxAddresses? cc { get; protected set; default = null; } - // BODY + /** + * {@inheritDoc} + * + * Value will be valid if {@link Field.RECEIVERS} is set. + */ + public Geary.RFC822.MailboxAddresses? bcc { get; protected set; default = null; } + + /** + * {@inheritDoc} + * + * Value will be valid if {@link Field.REFERENCES} is set. + */ + public Geary.RFC822.MessageID? message_id { get; protected set; default = null; } + + /** + * {@inheritDoc} + * + * Value will be valid if {@link Field.REFERENCES} is set. + */ + public Geary.RFC822.MessageIDList? in_reply_to { get; protected set; default = null; } + + /** + * {@inheritDoc} + * + * Value will be valid if {@link Field.REFERENCES} is set. + */ + public Geary.RFC822.MessageIDList? references { get; protected set; default = null; } + + /** + * {@inheritDoc} + * + * Value will be valid if {@link Field.SUBJECT} is set. + */ + public Geary.RFC822.Subject? subject { get; protected set; default = null; } + + /** + * {@inheritDoc} + * + * Value will be valid if {@link Field.HEADER} is set. + */ + public RFC822.Header? header { get; protected set; default = null; } + + /** + * The complete RFC 822 message body. + * + * Value will be valid if {@link Field.BODY} is set. + */ public RFC822.Text? body { get; private set; default = null; } + + /** + * MIME multipart body parts. + * + * Value will be valid if {@link Field.BODY} is set. + */ public Gee.List attachments { get; private set; default = new Gee.ArrayList(); } - // PROPERTIES - public Geary.EmailProperties? properties { get; private set; default = null; } - - // PREVIEW + /** + * A plain text prefix of the email's message body. + * + * Value will be valid if {@link Field.PREVIEW} is set. + */ public RFC822.PreviewText? preview { get; private set; default = null; } - // FLAGS + /** + * Set of immutable properties for the email. + * + * Value will be valid if {@link Field.PROPERTIES} is set. + */ + public Geary.EmailProperties? properties { get; private set; default = null; } + + /** + * Set of mutable flags for the email. + * + * Value will be valid if {@link Field.FLAGS} is set. + */ public Geary.EmailFlags? email_flags { get; private set; default = null; } /** diff --git a/src/engine/meson.build b/src/engine/meson.build index 3f5bfad9..08cc1ebe 100644 --- a/src/engine/meson.build +++ b/src/engine/meson.build @@ -16,6 +16,7 @@ geary_engine_vala_sources = files( 'api/geary-credentials.vala', 'api/geary-credentials-mediator.vala', 'api/geary-email-flags.vala', + 'api/geary-email-header-set.vala', 'api/geary-email-identifier.vala', 'api/geary-email-properties.vala', 'api/geary-email.vala', diff --git a/src/engine/rfc822/rfc822-message.vala b/src/engine/rfc822/rfc822-message.vala index 3afdec4e..9bbfb5a0 100644 --- a/src/engine/rfc822/rfc822-message.vala +++ b/src/engine/rfc822/rfc822-message.vala @@ -13,7 +13,7 @@ * representation of an email message, and contain no information * other than what RFC-822 and its successor RFC documents specify. */ -public class Geary.RFC822.Message : BaseObject { +public class Geary.RFC822.Message : BaseObject, EmailHeaderSet { /** * Callback for including non-text MIME entities in message bodies. @@ -35,18 +35,46 @@ public class Geary.RFC822.Message : BaseObject { private const string HEADER_MAILER = "X-Mailer"; private const string HEADER_BCC = "Bcc"; - // Internal note: If a field is added here, it *must* be set in stock_from_gmime(). - public RFC822.MailboxAddress? sender { get; private set; default = null; } - public RFC822.MailboxAddresses? from { get; private set; default = null; } - public RFC822.MailboxAddresses? to { get; private set; default = null; } - public RFC822.MailboxAddresses? cc { get; private set; default = null; } - public RFC822.MailboxAddresses? bcc { get; private set; default = null; } - public RFC822.MailboxAddresses? reply_to { get; private set; default = null; } - public RFC822.MessageIDList? in_reply_to { get; private set; default = null; } - public RFC822.MessageIDList? references { get; private set; default = null; } - public RFC822.Subject? subject { get; private set; default = null; } - public string? mailer { get; private set; default = null; } - public Geary.RFC822.Date? date { get; private set; default = null; } + // Internal note: If a header field is added here, it *must* be + // set in stock_from_gmime(). + + /** {@inheritDoc} */ + + /** {@inheritDoc} */ + public RFC822.MailboxAddress? sender { get; protected set; default = null; } + + /** {@inheritDoc} */ + public RFC822.MailboxAddresses? from { get; protected set; default = null; } + + /** {@inheritDoc} */ + public RFC822.MailboxAddresses? to { get; protected set; default = null; } + + /** {@inheritDoc} */ + public RFC822.MailboxAddresses? cc { get; protected set; default = null; } + + /** {@inheritDoc} */ + public RFC822.MailboxAddresses? bcc { get; protected set; default = null; } + + /** {@inheritDoc} */ + public RFC822.MailboxAddresses? reply_to { get; protected set; default = null; } + + /** {@inheritDoc} */ + public RFC822.MessageID? message_id { get; protected set; default = null; } + + /** {@inheritDoc} */ + public RFC822.MessageIDList? in_reply_to { get; protected set; default = null; } + + /** {@inheritDoc} */ + public RFC822.MessageIDList? references { get; protected set; default = null; } + + /** {@inheritDoc} */ + public RFC822.Subject? subject { get; protected set; default = null; } + + /** {@inheritDoc} */ + public Geary.RFC822.Date? date { get; protected set; default = null; } + + /** Value of the X-Mailer header. */ + public string? mailer { get; protected set; default = null; } private GMime.Message message; @@ -57,6 +85,7 @@ public class Geary.RFC822.Message : BaseObject { private Memory.Buffer? body_buffer = null; private size_t? body_offset = null; + public Message(Full full) throws RFC822Error { GMime.Parser parser = new GMime.Parser.with_stream(Utils.create_stream_mem(full.buffer)); @@ -110,8 +139,10 @@ public class Geary.RFC822.Message : BaseObject { // supports a list of addresses message.set_sender(this.from.to_rfc822_string()); message.set_date_as_string(this.date.serialize()); - if (message_id != null) + if (message_id != null) { + this.message_id = new MessageID(message_id); message.set_message_id(message_id); + } // Optional headers if (email.to != null) { @@ -378,7 +409,7 @@ public class Geary.RFC822.Message : BaseObject { email.set_send_date(date); email.set_originators(from, sender, reply_to); email.set_receivers(to, cc, bcc); - email.set_full_references(null, in_reply_to, references); + email.set_full_references(message_id, in_reply_to, references); email.set_message_subject(subject); email.set_message_body(new Geary.RFC822.Text(new Geary.Memory.OffsetBuffer( body_buffer, body_offset))); @@ -778,6 +809,10 @@ public class Geary.RFC822.Message : BaseObject { } break; + case "message-id": + this.message_id = new MessageID(value); + break; + case "in-reply-to": this.in_reply_to = append_message_id(this.in_reply_to, value); break;