Files
Wino-Mail/Wino.Services/CalendarIcsFileService.cs
T
2026-02-15 02:20:18 +01:00

128 lines
4.9 KiB
C#

using System;
using System.IO;
using System.Threading.Tasks;
using Serilog;
using Wino.Core.Domain.Interfaces;
namespace Wino.Services;
public class CalendarIcsFileService : ICalendarIcsFileService
{
private readonly INativeAppService _nativeAppService;
private readonly ILogger _logger = Log.ForContext<CalendarIcsFileService>();
public CalendarIcsFileService(INativeAppService nativeAppService)
{
_nativeAppService = nativeAppService;
}
public async Task SaveCalendarItemIcsAsync(Guid accountId, Guid calendarId, Guid calendarItemId, string remoteEventId, string remoteResourceHref, string eTag, string icsContent)
{
if (accountId == Guid.Empty || calendarId == Guid.Empty || calendarItemId == Guid.Empty || string.IsNullOrWhiteSpace(icsContent))
return;
var folderPath = await GetCalendarItemFolderPathAsync(accountId, calendarId, calendarItemId).ConfigureAwait(false);
var icsPath = Path.Combine(folderPath, "event.ics");
var metaPath = Path.Combine(folderPath, "event.meta.json");
try
{
await File.WriteAllTextAsync(icsPath, icsContent).ConfigureAwait(false);
var metadataContent = string.Join(
Environment.NewLine,
$"CalendarItemId={calendarItemId:N}",
$"RemoteEventId={remoteEventId ?? string.Empty}",
$"RemoteResourceHref={remoteResourceHref ?? string.Empty}",
$"ETag={eTag ?? string.Empty}",
$"UpdatedAtUtc={DateTime.UtcNow:O}");
await File.WriteAllTextAsync(metaPath, metadataContent).ConfigureAwait(false);
}
catch (Exception ex)
{
_logger.Error(ex, "Failed to save ICS file for account {AccountId} and calendar item {CalendarItemId}", accountId, calendarItemId);
}
}
public async Task DeleteCalendarItemIcsAsync(Guid accountId, Guid calendarItemId)
{
if (accountId == Guid.Empty || calendarItemId == Guid.Empty)
return;
try
{
var accountRootPath = await GetAccountCalendarsRootPathAsync(accountId).ConfigureAwait(false);
if (!Directory.Exists(accountRootPath))
return;
var calendarDirectories = Directory.GetDirectories(accountRootPath);
foreach (var calendarDirectory in calendarDirectories)
{
var itemPath = Path.Combine(calendarDirectory, calendarItemId.ToString("N"));
if (Directory.Exists(itemPath))
{
Directory.Delete(itemPath, recursive: true);
break;
}
}
}
catch (Exception ex)
{
_logger.Error(ex, "Failed to delete ICS folder for account {AccountId} and calendar item {CalendarItemId}", accountId, calendarItemId);
}
}
public async Task DeleteCalendarIcsForCalendarAsync(Guid accountId, Guid calendarId)
{
if (accountId == Guid.Empty || calendarId == Guid.Empty)
return;
try
{
var calendarPath = await GetCalendarFolderPathAsync(accountId, calendarId).ConfigureAwait(false);
if (Directory.Exists(calendarPath))
{
Directory.Delete(calendarPath, recursive: true);
}
}
catch (Exception ex)
{
_logger.Error(ex, "Failed to delete ICS folder for account {AccountId} and calendar {CalendarId}", accountId, calendarId);
}
}
private async Task<string> GetCalendarItemFolderPathAsync(Guid accountId, Guid calendarId, Guid calendarItemId)
{
var calendarPath = await GetCalendarFolderPathAsync(accountId, calendarId).ConfigureAwait(false);
var itemDirectory = Path.Combine(calendarPath, calendarItemId.ToString("N"));
Directory.CreateDirectory(itemDirectory);
return itemDirectory;
}
private async Task<string> GetCalendarFolderPathAsync(Guid accountId, Guid calendarId)
{
var accountRootPath = await GetAccountCalendarsRootPathAsync(accountId).ConfigureAwait(false);
var calendarDirectory = Path.Combine(accountRootPath, calendarId.ToString("N"));
Directory.CreateDirectory(calendarDirectory);
return calendarDirectory;
}
private async Task<string> GetAccountCalendarsRootPathAsync(Guid accountId)
{
var root = await GetIcsRootPathAsync().ConfigureAwait(false);
var accountPath = Path.Combine(root, accountId.ToString("N"), "calendars");
Directory.CreateDirectory(accountPath);
return accountPath;
}
private async Task<string> GetIcsRootPathAsync()
{
var mimeRootPath = await _nativeAppService.GetMimeMessageStoragePath().ConfigureAwait(false);
var icsRootPath = Path.Combine(mimeRootPath, "CalendarIcs");
Directory.CreateDirectory(icsRootPath);
return icsRootPath;
}
}