Files
meeting-assistant/MeetingAssistant/Calendar/OutlookClassicCalendarMeetingProvider.Windows.cs
T

111 lines
3.8 KiB
C#

#if WINDOWS
using MeetingAssistant.MeetingNotes;
namespace MeetingAssistant.Calendar;
public sealed class OutlookClassicCalendarMeetingProvider : ICalendarMeetingProvider
{
private readonly ILogger<OutlookClassicCalendarMeetingProvider> logger;
public OutlookClassicCalendarMeetingProvider(ILogger<OutlookClassicCalendarMeetingProvider> logger)
{
this.logger = logger;
}
public Task<IReadOnlyList<CalendarMeeting>> GetRecordingPromptCandidatesForDayAsync(
DateOnly day,
CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
try
{
return OutlookClassicCom.RunStaAsync(
() => GetTeamsMeetingsForDay(day),
cancellationToken,
"Meeting Assistant Outlook Calendar Prompt Lookup");
}
catch (Exception exception) when (exception is not OperationCanceledException)
{
logger.LogDebug(exception, "Outlook Classic calendar meetings were not available");
return Task.FromResult<IReadOnlyList<CalendarMeeting>>([]);
}
}
private IReadOnlyList<CalendarMeeting> GetTeamsMeetingsForDay(DateOnly day)
{
using var calendar = OutlookClassicCom.OpenDefaultCalendar(logger, "calendar prompt lookup");
if (calendar is null)
{
return [];
}
var dayStart = day.ToDateTime(TimeOnly.MinValue);
var dayEnd = dayStart.AddDays(1);
var meetings = new List<CalendarMeeting>();
foreach (var item in OutlookClassicCom.EnumerateItems(calendar.Items))
{
try
{
if (item is null || !OutlookClassicCom.IsAppointment(item))
{
continue;
}
var start = Convert.ToDateTime(OutlookClassicCom.GetProperty(item, "Start"));
if (start >= dayEnd)
{
break;
}
var end = Convert.ToDateTime(OutlookClassicCom.GetProperty(item, "End"));
if (end <= dayStart ||
start < dayStart ||
!IsTeamsAppointment(item))
{
continue;
}
var rawSubject = Convert.ToString(OutlookClassicCom.GetProperty(item, "Subject"))?.Trim();
var subject = string.IsNullOrWhiteSpace(rawSubject) ? "Teams meeting" : rawSubject;
meetings.Add(new CalendarMeeting(
GetAppointmentId(item, start, end, subject),
subject,
OutlookClassicCom.ToLocalOffset(start),
OutlookClassicCom.ToLocalOffset(end)));
}
finally
{
OutlookClassicCom.ReleaseComObject(item);
}
}
return meetings;
}
private static string GetAppointmentId(
object appointment,
DateTime start,
DateTime end,
string subject)
{
var id = Convert.ToString(OutlookClassicCom.TryGetProperty(appointment, "GlobalAppointmentID"));
if (string.IsNullOrWhiteSpace(id))
{
id = Convert.ToString(OutlookClassicCom.TryGetProperty(appointment, "EntryID"));
}
return string.IsNullOrWhiteSpace(id)
? $"{start:O}|{end:O}|{subject}"
: $"{id}|{start:O}";
}
private static bool IsTeamsAppointment(object appointment)
{
var subject = Convert.ToString(OutlookClassicCom.GetProperty(appointment, "Subject")) ?? "";
var location = Convert.ToString(OutlookClassicCom.GetProperty(appointment, "Location")) ?? "";
var body = Convert.ToString(OutlookClassicCom.GetProperty(appointment, "Body")) ?? "";
return TeamsMeetingMarkerDetector.IsTeamsAppointment(subject, location, body);
}
}
#endif