meeting-clock/OutlookManager.cs
Zechert, Frank (EXTERN: Capgemini) 4c9fa6feff initial commit
2020-12-17 17:45:20 +01:00

182 lines
8.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Outlook = Microsoft.Office.Interop.Outlook;
namespace MeetingClock
{
public class OutlookManager
{
private Outlook.Application application;
public OutlookManager()
{
}
public async Task<Outlook.AppointmentItem> GetNextAppointment(
bool ignoreAllDayEvents, bool ignoreCancelledMeetings, bool ignoreFreeMeetings, bool ignoreOutOfOfficeMeetings, bool ignoreTentativeMeetings)
{
await Task.Run(() =>
{
lock(this)
{
int retries = 5;
while (this.application == null && retries-- > 0)
{
try
{
this.application = new Outlook.Application();
}
catch (Exception exception)
{
this.application = null;
Debug.WriteLine(String.Format("Failed to start outlook application: {0}", exception.Message));
Thread.Sleep(3000);
}
}
}
});
List<Outlook.AppointmentItem> appointmentItems = new List<Outlook.AppointmentItem>();
lock (this)
{
if (this.application == null)
{
return null; // not available at the moment
}
try
{
Outlook.Folder calendarFolder = this.application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar) as Outlook.Folder;
DateTime start = DateTime.Now;
DateTime end = start.AddHours(2);
string filter = String.Format("[Start] >= '{0}' AND [Start] <= '{1}'", start.ToString("g"), end.ToString("g"));
Debug.WriteLine(String.Format("Filtering Outlook Events: {0}", filter));
Outlook.Items appointments = calendarFolder.Items;
appointments.IncludeRecurrences = true;
appointments.Sort("[Start]", Type.Missing);
Outlook.Items filteredAppointments = appointments.Restrict(filter);
Debug.WriteLine(String.Format("Found {0} outlook appointments between {1} and {2}", filteredAppointments.Count, start.ToString("g"), end.ToString("g")));
DateTime? firstAppointmentTime = null;
foreach (Outlook.AppointmentItem appointment in filteredAppointments)
{
Debug.WriteLine(String.Format("{0}-{5} ({6}): {1} ({2}), allday: {3}, busy: {4}, importance: {7}, recurring: {8}, scheduled: {9}, conflict: {10}",
appointment.Start.ToString("g"), appointment.Subject, appointment.MeetingStatus, appointment.AllDayEvent, appointment.BusyStatus, appointment.End.ToString("g"),
appointment.Duration, appointment.Importance, appointment.RecurrenceState, appointment.CreationTime.ToString("g"), appointment.IsConflict));
if (ignoreAllDayEvents && appointment.AllDayEvent)
{
continue; // ignore all day events
}
if (ignoreCancelledMeetings
&& (appointment.MeetingStatus == Outlook.OlMeetingStatus.olMeetingCanceled || appointment.MeetingStatus == Outlook.OlMeetingStatus.olMeetingReceivedAndCanceled))
{
continue; // ignore cancelled meetings
}
if (ignoreFreeMeetings && appointment.BusyStatus == Outlook.OlBusyStatus.olFree)
{
continue; // ignore free meetings
}
if (ignoreOutOfOfficeMeetings && appointment.BusyStatus == Outlook.OlBusyStatus.olOutOfOffice)
{
continue; // ignore out of office meetings
}
if (ignoreTentativeMeetings && appointment.BusyStatus == Outlook.OlBusyStatus.olTentative)
{
continue; // ignore tentative meetings
}
if (firstAppointmentTime == null)
{
firstAppointmentTime = appointment.Start;
}
// ignore appointments that do not start first
if (firstAppointmentTime < appointment.Start)
{
continue; // ignore later appointments
}
appointmentItems.Add(appointment);
Debug.WriteLine(String.Format("Next possible appointment is {0}-{1}: {2}", appointment.Start.ToString("t"), appointment.End.ToString("t"), appointment.Subject));
}
}
catch (Exception exception)
{
Debug.WriteLine(String.Format("Exception getting outlook appointments: {0}", exception.Message));
this.application = null;
}
}
if (appointmentItems.Count == 0)
{
return null; // no appointments upcoming
}
if (appointmentItems.Count == 1)
{
return appointmentItems[0]; // exactly one appointment upcoming
}
// remove cancelled events
appointmentItems = appointmentItems.AsQueryable()
.Where(item => item.MeetingStatus != Outlook.OlMeetingStatus.olMeetingCanceled && item.MeetingStatus != Outlook.OlMeetingStatus.olMeetingReceivedAndCanceled).ToList();
if (appointmentItems.Count == 1)
{
return appointmentItems[0]; // one appointment still left
}
// remove duplicates by priority, select highest priority
Outlook.OlImportance importance = appointmentItems.AsQueryable().OrderByDescending(item => (int)item.Importance).Select(item => item.Importance).First();
appointmentItems = appointmentItems.AsQueryable().Where(item => item.Importance == importance).ToList();
if (appointmentItems.Count == 1)
{
return appointmentItems[0]; // one appointment still left
}
// remove all day events
appointmentItems = appointmentItems.AsQueryable().Where(item => !item.AllDayEvent).ToList();
if (appointmentItems.Count == 1)
{
return appointmentItems[0]; // one appointment still left
}
// remove free appointment
appointmentItems = appointmentItems.AsQueryable().Where(item => item.BusyStatus != Outlook.OlBusyStatus.olFree).ToList();
if (appointmentItems.Count == 1)
{
return appointmentItems[0]; // one appointment still left
}
// remove tentative appointment
appointmentItems = appointmentItems.AsQueryable().Where(item => item.BusyStatus != Outlook.OlBusyStatus.olTentative).ToList();
if (appointmentItems.Count == 1)
{
return appointmentItems[0]; // one appointment still left
}
// remove out of office appointment
appointmentItems = appointmentItems.AsQueryable().Where(item => item.BusyStatus != Outlook.OlBusyStatus.olOutOfOffice).ToList();
if (appointmentItems.Count == 1)
{
return appointmentItems[0]; // one appointment still left
}
return appointmentItems[0];
}
}
}