예제 #1
0
        internal static bool Equals(Event googleException, Outlook.Exception outlookException)
        {
            bool googleExceptionDeleted = googleException.Status == "cancelled";
            bool exceptionEventScheduleEqual;

            if (outlookException.Deleted)
            {
                return
                    (googleException.OriginalStartTime.DateTime.Value.Date == outlookException.OriginalDate &&
                     googleExceptionDeleted);
            }
            else
            {
                exceptionEventScheduleEqual = outlookException.AppointmentItem.AllDayEvent ?
                                              (
                    googleException.Start.Date == outlookException.AppointmentItem.Start.ToString("yyyy-MM-dd") &&
                    googleException.End.Date == outlookException.AppointmentItem.End.ToString("yyyy-MM-dd")
                                              ) :
                                              (
                    googleException.Start.DateTime.Value == outlookException.AppointmentItem.Start &&
                    googleException.End.DateTime.Value == outlookException.AppointmentItem.End
                                              );
                return
                    (googleException.OriginalStartTime.DateTime == outlookException.OriginalDate &&
                     !googleExceptionDeleted && exceptionEventScheduleEqual);
            }
        }
예제 #2
0
        private static Boolean exceptionIsDeleted(Microsoft.Office.Interop.Outlook.Exception oExcp)
        {
            if (oExcp.Deleted)
            {
                return(true);
            }
            AppointmentItem ai = null;

            try {
                ai = oExcp.AppointmentItem;
                return(false);
            } catch (System.Exception ex) {
                OGCSexception.Analyse(ex);
                if (ex.Message == "You changed one of the recurrences of this item, and this instance no longer exists. Close any open items and try again.")
                {
                    log.Warn("This Outlook recurrence instance has become inaccessible, probably due to caching");
                    return(true);
                }
                else
                {
                    log.Warn("Error when determining if Outlook recurrence is deleted or not.\r\n" + ex.Message);
                    return(true);
                }
            } finally {
                ai = (AppointmentItem)OutlookOgcs.Calendar.ReleaseObject(ai);
            }
        }
예제 #3
0
 internal RecurrenceException(Outlook.Exception outlookException, EventRecurrence parentRecurrence = null)
 {
     this._parentRecurrence = parentRecurrence != null ? parentRecurrence : new EventRecurrence(outlookException.Parent as Outlook.RecurrencePattern);
     this.OriginalDate      = outlookException.OriginalDate;
     this.Deleted           = outlookException.Deleted;
     if (!this.Deleted)
     {
         this.ModifiedEvent = new CalendarEvent(outlookException.AppointmentItem);
     }
 }
예제 #4
0
 internal static bool Contains(IEnumerable <Event> googleExceptions, Outlook.Exception outlookException)
 {
     foreach (var googleException in googleExceptions)
     {
         if (Equals(googleException, outlookException))
         {
             return(true);
         }
     }
     return(false);
 }
예제 #5
0
        private static void getOutlookInstance(RecurrencePattern oPattern, DateTime instanceDate, ref AppointmentItem ai)
        {
            //First check if this is not yet an exception
            try {
                ai = oPattern.GetOccurrence(instanceDate);
            } catch { }
            if (ai == null)
            {
                //The Outlook API is rubbish as the date argument is how it exists NOW (not OriginalDate).
                //If this has changed >1 in Google then there's no way of knowing what it might be!

                Exceptions oExcps = null;
                try {
                    oExcps = oPattern.Exceptions;
                    for (int e = 1; e <= oExcps.Count; e++)
                    {
                        Microsoft.Office.Interop.Outlook.Exception oExcp = null;
                        try {
                            oExcp = oExcps[e];
                            if (oExcp.OriginalDate.Date == instanceDate.Date)
                            {
                                try {
                                    log.Debug("Found Outlook exception for " + instanceDate);
                                    if (exceptionIsDeleted(oExcp))
                                    {
                                        log.Debug("This exception is deleted.");
                                        break;
                                    }
                                    else
                                    {
                                        ai = oExcp.AppointmentItem;
                                        break;
                                    }
                                } catch (System.Exception ex) {
                                    MainForm.Instance.Logboxout(ex.Message);
                                    MainForm.Instance.Logboxout("If this keeps happening, please restart OGCS.");
                                    break;
                                } finally {
                                    OutlookCalendar.ReleaseObject(oExcp);
                                }
                            }
                        } finally {
                            oExcp = (Microsoft.Office.Interop.Outlook.Exception)OutlookCalendar.ReleaseObject(oExcp);
                        }
                    }
                } finally {
                    oExcps = (Exceptions)OutlookCalendar.ReleaseObject(oExcps);
                }
                if (ai == null)
                {
                    log.Warn("Unable to find Outlook exception for " + instanceDate);
                }
            }
        }
