Move SmtpOutbox impl out of ImapDB, rename to just Outbox

Outbox code now effectively does not depend on ImapDB, and no longer
contains any SMTP code, so this moves it to it's own top-level engine
package and removes SMTP from its name.
This commit is contained in:
Michael Gratton 2018-11-18 23:46:41 +11:00 committed by Michael James Gratton
parent 41402c9108
commit 3dc60793c8
13 changed files with 159 additions and 128 deletions

View file

@ -230,11 +230,6 @@ src/engine/imap-db/imap-db-folder.vala
src/engine/imap-db/imap-db-gc.vala
src/engine/imap-db/imap-db-message-addresses.vala
src/engine/imap-db/imap-db-message-row.vala
src/engine/imap-db/outbox/smtp-outbox-email-identifier.vala
src/engine/imap-db/outbox/smtp-outbox-email-properties.vala
src/engine/imap-db/outbox/smtp-outbox-folder-properties.vala
src/engine/imap-db/outbox/smtp-outbox-folder-root.vala
src/engine/imap-db/outbox/smtp-outbox-folder.vala
src/engine/imap-db/search/imap-db-search-email-identifier.vala
src/engine/imap-db/search/imap-db-search-folder-properties.vala
src/engine/imap-db/search/imap-db-search-folder-root.vala
@ -359,6 +354,11 @@ src/engine/nonblocking/nonblocking-mutex.vala
src/engine/nonblocking/nonblocking-queue.vala
src/engine/nonblocking/nonblocking-reporting-semaphore.vala
src/engine/nonblocking/nonblocking-variants.vala
src/engine/outbox/outbox-email-identifier.vala
src/engine/outbox/outbox-email-properties.vala
src/engine/outbox/outbox-folder-properties.vala
src/engine/outbox/outbox-folder-root.vala
src/engine/outbox/outbox-folder.vala
src/engine/rfc822/rfc822-error.vala
src/engine/rfc822/rfc822-gmime-filter-blockquotes.vala
src/engine/rfc822/rfc822-gmime-filter-flowed.vala

View file

@ -1,24 +0,0 @@
/* Copyright 2016 Software Freedom Conservancy Inc.
*
* This software is licensed under the GNU Lesser General Public License
* (version 2.1 or later). See the COPYING file in this distribution.
*/
private class Geary.SmtpOutboxEmailIdentifier : Geary.EmailIdentifier {
public int64 ordering { get; private set; }
public SmtpOutboxEmailIdentifier(int64 message_id, int64 ordering) {
base ("SmtpOutboxEmailIdentifer:%s".printf(message_id.to_string()));
this.ordering = ordering;
}
public override int natural_sort_comparator(Geary.EmailIdentifier o) {
SmtpOutboxEmailIdentifier? other = o as SmtpOutboxEmailIdentifier;
if (other == null)
return 1;
return (int) (ordering - other.ordering).clamp(-1, 1);
}
}

View file

@ -1,16 +0,0 @@
/* Copyright 2016 Software Freedom Conservancy Inc.
*
* This software is licensed under the GNU Lesser General Public License
* (version 2.1 or later). See the COPYING file in this distribution.
*/
private class Geary.SmtpOutboxEmailProperties : Geary.EmailProperties {
public SmtpOutboxEmailProperties(DateTime date_received, long total_bytes) {
base(date_received, total_bytes);
}
public override string to_string() {
return "SmtpOutboxProperties";
}
}

View file

@ -1,16 +0,0 @@
/* Copyright 2016 Software Freedom Conservancy Inc.
*
* This software is licensed under the GNU Lesser General Public License
* (version 2.1 or later). See the COPYING file in this distribution.
*/
private class Geary.SmtpOutboxFolderProperties : Geary.FolderProperties {
public SmtpOutboxFolderProperties(int total, int unread) {
base (total, unread, Trillian.FALSE, Trillian.FALSE, Trillian.TRUE, true, false, false);
}
public void set_total(int total) {
this.email_total = total;
}
}

View file

