Ground work for Wino Calendar. (#475)

Wino Calendar abstractions.
This commit is contained in:
Burak Kaan Köse
2024-11-10 23:28:25 +01:00
committed by GitHub
parent a979e8430f
commit d1d6f12f05
486 changed files with 7969 additions and 2708 deletions

View File

@@ -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;
}

View File

@@ -0,0 +1,9 @@
using Wino.Core.Integration;
namespace Wino.Core.Synchronizers.Calendar
{
public abstract class BaseCalendarSynchronizer<TNativeRequestType, TCalendarEventType> : BaseCalendarIntegrator<TNativeRequestType, TCalendarEventType>
{
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);