diff --git a/src/engine/imap-db/imap-db-folder.vala b/src/engine/imap-db/imap-db-folder.vala index f4ed001b..615d8194 100644 --- a/src/engine/imap-db/imap-db-folder.vala +++ b/src/engine/imap-db/imap-db-folder.vala @@ -276,6 +276,7 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics { public async Gee.Map create_or_merge_email_async(Gee.Collection emails, bool update_totals, + ContactHarvester harvester, GLib.Cancellable? cancellable) throws GLib.Error { Gee.HashMap results = new Gee.HashMap(); @@ -332,6 +333,10 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics { yield Scheduler.sleep_ms_async(100); } + yield harvester.harvest_from_email( + results.keys, cancellable + ); + return results; } diff --git a/src/engine/imap-engine/imap-engine-minimal-folder.vala b/src/engine/imap-engine/imap-engine-minimal-folder.vala index bbe2bded..f1c2c80b 100644 --- a/src/engine/imap-engine/imap-engine-minimal-folder.vala +++ b/src/engine/imap-engine/imap-engine-minimal-folder.vala @@ -66,6 +66,7 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport internal ReplayQueue? replay_queue { get; private set; default = null; } internal EmailPrefetcher email_prefetcher { get; private set; } + internal ContactHarvester harvester { get; private set; } private weak GenericAccount _account; private Geary.AggregatedFolderProperties _properties = @@ -124,6 +125,7 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport this._special_folder_type = special_folder_type; this._properties.add(local_folder.get_properties()); this.email_prefetcher = new EmailPrefetcher(this); + update_harvester(); this.remote_open_timer = new TimeoutManager.seconds( FORCE_OPEN_REMOTE_TIMEOUT_SEC, () => { this.open_remote_session.begin(); } @@ -181,6 +183,7 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport _special_folder_type = new_type; if (old_type != new_type) notify_special_folder_type_changed(old_type, new_type); + update_harvester(); } /** {@inheritDoc} */ @@ -535,7 +538,7 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport // also Issue #213. Gee.Map? created_or_merged = yield local_folder.create_or_merge_email_async( - to_create, false, cancellable + to_create, false, this.harvester, cancellable ); assert(created_or_merged != null); @@ -1521,6 +1524,14 @@ private class Geary.ImapEngine.MinimalFolder : Geary.Folder, Geary.FolderSupport } } + private void update_harvester() { + this.harvester = new ContactHarvesterImpl( + this.account.contact_store, + this.special_folder_type, + this.account.information.sender_mailboxes + ); + } + private void on_refresh_unseen() { // We queue an account operation since the folder itself is // closed and hence does not have a connection to use for it. diff --git a/src/engine/imap-engine/replay-ops/imap-engine-abstract-list-email.vala b/src/engine/imap-engine/replay-ops/imap-engine-abstract-list-email.vala index 59ce9468..0d04eb47 100644 --- a/src/engine/imap-engine/replay-ops/imap-engine-abstract-list-email.vala +++ b/src/engine/imap-engine/replay-ops/imap-engine-abstract-list-email.vala @@ -23,18 +23,23 @@ private abstract class Geary.ImapEngine.AbstractListEmail : Geary.ImapEngine.Sen // OUT public Gee.Set created_ids = new Gee.HashSet(); + private ContactHarvester harvester; + + public RemoteBatchOperation(Imap.FolderSession remote, ImapDB.Folder local, Imap.MessageSet msg_set, Geary.Email.Field unfulfilled_fields, Geary.Email.Field required_fields, - bool update_unread) { + bool update_unread, + ContactHarvester harvester) { this.remote = remote; this.local = local; this.msg_set = msg_set; this.unfulfilled_fields = unfulfilled_fields; this.required_fields = required_fields; this.update_unread = update_unread; + this.harvester = harvester; } public override async Object? execute_async(Cancellable? cancellable) throws Error { @@ -50,8 +55,10 @@ private abstract class Geary.ImapEngine.AbstractListEmail : Geary.ImapEngine.Sen yield this.local.create_or_merge_email_async( list, this.update_unread, + this.harvester, cancellable ); + for (int ctr = 0; ctr < list.size; ctr++) { Geary.Email email = list[ctr]; @@ -179,7 +186,8 @@ private abstract class Geary.ImapEngine.AbstractListEmail : Geary.ImapEngine.Sen msg_set, unfulfilled_fields, required_fields, - !this.flags.is_any_set(NO_UNREAD_UPDATE) + !this.flags.is_any_set(NO_UNREAD_UPDATE), + this.owner.harvester ); batch.add(remote_op); } diff --git a/src/engine/imap-engine/replay-ops/imap-engine-create-email.vala b/src/engine/imap-engine/replay-ops/imap-engine-create-email.vala index 2f9a325d..ca5e29c9 100644 --- a/src/engine/imap-engine/replay-ops/imap-engine-create-email.vala +++ b/src/engine/imap-engine/replay-ops/imap-engine-create-email.vala @@ -60,6 +60,7 @@ private class Geary.ImapEngine.CreateEmail : Geary.ImapEngine.SendReplayOperatio yield this.engine.local_folder.create_or_merge_email_async( Geary.iterate(created).to_array_list(), true, + this.engine.harvester, this.cancellable ); if (results.size > 0) { diff --git a/src/engine/imap-engine/replay-ops/imap-engine-fetch-email.vala b/src/engine/imap-engine/replay-ops/imap-engine-fetch-email.vala index 79688792..50584097 100644 --- a/src/engine/imap-engine/replay-ops/imap-engine-fetch-email.vala +++ b/src/engine/imap-engine/replay-ops/imap-engine-fetch-email.vala @@ -116,7 +116,7 @@ private class Geary.ImapEngine.FetchEmail : Geary.ImapEngine.SendReplayOperation Gee.Map created_or_merged = yield this.engine.local_folder.create_or_merge_email_async( - list, true, this.cancellable + list, true, this.engine.harvester, this.cancellable ); Geary.Email email = list[0]; diff --git a/src/engine/imap-engine/replay-ops/imap-engine-replay-append.vala b/src/engine/imap-engine/replay-ops/imap-engine-replay-append.vala index 1c2479b1..2ed09438 100644 --- a/src/engine/imap-engine/replay-ops/imap-engine-replay-append.vala +++ b/src/engine/imap-engine/replay-ops/imap-engine-replay-append.vala @@ -91,7 +91,7 @@ private class Geary.ImapEngine.ReplayAppend : Geary.ImapEngine.ReplayOperation { // could mean created or simply a known email associated with this folder) Gee.Map created_or_merged = yield this.owner.local_folder.create_or_merge_email_async( - list, true, this.cancellable + list, true, this.owner.harvester, this.cancellable ); foreach (Geary.Email email in created_or_merged.keys) { // true means created diff --git a/test/engine/common/common-contact-harvester-mock.vala b/test/engine/common/common-contact-harvester-mock.vala new file mode 100644 index 00000000..d949a934 --- /dev/null +++ b/test/engine/common/common-contact-harvester-mock.vala @@ -0,0 +1,15 @@ +/* + * 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. + */ + +internal class Geary.MockContactHarvester : ContactHarvester, GLib.Object { + + public async void harvest_from_email(Gee.Collection messages, + GLib.Cancellable? cancellable) + throws GLib.Error { + } + +} diff --git a/test/engine/imap-db/imap-db-folder-test.vala b/test/engine/imap-db/imap-db-folder-test.vala index ce32de7c..df890003 100644 --- a/test/engine/imap-db/imap-db-folder-test.vala +++ b/test/engine/imap-db/imap-db-folder-test.vala @@ -83,6 +83,7 @@ class Geary.ImapDB.FolderTest : TestCase { this.folder.create_or_merge_email_async.begin( Collection.single(mock), true, + new MockContactHarvester(), null, (obj, ret) => { async_complete(ret); } ); @@ -102,6 +103,7 @@ class Geary.ImapDB.FolderTest : TestCase { this.folder.create_or_merge_email_async.begin( Collection.single(mock), true, + new MockContactHarvester(), null, (obj, ret) => { async_complete(ret); } ); @@ -121,6 +123,7 @@ class Geary.ImapDB.FolderTest : TestCase { this.folder.create_or_merge_email_async.begin( Collection.single(mock), false, + new MockContactHarvester(), null, (obj, ret) => { async_complete(ret); } ); @@ -150,6 +153,7 @@ class Geary.ImapDB.FolderTest : TestCase { this.folder.create_or_merge_email_async.begin( Collection.single(mock), true, + new MockContactHarvester(), null, (obj, ret) => { async_complete(ret); } ); @@ -200,6 +204,7 @@ class Geary.ImapDB.FolderTest : TestCase { this.folder.create_or_merge_email_async.begin( Collection.single(test), true, + new MockContactHarvester(), null, (obj, ret) => { async_complete(ret); } ); @@ -233,6 +238,7 @@ class Geary.ImapDB.FolderTest : TestCase { this.folder.create_or_merge_email_async.begin( Collection.single(test), true, + new MockContactHarvester(), null, (obj, ret) => { async_complete(ret); } ); diff --git a/test/meson.build b/test/meson.build index 1563a5fe..9bf86e1b 100644 --- a/test/meson.build +++ b/test/meson.build @@ -20,6 +20,7 @@ geary_test_engine_sources = [ 'engine/api/geary-email-properties-mock.vala', 'engine/api/geary-folder-mock.vala', 'engine/api/geary-folder-properties-mock.vala', + 'engine/common/common-contact-harvester-mock.vala', 'engine/api/geary-account-information-test.vala', 'engine/api/geary-attachment-test.vala',