@ -1,14 +0,0 @@
/* Copyright 2016 Software Freedom Conservancy Inc.
*
* This software is licensed under the GNU Lesser General Public License
* (version 2.1 or later). See the COPYING file in this distribution.
*/
private class Geary.SmtpOutboxFolderRoot : Geary.FolderRoot {
public const string MAGIC_BASENAME = "$GearyOutbox$";
public SmtpOutboxFolderRoot() {
base(MAGIC_BASENAME, false, false);
}
}

View file

@ -74,7 +74,7 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
this.imap.login_failed.connect(on_pool_login_failed);
this.smtp = new Smtp.ClientService(
config, config.smtp, new SmtpOutboxFolder(this, this.local)
config, config.smtp, new Outbox.Folder(this, this.local)
);
this.smtp.email_sent.connect(on_email_sent);
this.smtp.report_problem.connect(notify_report_problem);
@ -138,9 +138,7 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.Account {
// Create/load local folders
local_only.set(
new SmtpOutboxFolderRoot(), this.smtp.outbox
);
local_only.set(new Outbox.FolderRoot(), this.smtp.outbox);
this.search_folder = new_search_folder();
local_only.set(new ImapDB.SearchFolderRoot(), this.search_folder);

View file

@ -184,11 +184,6 @@ geary_engine_vala_sources = files(
'imap-db/search/imap-db-search-folder-root.vala',
'imap-db/search/imap-db-search-query.vala',
'imap-db/search/imap-db-search-term.vala',
'imap-db/outbox/smtp-outbox-email-identifier.vala',
'imap-db/outbox/smtp-outbox-email-properties.vala',
'imap-db/outbox/smtp-outbox-folder.vala',
'imap-db/outbox/smtp-outbox-folder-properties.vala',
'imap-db/outbox/smtp-outbox-folder-root.vala',
'imap-engine/imap-engine.vala',
'imap-engine/imap-engine-account-operation.vala',
@ -265,6 +260,12 @@ geary_engine_vala_sources = files(
'nonblocking/nonblocking-reporting-semaphore.vala',
'nonblocking/nonblocking-variants.vala',
'outbox/outbox-email-identifier.vala',
'outbox/outbox-email-properties.vala',
'outbox/outbox-folder.vala',
'outbox/outbox-folder-properties.vala',
'outbox/outbox-folder-root.vala',
'rfc822/rfc822.vala',
'rfc822/rfc822-error.vala',
'rfc822/rfc822-gmime-filter-flowed.vala',

View file

@ -0,0 +1,27 @@
/*
* Copyright 2016 Software Freedom Conservancy Inc.
*
* This software is licensed under the GNU Lesser General Public License
* (version 2.1 or later). See the COPYING file in this distribution.
*/
private class Geary.Outbox.EmailIdentifier : Geary.EmailIdentifier {
public int64 ordering { get; private set; }
public EmailIdentifier(int64 message_id, int64 ordering) {
base("Outbox.EmailIdentifier:%s".printf(message_id.to_string()));
this.ordering = ordering;
}
public override int natural_sort_comparator(Geary.EmailIdentifier o) {
EmailIdentifier? other = o as EmailIdentifier;
if (other == null) {
return 1;
}
return (int) (ordering - other.ordering).clamp(-1, 1);
}
}

View file

@ -0,0 +1,19 @@
/*
* Copyright 2016 Software Freedom Conservancy Inc.
*
* This software is licensed under the GNU Lesser General Public License
* (version 2.1 or later). See the COPYING file in this distribution.
*/
private class Geary.Outbox.EmailProperties : Geary.EmailProperties {
public EmailProperties(GLib.DateTime date_received, long total_bytes) {
base(date_received, total_bytes);
}
public override string to_string() {
return "Outbox.Properties";
}
}

View file

@ -0,0 +1,22 @@
/*
* Copyright 2016 Software Freedom Conservancy Inc.
*
* This software is licensed under the GNU Lesser General Public License
* (version 2.1 or later). See the COPYING file in this distribution.
*/
private class Geary.Outbox.FolderProperties : Geary.FolderProperties {
public FolderProperties(int total, int unread) {
base(
total, unread,
Trillian.FALSE, Trillian.FALSE, Trillian.TRUE,
true, false, false
);
}
public void set_total(int total) {
this.email_total = total;
}
}

View file

@ -0,0 +1,18 @@
/*
* Copyright 2016 Software Freedom Conservancy Inc.
*
* This software is licensed under the GNU Lesser General Public License
* (version 2.1 or later). See the COPYING file in this distribution.
*/
private class Geary.Outbox.FolderRoot : Geary.FolderRoot {
public const string MAGIC_BASENAME = "$GearyOutbox$";
public FolderRoot() {
base(MAGIC_BASENAME, false, false);
}
}

View file

@ -9,7 +9,7 @@
/**
* Local folder for storing outgoing mail.
*/
private class Geary.SmtpOutboxFolder :
private class Geary.Outbox.Folder :
Geary.AbstractLocalFolder,
Geary.FolderSupport.Create,
Geary.FolderSupport.Mark,
@ -22,7 +22,7 @@ private class Geary.SmtpOutboxFolder :
public int64 ordering;
public bool sent;
public Memory.Buffer? message;
public SmtpOutboxEmailIdentifier outbox_id;
public EmailIdentifier outbox_id;
public OutboxRow(int64 id, int position, int64 ordering, bool sent, Memory.Buffer? message) {
assert(position >= 1);
@ -33,16 +33,18 @@ private class Geary.SmtpOutboxFolder :
this.sent = sent;
this.message = message;
outbox_id = new SmtpOutboxEmailIdentifier(id, ordering);
outbox_id = new EmailIdentifier(id, ordering);
}
}
public override Account account { get { return this._account; } }
public override FolderProperties properties { get { return _properties; } }
public override Geary.FolderProperties properties {
get { return _properties; }
}
private SmtpOutboxFolderRoot _path = new SmtpOutboxFolderRoot();
private FolderRoot _path = new FolderRoot();
public override FolderPath path {
get {
return _path;
@ -58,13 +60,13 @@ private class Geary.SmtpOutboxFolder :
private weak Account _account;
private weak ImapDB.Account local;
private Db.Database? db = null;
private SmtpOutboxFolderProperties _properties = new SmtpOutboxFolderProperties(0, 0);
private FolderProperties _properties = new FolderProperties(0, 0);
private int64 next_ordering = 0;
// Requires the Database from the get-go because it runs a background task that access it
// whether open or not
public SmtpOutboxFolder(Account account, ImapDB.Account local) {
public Folder(Account account, ImapDB.Account local) {
this._account = account;
this.local = local;
}
@ -88,11 +90,11 @@ private class Geary.SmtpOutboxFolder :
return closed;
}
public virtual async EmailIdentifier?
public virtual async Geary.EmailIdentifier?
create_email_async(RFC822.Message rfc822,
EmailFlags? flags,
DateTime? date_received,
EmailIdentifier? id = null,
Geary.EmailFlags? flags,
GLib.DateTime? date_received,
Geary.EmailIdentifier? id = null,
GLib.Cancellable? cancellable = null)
throws GLib.Error {
check_open();
@ -120,7 +122,7 @@ private class Geary.SmtpOutboxFolder :
// update properties
_properties.set_total(yield get_email_count_async(cancellable));
Gee.List<SmtpOutboxEmailIdentifier> list = new Gee.ArrayList<SmtpOutboxEmailIdentifier>();
Gee.List<EmailIdentifier> list = new Gee.ArrayList<EmailIdentifier>();
list.add(row.outbox_id);
notify_email_appended(list);
@ -131,17 +133,17 @@ private class Geary.SmtpOutboxFolder :
}
public virtual async void
mark_email_async(Gee.Collection<EmailIdentifier> to_mark,
EmailFlags? flags_to_add,
EmailFlags? flags_to_remove,
GLib.Cancellable? cancellable = null)
mark_email_async(Gee.Collection<Geary.EmailIdentifier> to_mark,
EmailFlags? flags_to_add,
EmailFlags? flags_to_remove,
GLib.Cancellable? cancellable = null)
throws GLib.Error {
check_open();
Gee.Map<EmailIdentifier,EmailFlags> changed =
new Gee.HashMap<EmailIdentifier,EmailFlags>();
Gee.Map<Geary.EmailIdentifier,EmailFlags> changed =
new Gee.HashMap<Geary.EmailIdentifier,EmailFlags>();
foreach (EmailIdentifier id in to_mark) {
SmtpOutboxEmailIdentifier? outbox_id = id as SmtpOutboxEmailIdentifier;
foreach (Geary.EmailIdentifier id in to_mark) {
EmailIdentifier? outbox_id = id as EmailIdentifier;
if (outbox_id != null) {
yield db.exec_transaction_async(Db.TransactionType.WR, (cx) => {
do_mark_email_as_sent(cx, outbox_id, cancellable);
@ -167,7 +169,7 @@ private class Geary.SmtpOutboxFolder :
foreach (Geary.EmailIdentifier id in email_ids) {
// ignore anything not belonging to the outbox, but also don't report it as removed
// either
SmtpOutboxEmailIdentifier? outbox_id = id as SmtpOutboxEmailIdentifier;
EmailIdentifier? outbox_id = id as EmailIdentifier;
if (outbox_id == null)
continue;
@ -193,12 +195,16 @@ private class Geary.SmtpOutboxFolder :
}
}
public override async Gee.List<Geary.Email>? list_email_by_id_async(
Geary.EmailIdentifier? _initial_id, int count, Geary.Email.Field required_fields,
Geary.Folder.ListFlags flags, Cancellable? cancellable = null) throws Error {
public override async Gee.List<Email>?
list_email_by_id_async(Geary.EmailIdentifier? _initial_id,
int count,
Geary.Email.Field required_fields,
Geary.Folder.ListFlags flags,
GLib.Cancellable? cancellable = null)
throws GLib.Error {
check_open();
SmtpOutboxEmailIdentifier? initial_id = _initial_id as SmtpOutboxEmailIdentifier;
EmailIdentifier? initial_id = _initial_id as EmailIdentifier;
if (_initial_id != null && initial_id == null) {
throw new EngineError.BAD_PARAMETERS("EmailIdentifier %s not for Outbox",
initial_id.to_string());
@ -276,15 +282,18 @@ private class Geary.SmtpOutboxFolder :
return list;
}
public override async Gee.List<Geary.Email>? list_email_by_sparse_id_async(
Gee.Collection<Geary.EmailIdentifier> ids, Geary.Email.Field required_fields,
Geary.Folder.ListFlags flags, Cancellable? cancellable = null) throws Error {
public override async Gee.List<Geary.Email>?
list_email_by_sparse_id_async(Gee.Collection<Geary.EmailIdentifier> ids,
Geary.Email.Field required_fields,
Geary.Folder.ListFlags flags,
GLib.Cancellable? cancellable = null)
throws GLib.Error {
check_open();
Gee.List<Geary.Email> list = new Gee.ArrayList<Geary.Email>();
yield db.exec_transaction_async(Db.TransactionType.RO, (cx) => {
foreach (Geary.EmailIdentifier id in ids) {
SmtpOutboxEmailIdentifier? outbox_id = id as SmtpOutboxEmailIdentifier;
EmailIdentifier? outbox_id = id as EmailIdentifier;
if (outbox_id == null)
throw new EngineError.BAD_PARAMETERS("%s is not outbox EmailIdentifier", id.to_string());
@ -303,7 +312,8 @@ private class Geary.SmtpOutboxFolder :
public override async Gee.Map<Geary.EmailIdentifier, Geary.Email.Field>?
list_local_email_fields_async(Gee.Collection<Geary.EmailIdentifier> ids,
Cancellable? cancellable = null) throws Error {
GLib.Cancellable? cancellable = null)
throws GLib.Error {
check_open();
Gee.Map<Geary.EmailIdentifier, Geary.Email.Field> map = new Gee.HashMap<
@ -312,7 +322,7 @@ private class Geary.SmtpOutboxFolder :
Db.Statement stmt = cx.prepare(
"SELECT id FROM SmtpOutboxTable WHERE ordering=?");
foreach (Geary.EmailIdentifier id in ids) {
SmtpOutboxEmailIdentifier? outbox_id = id as SmtpOutboxEmailIdentifier;
EmailIdentifier? outbox_id = id as EmailIdentifier;
if (outbox_id == null)
throw new EngineError.BAD_PARAMETERS("%s is not outbox EmailIdentifier", id.to_string());
@ -331,12 +341,15 @@ private class Geary.SmtpOutboxFolder :
return (map.size > 0) ? map : null;
}
public override async Geary.Email fetch_email_async(Geary.EmailIdentifier id,
Geary.Email.Field required_fields, Geary.Folder.ListFlags flags,
Cancellable? cancellable = null) throws Error {
public override async Email
fetch_email_async(Geary.EmailIdentifier id,
Geary.Email.Field required_fields,
Geary.Folder.ListFlags flags,
GLib.Cancellable? cancellable = null)
throws GLib.Error {
check_open();
SmtpOutboxEmailIdentifier? outbox_id = id as SmtpOutboxEmailIdentifier;
EmailIdentifier? outbox_id = id as EmailIdentifier;
if (outbox_id == null)
throw new EngineError.BAD_PARAMETERS("%s is not outbox EmailIdentifier", id.to_string());
@ -354,14 +367,14 @@ private class Geary.SmtpOutboxFolder :
}
internal async void
add_to_containing_folders_async(Gee.Collection<EmailIdentifier> ids,
Gee.MultiMap<EmailIdentifier,FolderPath> map,
add_to_containing_folders_async(Gee.Collection<Geary.EmailIdentifier> ids,
Gee.MultiMap<Geary.EmailIdentifier,FolderPath> map,
GLib.Cancellable? cancellable)
throws GLib.Error {
check_open();
yield db.exec_transaction_async(Db.TransactionType.RO, (cx, cancellable) => {
foreach (Geary.EmailIdentifier id in ids) {
SmtpOutboxEmailIdentifier? outbox_id = id as SmtpOutboxEmailIdentifier;
EmailIdentifier? outbox_id = id as EmailIdentifier;
if (outbox_id == null)
continue;
@ -387,8 +400,11 @@ private class Geary.SmtpOutboxFolder :
RFC822.Message message = new RFC822.Message.from_buffer(row.message);
email = message.get_email(row.outbox_id);
// TODO: Determine message's total size (header + body) to store in Properties.
email.set_email_properties(new SmtpOutboxEmailProperties(new DateTime.now_local(), -1));
// TODO: Determine message's total size (header + body) to
// store in Properties.
email.set_email_properties(
new EmailProperties(new DateTime.now_local(), -1)
);
Geary.EmailFlags flags = new Geary.EmailFlags();
if (row.sent)
flags.add(Geary.EmailFlags.OUTBOX_SENT);
@ -476,7 +492,7 @@ private class Geary.SmtpOutboxFolder :
}
private void do_mark_email_as_sent(Db.Connection cx,
SmtpOutboxEmailIdentifier id,
EmailIdentifier id,
Cancellable? cancellable)
throws Error {
Db.Statement stmt = cx.prepare("UPDATE SmtpOutboxTable SET sent = 1 WHERE ordering = ?");
@ -485,7 +501,7 @@ private class Geary.SmtpOutboxFolder :
stmt.exec(cancellable);
}
private bool do_remove_email(Db.Connection cx, SmtpOutboxEmailIdentifier id, Cancellable? cancellable)
private bool do_remove_email(Db.Connection cx, EmailIdentifier id, Cancellable? cancellable)
throws Error {
Db.Statement stmt = cx.prepare("DELETE FROM SmtpOutboxTable WHERE ordering=?");
stmt.bind_int64(0, id.ordering);

View file

@ -28,7 +28,7 @@ internal class Geary.Smtp.ClientService : Geary.ClientService {
/** Folder used for storing and retrieving queued mail. */
public SmtpOutboxFolder outbox { get; private set; }
public Outbox.Folder outbox { get; private set; }
/** Progress monitor indicating when email is being sent. */
public ProgressMonitor sending_monitor {
@ -52,7 +52,7 @@ internal class Geary.Smtp.ClientService : Geary.ClientService {
public ClientService(AccountInformation account,
ServiceInformation service,
SmtpOutboxFolder outbox) {
Outbox.Folder outbox) {
base(account, service);
this.outbox = outbox;
}