예제 #6
0
        public Event GetGoogleInstance(Microsoft.Office.Interop.Outlook.Exception oExcp, String gRecurringEventID, String oEntryID)
        {
            Boolean oIsDeleted = exceptionIsDeleted(oExcp);

            log.Debug("Finding Google instance for " + (oIsDeleted ? "deleted " : "") + "Outlook exception:-");
            log.Debug("  Original date: " + oExcp.OriginalDate.ToString("dd/MM/yyyy"));
            if (!oIsDeleted)
            {
                log.Debug("  Current  date: " + oExcp.AppointmentItem.Start.ToString("dd/MM/yyyy"));
            }
            foreach (Event gExcp in googleExceptions)
            {
                if (gExcp.RecurringEventId == gRecurringEventID)
                {
                    if ((!oIsDeleted &&
                         GoogleCalendar.GoogleTimeFrom(oExcp.OriginalDate) == (gExcp.OriginalStartTime.Date ?? gExcp.OriginalStartTime.DateTime)
                         ) ||
                        (oIsDeleted &&
                         GoogleCalendar.GoogleTimeFrom(oExcp.OriginalDate) == (gExcp.OriginalStartTime.Date ?? GoogleCalendar.GoogleTimeFrom(DateTime.Parse(gExcp.OriginalStartTime.DateTime).Date))
                        ))
                    {
                        return(gExcp);
                    }
                }
            }
            log.Debug("Google exception event is not cached. Retrieving all recurring instances...");
            List <Event> gInstances = GoogleCalendar.Instance.GetCalendarEntriesInRecurrence(gRecurringEventID);

            //Add any new exceptions to local cache
            googleExceptions = googleExceptions.Union(gInstances.Where(ev => !String.IsNullOrEmpty(ev.RecurringEventId))).ToList();
            foreach (Event gInst in gInstances)
            {
                if (gInst.RecurringEventId == gRecurringEventID)
                {
                    if (((!oIsDeleted || (oIsDeleted && !oExcp.Deleted)) && /* Weirdness when exception is cancelled by organiser but not yet deleted/accepted by recipient */
                         GoogleCalendar.GoogleTimeFrom(oExcp.OriginalDate) == GoogleCalendar.GoogleTimeFrom(DateTime.Parse(gInst.OriginalStartTime.Date ?? gInst.OriginalStartTime.DateTime))
                         ) ||
                        (oIsDeleted &&
                         GoogleCalendar.GoogleTimeFrom(oExcp.OriginalDate) == GoogleCalendar.GoogleTimeFrom(DateTime.Parse(gInst.OriginalStartTime.Date ?? gInst.OriginalStartTime.DateTime).Date)
                        ))
                    {
                        return(gInst);
                    }
                }
            }
            return(null);
        }
예제 #7
0
 private static Boolean exceptionIsDeleted(Microsoft.Office.Interop.Outlook.Exception oExcp)
 {
     if (oExcp.Deleted)
     {
         return(true);
     }
     try {
         AppointmentItem ai = oExcp.AppointmentItem;
         return(false);
     } catch (System.Exception ex) {
         if (ex.Message == "You changed one of the recurrences of this item, and this instance no longer exists. Close any open items and try again.")
         {
             //log.Debug("This Outlook recurrence instance has been deleted, but the API is reporting it incorrectly due to caching");
             return(true);
         }
         else
         {
             log.Warn("Error when determining if Outlook recurrence is deleted or not.\r\n" + ex.Message);
             return(true);
         }
     }
 }
