Skip to content

Commit 832b363

Browse files
authored
Improved outlook online search even more and removed redundant methods from ChangeProcessor (#586)
1 parent cf8f1ec commit 832b363

File tree

2 files changed

+31
-49
lines changed

2 files changed

+31
-49
lines changed

Wino.Core/Integration/Processors/DefaultChangeProcessor.cs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,6 @@ public interface IDefaultChangeProcessor
4040
Task<bool> MapLocalDraftAsync(Guid accountId, Guid localDraftCopyUniqueId, string newMailCopyId, string newDraftId, string newThreadId);
4141
Task UpdateFolderLastSyncDateAsync(Guid folderId);
4242
Task UpdateRemoteAliasInformationAsync(MailAccount account, List<RemoteAccountAlias> remoteAccountAliases);
43-
44-
/// <summary>
45-
/// Interrupted initial synchronization may cause downloaded mails to be saved in the database twice.
46-
/// Since downloading mime is costly in Outlook, we need to check if the actual copy of the message has been saved before.
47-
/// This is also used in online search to prevent duplicate mails.
48-
/// </summary>
49-
/// <param name="messageId">MailCopyId of the message.</param>
50-
/// <returns>Whether mail exists or not.</returns>
51-
Task<bool> IsMailExistsAsync(string messageId);
52-
5343
// Calendar
5444
Task<List<AccountCalendar>> GetAccountCalendarsAsync(Guid accountId);
5545

@@ -60,7 +50,6 @@ public interface IDefaultChangeProcessor
6050
Task UpdateAccountCalendarAsync(AccountCalendar accountCalendar);
6151

6252
Task UpdateCalendarDeltaSynchronizationToken(Guid calendarId, string deltaToken);
63-
Task<MailCopy> GetMailCopyAsync(string mailCopyId);
6453
Task<List<MailCopy>> GetMailCopiesAsync(IEnumerable<string> mailCopyIds);
6554
Task CreateMailRawAsync(MailAccount account, MailItemFolder mailItemFolder, NewMailItemPackage package);
6655
Task DeleteUserMailCacheAsync(Guid accountId);
@@ -138,15 +127,9 @@ public Task<string> UpdateAccountDeltaSynchronizationIdentifierAsync(Guid accoun
138127
public Task ChangeFlagStatusAsync(string mailCopyId, bool isFlagged)
139128
=> MailService.ChangeFlagStatusAsync(mailCopyId, isFlagged);
140129

141-
public Task<bool> IsMailExistsAsync(string messageId)
142-
=> MailService.IsMailExistsAsync(messageId);
143-
144130
public Task<List<string>> AreMailsExistsAsync(IEnumerable<string> mailCopyIds)
145131
=> MailService.AreMailsExistsAsync(mailCopyIds);
146132

147-
public Task<MailCopy> GetMailCopyAsync(string mailCopyId)
148-
=> MailService.GetSingleMailItemAsync(mailCopyId);
149-
150133
public Task<List<MailCopy>> GetMailCopiesAsync(IEnumerable<string> mailCopyIds)
151134
=> MailService.GetMailItemsAsync(mailCopyIds);
152135

Wino.Core/Synchronizers/OutlookSynchronizer.cs

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -967,12 +967,10 @@ public override async Task ExecuteNativeRequestsAsync(List<IRequestBundle<Reques
967967

968968
public override async Task<List<MailCopy>> OnlineSearchAsync(string queryText, List<IMailItemFolder> folders, CancellationToken cancellationToken = default)
969969
{
970-
bool isFoldersIncluded = folders?.Any() ?? false;
971-
972-
var messagesToDownload = new List<Message>();
970+
List<Message> messagesReturnedByApi = [];
973971

974972
// Perform search for each folder separately.
975-
if (isFoldersIncluded)
973+
if (folders?.Count > 0)
976974
{
977975
var folderIds = folders.Select(a => a.RemoteFolderId);
978976

@@ -990,9 +988,9 @@ public override async Task<List<MailCopy>> OnlineSearchAsync(string queryText, L
990988

991989
if (result?.Value != null)
992990
{
993-
lock (messagesToDownload)
991+
lock (messagesReturnedByApi)
994992
{
995-
messagesToDownload.AddRange(result.Value);
993+
messagesReturnedByApi.AddRange(result.Value);
996994
}
997995
}
998996
});
@@ -1008,59 +1006,60 @@ public override async Task<List<MailCopy>> OnlineSearchAsync(string queryText, L
10081006
requestConfig.QueryParameters.Search = $"\"{queryText}\"";
10091007
requestConfig.QueryParameters.Select = ["Id, ParentFolderId"];
10101008
requestConfig.QueryParameters.Top = 1000;
1011-
});
1009+
}, cancellationToken);
10121010

10131011
var result = await mailQuery;
10141012

10151013
if (result?.Value != null)
10161014
{
1017-
lock (messagesToDownload)
1018-
{
1019-
messagesToDownload.AddRange(result.Value);
1020-
}
1015+
messagesReturnedByApi.AddRange(result.Value);
10211016
}
10221017
}
10231018

