182 lines
8.0 KiB
C#
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];
|
|
}
|
|
}
|
|
}
|