@@ -9,7 +9,8 @@ using CommunityToolkit.Mvvm.Messaging;
|
||||
using MailKit;
|
||||
using Serilog;
|
||||
using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Entities;
|
||||
using Wino.Core.Domain.Entities.Mail;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Accounts;
|
||||
@@ -22,15 +23,15 @@ using Wino.Messaging.UI;
|
||||
|
||||
namespace Wino.Core.Synchronizers
|
||||
{
|
||||
public abstract class BaseSynchronizer<TBaseRequest, TMessageType> : BaseMailIntegrator<TBaseRequest>, IBaseSynchronizer
|
||||
public abstract class BaseMailSynchronizer<TBaseRequest, TMessageType> : BaseMailIntegrator<TBaseRequest>, IBaseMailSynchronizer
|
||||
{
|
||||
private SemaphoreSlim synchronizationSemaphore = new(1);
|
||||
private CancellationToken activeSynchronizationCancellationToken;
|
||||
|
||||
protected ConcurrentBag<IRequestBase> changeRequestQueue = [];
|
||||
protected ILogger Logger = Log.ForContext<BaseSynchronizer<TBaseRequest, TMessageType>>();
|
||||
protected ILogger Logger = Log.ForContext<BaseMailSynchronizer<TBaseRequest, TMessageType>>();
|
||||
|
||||
protected BaseSynchronizer(MailAccount account)
|
||||
protected BaseMailSynchronizer(MailAccount account)
|
||||
{
|
||||
Account = account;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using Wino.Core.Integration;
|
||||
|
||||
namespace Wino.Core.Synchronizers.Calendar
|
||||
{
|
||||
public abstract class BaseCalendarSynchronizer<TNativeRequestType, TCalendarEventType> : BaseCalendarIntegrator<TNativeRequestType, TCalendarEventType>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Graph.Models;
|
||||
using Microsoft.Kiota.Abstractions;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
|
||||
namespace Wino.Core.Synchronizers.Calendar
|
||||
{
|
||||
public class OutlookCalendarSynchronizer : BaseCalendarSynchronizer<RequestInformation, Event>
|
||||
{
|
||||
public OutlookCalendarSynchronizer(MailAccount account)
|
||||
{
|
||||
Account = account;
|
||||
}
|
||||
|
||||
public MailAccount Account { get; }
|
||||
|
||||
public override Task<Event> CreateCalendarEventAsync(RequestInformation request)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,23 +16,24 @@ using Microsoft.IdentityModel.Tokens;
|
||||
using MimeKit;
|
||||
using MoreLinq;
|
||||
using Serilog;
|
||||
using Wino.Core.Domain.Entities;
|
||||
using Wino.Core.Domain.Entities.Mail;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Exceptions;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Accounts;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
using Wino.Core.Domain.Models.Requests;
|
||||
using Wino.Core.Domain.Models.Synchronization;
|
||||
using Wino.Core.Extensions;
|
||||
using Wino.Core.Http;
|
||||
using Wino.Core.Integration.Processors;
|
||||
using Wino.Core.Requests;
|
||||
using Wino.Core.Requests.Bundles;
|
||||
using Wino.Messaging.UI;
|
||||
|
||||
namespace Wino.Core.Synchronizers
|
||||
namespace Wino.Core.Synchronizers.Mail
|
||||
{
|
||||
public class GmailSynchronizer : BaseSynchronizer<IClientServiceRequest, Message>, IHttpClientFactory
|
||||
public class GmailSynchronizer : BaseMailSynchronizer<IClientServiceRequest, Message>, IHttpClientFactory
|
||||
{
|
||||
public override uint BatchModificationSize => 1000;
|
||||
public override uint InitialMessageDownloadCountPerFolder => 1200;
|
||||
@@ -11,7 +11,8 @@ using MailKit.Search;
|
||||
using MimeKit;
|
||||
using MoreLinq;
|
||||
using Serilog;
|
||||
using Wino.Core.Domain.Entities;
|
||||
using Wino.Core.Domain.Entities.Mail;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Exceptions;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
@@ -26,9 +27,9 @@ using Wino.Core.Requests;
|
||||
using Wino.Core.Requests.Bundles;
|
||||
using Wino.Messaging.UI;
|
||||
|
||||
namespace Wino.Core.Synchronizers
|
||||
namespace Wino.Core.Synchronizers.Mail
|
||||
{
|
||||
public class ImapSynchronizer : BaseSynchronizer<ImapRequest, ImapMessageCreationPackage>
|
||||
public class ImapSynchronizer : BaseMailSynchronizer<ImapRequest, ImapMessageCreationPackage>
|
||||
{
|
||||
private CancellationTokenSource idleDoneToken;
|
||||
private CancellationTokenSource cancelInboxListeningToken = new CancellationTokenSource();
|
||||
@@ -225,7 +226,7 @@ namespace Wino.Core.Synchronizers
|
||||
|
||||
public override IEnumerable<IRequestBundle<ImapRequest>> Move(BatchMoveRequest request)
|
||||
{
|
||||
return CreateTaskBundle(async (ImapClient client) =>
|
||||
return CreateTaskBundle(async (client) =>
|
||||
{
|
||||
var uniqueIds = GetUniqueIds(request.Items.Select(a => a.Item.Id));
|
||||
|
||||
@@ -241,7 +242,7 @@ namespace Wino.Core.Synchronizers
|
||||
|
||||
public override IEnumerable<IRequestBundle<ImapRequest>> ChangeFlag(BatchChangeFlagRequest request)
|
||||
{
|
||||
return CreateTaskBundle(async (ImapClient client) =>
|
||||
return CreateTaskBundle(async (client) =>
|
||||
{
|
||||
var folder = request.Items.First().Item.AssignedFolder;
|
||||
var remoteFolder = await client.GetFolderAsync(folder.RemoteFolderId);
|
||||
@@ -255,7 +256,7 @@ namespace Wino.Core.Synchronizers
|
||||
|
||||
public override IEnumerable<IRequestBundle<ImapRequest>> Delete(BatchDeleteRequest request)
|
||||
{
|
||||
return CreateTaskBundle(async (ImapClient client) =>
|
||||
return CreateTaskBundle(async (client) =>
|
||||
{
|
||||
var folder = request.Items.First().Item.AssignedFolder;
|
||||
var remoteFolder = await client.GetFolderAsync(folder.RemoteFolderId).ConfigureAwait(false);
|
||||
@@ -270,7 +271,7 @@ namespace Wino.Core.Synchronizers
|
||||
|
||||
public override IEnumerable<IRequestBundle<ImapRequest>> MarkRead(BatchMarkReadRequest request)
|
||||
{
|
||||
return CreateTaskBundle(async (ImapClient client) =>
|
||||
return CreateTaskBundle(async (client) =>
|
||||
{
|
||||
var folder = request.Items.First().Item.AssignedFolder;
|
||||
var remoteFolder = await client.GetFolderAsync(folder.RemoteFolderId);
|
||||
@@ -284,7 +285,7 @@ namespace Wino.Core.Synchronizers
|
||||
|
||||
public override IEnumerable<IRequestBundle<ImapRequest>> CreateDraft(BatchCreateDraftRequest request)
|
||||
{
|
||||
return CreateTaskBundle(async (ImapClient client) =>
|
||||
return CreateTaskBundle(async (client) =>
|
||||
{
|
||||
var remoteDraftFolder = await client.GetFolderAsync(request.DraftPreperationRequest.CreatedLocalDraftCopy.AssignedFolder.RemoteFolderId).ConfigureAwait(false);
|
||||
|
||||
@@ -305,7 +306,7 @@ namespace Wino.Core.Synchronizers
|
||||
|
||||
public override IEnumerable<IRequestBundle<ImapRequest>> SendDraft(BatchSendDraftRequestRequest request)
|
||||
{
|
||||
return CreateTaskBundle(async (ImapClient client) =>
|
||||
return CreateTaskBundle(async (client) =>
|
||||
{
|
||||
// Batch sending is not supported. It will always be a single request therefore no need for a loop here.
|
||||
|
||||
@@ -381,7 +382,7 @@ namespace Wino.Core.Synchronizers
|
||||
|
||||
public override IEnumerable<IRequestBundle<ImapRequest>> RenameFolder(RenameFolderRequest request)
|
||||
{
|
||||
return CreateTaskBundle(async (ImapClient client) =>
|
||||
return CreateTaskBundle(async (client) =>
|
||||
{
|
||||
var folder = await client.GetFolderAsync(request.Folder.RemoteFolderId).ConfigureAwait(false);
|
||||
await folder.RenameAsync(folder.ParentFolder, request.NewFolderName).ConfigureAwait(false);
|
||||
@@ -663,7 +664,7 @@ namespace Wino.Core.Synchronizers
|
||||
// Namespaces are not needed as folders.
|
||||
// Non-existed folders don't need to be synchronized.
|
||||
|
||||
if ((remoteFolder.IsNamespace && !remoteFolder.Attributes.HasFlag(FolderAttributes.Inbox)) || !remoteFolder.Exists)
|
||||
if (remoteFolder.IsNamespace && !remoteFolder.Attributes.HasFlag(FolderAttributes.Inbox) || !remoteFolder.Exists)
|
||||
continue;
|
||||
|
||||
var existingLocalFolder = localFolders.FirstOrDefault(a => a.RemoteFolderId == remoteFolder.FullName);
|
||||
@@ -926,8 +927,8 @@ namespace Wino.Core.Synchronizers
|
||||
{
|
||||
var localMailCopyId = MailkitClientExtensions.CreateUid(folder.Id, changedItem.UniqueId.Id);
|
||||
|
||||
var isFlagged = MailkitClientExtensions.GetIsFlagged(changedItem.Flags);
|
||||
var isRead = MailkitClientExtensions.GetIsRead(changedItem.Flags);
|
||||
var isFlagged = changedItem.Flags.GetIsFlagged();
|
||||
var isRead = changedItem.Flags.GetIsRead();
|
||||
|
||||
await _imapChangeProcessor.ChangeMailReadStatusAsync(localMailCopyId, isRead);
|
||||
await _imapChangeProcessor.ChangeFlagStatusAsync(localMailCopyId, isFlagged);
|
||||
@@ -20,7 +20,8 @@ using Microsoft.Kiota.Http.HttpClientLibrary.Middleware.Options;
|
||||
using MimeKit;
|
||||
using MoreLinq.Extensions;
|
||||
using Serilog;
|
||||
using Wino.Core.Domain.Entities;
|
||||
using Wino.Core.Domain.Entities.Mail;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Exceptions;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
@@ -33,10 +34,11 @@ using Wino.Core.Http;
|
||||
using Wino.Core.Integration.Processors;
|
||||
using Wino.Core.Misc;
|
||||
using Wino.Core.Requests;
|
||||
using Wino.Core.Requests.Bundles;
|
||||
|
||||
namespace Wino.Core.Synchronizers
|
||||
namespace Wino.Core.Synchronizers.Mail
|
||||
{
|
||||
public class OutlookSynchronizer : BaseSynchronizer<RequestInformation, Message>
|
||||
public class OutlookSynchronizer : BaseMailSynchronizer<RequestInformation, Message>
|
||||
{
|
||||
public override uint BatchModificationSize => 20;
|
||||
public override uint InitialMessageDownloadCountPerFolder => 250;
|
||||
@@ -825,7 +827,7 @@ namespace Wino.Core.Synchronizers
|
||||
|
||||
public override async Task ExecuteNativeRequestsAsync(IEnumerable<IRequestBundle<RequestInformation>> batchedRequests, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var batchRequestInformations = BatchExtension.Batch(batchedRequests, (int)MaximumAllowedBatchRequestSize);
|
||||
var batchRequestInformations = batchedRequests.Batch((int)MaximumAllowedBatchRequestSize);
|
||||
|
||||
bool serializeRequests = false;
|
||||
|
||||
@@ -906,7 +908,7 @@ namespace Wino.Core.Synchronizers
|
||||
bundle.Request.RevertUIChanges();
|
||||
|
||||
var content = await httpResponseMessage.Content.ReadAsStringAsync();
|
||||
var errorJson = JsonObject.Parse(content);
|
||||
var errorJson = JsonNode.Parse(content);
|
||||
var errorString = $"{httpResponseMessage.StatusCode} [{bundle.Request.GetType().Name}]\n{errorJson["error"]["code"]} - {errorJson["error"]["message"]}\n";
|
||||
|
||||
exceptionBag.Add(errorString);
|
||||
Reference in New Issue
Block a user