1024-
// Do not download messages that exists, but return them for listing.
1019+
if (messagesReturnedByApi.Count == 0) return [];
10251020

1026-
var localFolders = await _outlookChangeProcessor.GetLocalFoldersAsync(Account.Id).ConfigureAwait(false);
1021+
var localFolders = (await _outlookChangeProcessor.GetLocalFoldersAsync(Account.Id).ConfigureAwait(false))
1022+
.ToDictionary(x => x.RemoteFolderId);
10271023

1028-
var existingMessageIds = new List<string>();
1024+
var messagesDictionary = messagesReturnedByApi.ToDictionary(a => a.Id);
10291025

1030-
//Download missing messages.
1031-
foreach (var message in messagesToDownload)
1032-
{
1033-
var messageId = message.Id;
1034-
var parentFolderId = message.ParentFolderId;
1026+
// Contains a list of message ids that potentially can be downloaded.
1027+
List<string> messageIdsWithKnownFolder = [];
10351028

1036-
if (!localFolders.Any(a => a.RemoteFolderId == parentFolderId))
1029+
// Validate that all messages are in a known folder.
1030+
foreach (var message in messagesReturnedByApi)
1031+
{
1032+
if (!localFolders.ContainsKey(message.ParentFolderId))
10371033
{
1038-
Log.Warning($"Search result returned a message from a folder that is not synchronized.");
1034+
Log.Warning("Search result returned a message from a folder that is not synchronized.");
10391035
continue;
10401036
}
10411037

1042-
existingMessageIds.Add(messageId);
1043-
1044-
var exists = await _outlookChangeProcessor.IsMailExistsAsync(messageId).ConfigureAwait(false);
1038+
messageIdsWithKnownFolder.Add(message.Id);
1039+
}
10451040

1046-
if (!exists)
1047-
{
1048-
// Check if folder exists. We can't download a mail without existing folder.
1041+
var locallyExistingMails = await _outlookChangeProcessor.AreMailsExistsAsync(messageIdsWithKnownFolder).ConfigureAwait(false);
10491042

1050-
var localFolder = localFolders.Find(a => a.RemoteFolderId == parentFolderId);
1043+
// Find messages that are not downloaded yet.
1044+
List<Message> messagesToDownload = [];
1045+
foreach (var id in messagesDictionary.Keys.Except(locallyExistingMails))
1046+
{
1047+
messagesToDownload.Add(messagesDictionary[id]);
1048+
}
10511049

1052-
await DownloadSearchResultMessageAsync(messageId, localFolder, cancellationToken).ConfigureAwait(false);
1053-
}
1050+
foreach (var message in messagesToDownload)
1051+
{
1052+
await DownloadSearchResultMessageAsync(message.Id, localFolders[message.ParentFolderId], cancellationToken).ConfigureAwait(false);
10541053
}
10551054

10561055
// Get results from database and return.
1057-
return await _outlookChangeProcessor.GetMailCopiesAsync(existingMessageIds);
1056+
return await _outlookChangeProcessor.GetMailCopiesAsync(messageIdsWithKnownFolder).ConfigureAwait(false);
10581057
}
10591058

10601059
private async Task<MimeMessage> DownloadMimeMessageAsync(string messageId, CancellationToken cancellationToken = default)
10611060
{
10621061
var mimeContentStream = await _graphClient.Me.Messages[messageId].Content.GetAsync(null, cancellationToken).ConfigureAwait(false);
1063-
return await MimeMessage.LoadAsync(mimeContentStream).ConfigureAwait(false);
1062+
return await MimeMessage.LoadAsync(mimeContentStream, cancellationToken).ConfigureAwait(false);
10641063
}
10651064

10661065
public override async Task<List<NewMailItemPackage>> CreateNewMailPackagesAsync(Message message, MailItemFolder assignedFolder, CancellationToken cancellationToken = default)

0 commit comments

Comments
 (0)