2025-02-26 23:11:49 +01:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Threading;
|
|
|
|
|
|
using MailKit;
|
2025-02-15 12:53:32 +01:00
|
|
|
|
using MailKit.Net.Imap;
|
|
|
|
|
|
using Serilog;
|
|
|
|
|
|
|
2025-02-16 11:54:23 +01:00
|
|
|
|
namespace Wino.Core.Integration;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Extended class for ImapClient that is used in Wino.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
internal class WinoImapClient : ImapClient
|
2025-02-15 12:53:32 +01:00
|
|
|
|
{
|
2025-02-26 23:11:49 +01:00
|
|
|
|
private int _busyCount;
|
|
|
|
|
|
|
2025-02-15 12:53:32 +01:00
|
|
|
|
/// <summary>
|
2025-02-16 11:54:23 +01:00
|
|
|
|
/// Gets or internally sets whether the QRESYNC extension is enabled.
|
|
|
|
|
|
/// It is set by ImapClientPool immidiately after the authentication.
|
2025-02-15 12:53:32 +01:00
|
|
|
|
/// </summary>
|
2025-02-16 11:54:23 +01:00
|
|
|
|
public bool IsQResyncEnabled { get; internal set; }
|
|
|
|
|
|
|
|
|
|
|
|
public WinoImapClient()
|
2025-02-16 11:35:43 +01:00
|
|
|
|
{
|
2025-02-16 11:54:23 +01:00
|
|
|
|
HookEvents();
|
|
|
|
|
|
}
|
2025-02-15 12:53:32 +01:00
|
|
|
|
|
2025-02-16 11:54:23 +01:00
|
|
|
|
public WinoImapClient(IProtocolLogger protocolLogger) : base(protocolLogger)
|
|
|
|
|
|
{
|
|
|
|
|
|
HookEvents();
|
|
|
|
|
|
}
|
2025-02-15 12:53:32 +01:00
|
|
|
|
|
2025-02-16 11:54:23 +01:00
|
|
|
|
private void HookEvents()
|
|
|
|
|
|
{
|
|
|
|
|
|
Disconnected += ClientDisconnected;
|
|
|
|
|
|
}
|
2025-02-15 12:53:32 +01:00
|
|
|
|
|
2025-02-16 11:54:23 +01:00
|
|
|
|
private void UnhookEvents()
|
|
|
|
|
|
{
|
|
|
|
|
|
Disconnected -= ClientDisconnected;
|
|
|
|
|
|
}
|
2025-02-16 11:43:30 +01:00
|
|
|
|
|
2025-02-16 11:54:23 +01:00
|
|
|
|
private void ClientDisconnected(object sender, DisconnectedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (e.IsRequested)
|
2025-02-15 12:53:32 +01:00
|
|
|
|
{
|
2025-02-16 11:54:23 +01:00
|
|
|
|
Log.Debug("Imap client is disconnected on request.");
|
2025-02-15 12:53:32 +01:00
|
|
|
|
}
|
2025-02-16 11:54:23 +01:00
|
|
|
|
else
|
2025-02-16 11:43:30 +01:00
|
|
|
|
{
|
2025-02-16 11:54:23 +01:00
|
|
|
|
Log.Debug("Imap client connection is dropped by server.");
|
2025-02-16 11:43:30 +01:00
|
|
|
|
}
|
2025-02-16 11:54:23 +01:00
|
|
|
|
}
|
2025-02-15 12:53:32 +01:00
|
|
|
|
|
2025-02-26 23:11:49 +01:00
|
|
|
|
public bool IsBusy() => _busyCount > 0;
|
|
|
|
|
|
|
|
|
|
|
|
public IDisposable GetBusyScope()
|
|
|
|
|
|
{
|
|
|
|
|
|
Interlocked.Increment(ref _busyCount);
|
|
|
|
|
|
return new BusyScope(this);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private class BusyScope : IDisposable
|
|
|
|
|
|
{
|
|
|
|
|
|
private readonly WinoImapClient _client;
|
|
|
|
|
|
private bool _disposed;
|
|
|
|
|
|
|
|
|
|
|
|
public BusyScope(WinoImapClient client)
|
|
|
|
|
|
{
|
|
|
|
|
|
_client = client;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!_disposed)
|
|
|
|
|
|
{
|
|
|
|
|
|
Interlocked.Decrement(ref _client._busyCount);
|
|
|
|
|
|
_disposed = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-16 11:54:23 +01:00
|
|
|
|
protected override void Dispose(bool disposing)
|
|
|
|
|
|
{
|
|
|
|
|
|
base.Dispose(disposing);
|
2025-02-16 11:43:30 +01:00
|
|
|
|
|
2025-02-16 11:54:23 +01:00
|
|
|
|
if (disposing)
|
|
|
|
|
|
{
|
|
|
|
|
|
UnhookEvents();
|
2025-02-15 12:53:32 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|