예제 #8
0
        public static void UpdateGoogleExceptions(AppointmentItem ai, Event ev, Boolean dirtyCache)
        {
            if (ai.IsRecurring)
            {
                RecurrencePattern rp    = null;
                Exceptions        excps = null;
                try {
                    rp    = ai.GetRecurrencePattern();
                    excps = rp.Exceptions;
                    if (excps.Count > 0)
                    {
                        log.Debug(OutlookOgcs.Calendar.GetEventSummary(ai));
                        log.Debug("This is a recurring appointment with " + excps.Count + " exceptions that will now be iteratively compared.");
                        for (int e = 1; e <= excps.Count; e++)
                        {
                            Microsoft.Office.Interop.Outlook.Exception oExcp = null;
                            AppointmentItem aiExcp = null;
                            try {
                                oExcp = excps[e];
                                int excp_itemModified = 0;

                                //Check the exception falls in the date range being synced
                                Boolean  oIsDeleted = exceptionIsDeleted(oExcp);
                                String   logDeleted = oIsDeleted ? " deleted and" : "";
                                DateTime oExcp_currDate;
                                if (oIsDeleted)
                                {
                                    oExcp_currDate = oExcp.OriginalDate;
                                }
                                else
                                {
                                    aiExcp         = oExcp.AppointmentItem;
                                    oExcp_currDate = aiExcp.Start;
                                    aiExcp         = (AppointmentItem)OutlookOgcs.Calendar.ReleaseObject(aiExcp);
                                }

                                if (oExcp_currDate < Settings.Instance.SyncStart.Date || oExcp_currDate > Settings.Instance.SyncEnd.Date)
                                {
                                    log.Fine("Exception is" + logDeleted + " outside date range being synced: " + oExcp_currDate.Date.ToString("dd/MM/yyyy"));
                                    continue;
                                }

                                Event gExcp = Recurrence.Instance.getGoogleInstance(ref oExcp, ev.RecurringEventId ?? ev.Id, OutlookOgcs.Calendar.Instance.IOutlook.GetGlobalApptID(ai), dirtyCache);
                                if (gExcp != null)
                                {
                                    log.Debug("Matching Google Event recurrence found.");
                                    if (gExcp.Status == "cancelled")
                                    {
                                        log.Debug("It is deleted in Google, so cannot compare items.");
                                        if (!oIsDeleted)
                                        {
                                            log.Warn("Outlook is NOT deleted though - a mismatch has occurred somehow!");
                                            String syncDirectionTip = (Settings.Instance.SyncDirection == Sync.Direction.Bidirectional) ? "<br/><i>Ensure you <b>first</b> set OGCS to one-way sync O->G.</i>" : "";
                                            Forms.Main.Instance.Console.Update(OutlookOgcs.Calendar.GetEventSummary(ai) + "<br/>" +
                                                                               "The occurrence on " + oExcp.OriginalDate.ToShortDateString() + " does not exist in Google, but does in Outlook.<br/>" +
                                                                               "This can happen if, for example, you declined the occurrence (which is synced to Google) and proposed a new time that is subsequently accepted by the organiser.<br/>" +
                                                                               "<u>Suggested fix</u>: delete the entire series in Google and let OGCS recreate it." + syncDirectionTip, Console.Markup.warning);
                                        }
                                        continue;
                                    }
                                    else if (oIsDeleted && gExcp.Status != "cancelled")
                                    {
                                        gExcp.Status = "cancelled";
                                        log.Debug("Exception deleted.");
                                        excp_itemModified++;
                                    }
                                    else
                                    {
                                        try {
                                            aiExcp = oExcp.AppointmentItem;
                                            //Force a compare of the exception if both G and O have been modified in last 24 hours
                                            TimeSpan modifiedDiff = (TimeSpan)(gExcp.Updated - aiExcp.LastModificationTime);
                                            log.Fine("Difference in days between G and O exception: " + modifiedDiff);
                                            Boolean forceCompare = modifiedDiff < TimeSpan.FromDays(1);
                                            GoogleOgcs.Calendar.Instance.UpdateCalendarEntry(aiExcp, gExcp, ref excp_itemModified, forceCompare);
                                        } catch (System.Exception ex) {
                                            log.Error(ex.Message);
                                            log.Error(ex.StackTrace);
                                            throw;
                                        }
                                    }
                                    if (excp_itemModified > 0)
                                    {
                                        try {
                                            GoogleOgcs.Calendar.Instance.UpdateCalendarEntry_save(ref gExcp);
                                        } catch (System.Exception ex) {
                                            Forms.Main.Instance.Console.UpdateWithError("Updated event exception failed to save.", ex);
                                            OGCSexception.Analyse(ex, true);
                                            if (OgcsMessageBox.Show("Updated Google event exception failed to save. Continue with synchronisation?", "Sync item failed", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                                            {
                                                continue;
                                            }
                                            else
                                            {
                                                throw new UserCancelledSyncException("User chose not to continue sync.");
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    log.Debug("No matching Google Event recurrence found.");
                                    if (oIsDeleted)
                                    {
                                        log.Debug("The Outlook appointment is deleted, so not a problem.");
                                    }
                                }
                            } finally {
                                aiExcp = (AppointmentItem)OutlookOgcs.Calendar.ReleaseObject(aiExcp);
                                oExcp  = (Microsoft.Office.Interop.Outlook.Exception)OutlookOgcs.Calendar.ReleaseObject(oExcp);
                            }
                        }
                    }
                } finally {
                    excps = (Exceptions)OutlookOgcs.Calendar.ReleaseObject(excps);
                    rp    = (RecurrencePattern)OutlookOgcs.Calendar.ReleaseObject(rp);
                }
            }
        }
예제 #9
0
        public static void CreateGoogleExceptions(AppointmentItem ai, String recurringEventId)
        {
            if (!ai.IsRecurring)
            {
                return;
            }

            log.Debug("Creating Google recurrence exceptions.");
            List <Event> gRecurrences = GoogleOgcs.Calendar.Instance.GetCalendarEntriesInRecurrence(recurringEventId);

            if (gRecurrences != null)
            {
                RecurrencePattern rp    = null;
                Exceptions        excps = null;
                try {
                    rp    = ai.GetRecurrencePattern();
                    excps = rp.Exceptions;
                    for (int e = 1; e <= excps.Count; e++)
                    {
                        Microsoft.Office.Interop.Outlook.Exception oExcp = null;
                        try {
                            oExcp = excps[e];
                            for (int g = 0; g < gRecurrences.Count; g++)
                            {
                                Event    ev        = gRecurrences[g];
                                DateTime gDate     = ev.OriginalStartTime.DateTime ?? DateTime.Parse(ev.OriginalStartTime.Date);
                                Boolean  isDeleted = exceptionIsDeleted(oExcp);
                                if (isDeleted && !ai.AllDayEvent)   //Deleted items get truncated?!
                                {
                                    gDate = gDate.Date;
                                }
                                if (oExcp.OriginalDate == gDate)
                                {
                                    if (isDeleted)
                                    {
                                        Forms.Main.Instance.Console.Update(GoogleOgcs.Calendar.GetEventSummary(ev), Console.Markup.calendar);
                                        Forms.Main.Instance.Console.Update("Recurrence deleted.");
                                        ev.Status = "cancelled";
                                        GoogleOgcs.Calendar.Instance.UpdateCalendarEntry_save(ref ev);
                                    }
                                    else
                                    {
                                        int   exceptionItemsModified = 0;
                                        Event modifiedEv             = GoogleOgcs.Calendar.Instance.UpdateCalendarEntry(oExcp.AppointmentItem, ev, ref exceptionItemsModified, forceCompare: true);
                                        if (exceptionItemsModified > 0)
                                        {
                                            GoogleOgcs.Calendar.Instance.UpdateCalendarEntry_save(ref modifiedEv);
                                        }
                                    }
                                    break;
                                }
                            }
                        } finally {
                            oExcp = (Microsoft.Office.Interop.Outlook.Exception)OutlookOgcs.Calendar.ReleaseObject(oExcp);
                        }
                    }
                } finally {
                    excps = (Exceptions)OutlookOgcs.Calendar.ReleaseObject(excps);
                    rp    = (RecurrencePattern)OutlookOgcs.Calendar.ReleaseObject(rp);
                }
            }
        }
예제 #10
0
        private Event getGoogleInstance(ref Microsoft.Office.Interop.Outlook.Exception oExcp, String gRecurringEventID, String oEntryID, Boolean dirtyCache)
        {
            Boolean oIsDeleted = exceptionIsDeleted(oExcp);

            log.Debug("Finding Google instance for " + (oIsDeleted ? "deleted " : "") + "Outlook exception:-");
            log.Debug("  Original date: " + oExcp.OriginalDate.ToString("dd/MM/yyyy"));
            if (!oIsDeleted)
            {
                AppointmentItem ai = null;
                try {
                    ai = oExcp.AppointmentItem;
                    log.Debug("  Current  date: " + ai.Start.ToString("dd/MM/yyyy"));
                } finally {
                    ai = (AppointmentItem)OutlookOgcs.Calendar.ReleaseObject(ai);
                }
            }
            if (dirtyCache)
            {
                log.Debug("Google exception cache not being used. Retrieving all recurring instances afresh...");
                //Remove dirty items
                googleExceptions.RemoveAll(ev => ev.RecurringEventId == gRecurringEventID);
            }
            else
            {
                foreach (Event gExcp in googleExceptions)
                {
                    if (gExcp.RecurringEventId == gRecurringEventID)
                    {
                        if ((!oIsDeleted &&
                             oExcp.OriginalDate == (gExcp.OriginalStartTime.DateTime ?? DateTime.Parse(gExcp.OriginalStartTime.Date))
                             ) ||
                            (oIsDeleted &&
                             oExcp.OriginalDate == (gExcp.OriginalStartTime.DateTime ?? DateTime.Parse(gExcp.OriginalStartTime.Date)).Date
                            ))
                        {
                            return(gExcp);
                        }
                    }
                }
                log.Debug("Google exception event is not cached. Retrieving all recurring instances...");
            }
            List <Event> gInstances = GoogleOgcs.Calendar.Instance.GetCalendarEntriesInRecurrence(gRecurringEventID);

            //Add any new exceptions to local cache
            googleExceptions = googleExceptions.Union(gInstances.Where(ev => !String.IsNullOrEmpty(ev.RecurringEventId))).ToList();
            foreach (Event gInst in gInstances)
            {
                if (gInst.RecurringEventId == gRecurringEventID)
                {
                    if (((!oIsDeleted || (oIsDeleted && !oExcp.Deleted)) && /* Weirdness when exception is cancelled by organiser but not yet deleted/accepted by recipient */
                         oExcp.OriginalDate == (gInst.OriginalStartTime.DateTime ?? DateTime.Parse(gInst.OriginalStartTime.Date))
                         ) ||
                        (oIsDeleted &&
                         oExcp.OriginalDate == (gInst.OriginalStartTime.DateTime ?? DateTime.Parse(gInst.OriginalStartTime.Date)).Date
                        ))
                    {
                        return(gInst);
                    }
                }
            }
            return(null);
        }
예제 #11
0
        public static void UpdateGoogleExceptions(AppointmentItem ai, Event ev, Boolean dirtyCache)
        {
            if (ai.IsRecurring)
            {
                RecurrencePattern rp    = null;
                Exceptions        excps = null;
                try {
                    rp    = ai.GetRecurrencePattern();
                    excps = rp.Exceptions;
                    if (excps.Count > 0)
                    {
                        log.Debug(OutlookCalendar.GetEventSummary(ai));
                        log.Debug("This is a recurring appointment with " + excps.Count + " exceptions that will now be iteratively compared.");
                        for (int e = 1; e <= excps.Count; e++)
                        {
                            Microsoft.Office.Interop.Outlook.Exception oExcp = null;
                            AppointmentItem aiExcp = null;
                            try {
                                oExcp = excps[e];
                                int excp_itemModified = 0;

                                //Check the exception falls in the date range being synced
                                Boolean  oIsDeleted = exceptionIsDeleted(oExcp);
                                String   logDeleted = oIsDeleted ? " deleted and" : "";
                                DateTime oExcp_currDate;
                                if (oIsDeleted)
                                {
                                    oExcp_currDate = oExcp.OriginalDate;
                                }
                                else
                                {
                                    aiExcp         = oExcp.AppointmentItem;
                                    oExcp_currDate = aiExcp.Start;
                                    aiExcp         = (AppointmentItem)OutlookCalendar.ReleaseObject(aiExcp);
                                }

                                if (oExcp_currDate < Settings.Instance.SyncStart.Date || oExcp_currDate > Settings.Instance.SyncEnd.Date)
                                {
                                    log.Fine("Exception is" + logDeleted + " outside date range being synced: " + oExcp_currDate.Date.ToString("dd/MM/yyyy"));
                                    continue;
                                }

                                Event gExcp = Recurrence.Instance.getGoogleInstance(ref oExcp, ev.RecurringEventId ?? ev.Id, OutlookCalendar.Instance.IOutlook.GetGlobalApptID(ai), dirtyCache);
                                if (gExcp != null)
                                {
                                    log.Debug("Matching Google Event recurrence found.");
                                    if (gExcp.Status == "cancelled")
                                    {
                                        log.Debug("It is deleted in Google, so cannot compare items.");
                                        if (!oIsDeleted)
                                        {
                                            log.Warn("Outlook is NOT deleted though - a mismatch has occurred somehow!");
                                        }
                                        continue;
                                    }
                                    else if (oIsDeleted && gExcp.Status != "cancelled")
                                    {
                                        gExcp.Status = "cancelled";
                                        log.Debug("Exception deleted.");
                                        excp_itemModified++;
                                    }
                                    else
                                    {
                                        try {
                                            aiExcp = oExcp.AppointmentItem;
                                            GoogleCalendar.Instance.UpdateCalendarEntry(aiExcp, gExcp, ref excp_itemModified);
                                        } catch (System.Exception ex) {
                                            log.Error(ex.Message);
                                            log.Error(ex.StackTrace);
                                            throw ex;
                                        }
                                    }
                                    if (excp_itemModified > 0)
                                    {
                                        try {
                                            GoogleCalendar.Instance.UpdateCalendarEntry_save(ref gExcp);
                                        } catch (System.Exception ex) {
                                            MainForm.Instance.Logboxout("WARNING: Updated event exception failed to save.\r\n" + ex.Message);
                                            log.Error(ex.StackTrace);
                                            if (MessageBox.Show("Updated Google event exception failed to save. Continue with synchronisation?", "Sync item failed", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                                            {
                                                continue;
                                            }
                                            else
                                            {
                                                throw new UserCancelledSyncException("User chose not to continue sync.");
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    log.Debug("No matching Google Event recurrence found.");
                                    if (oIsDeleted)
                                    {
                                        log.Debug("The Outlook appointment is deleted, so not a problem.");
                                    }
                                }
                            } finally {
                                aiExcp = (AppointmentItem)OutlookCalendar.ReleaseObject(aiExcp);
                                oExcp  = (Microsoft.Office.Interop.Outlook.Exception)OutlookCalendar.ReleaseObject(oExcp);
                            }
                        }
                    }
                } finally {
                    excps = (Exceptions)OutlookCalendar.ReleaseObject(excps);
                    rp    = (RecurrencePattern)OutlookCalendar.ReleaseObject(rp);
                }
            }
        }