private Event outlookToGoogleObject(Appointment appt)
        {
            AppointmentItem outAppt = outlookAppointments.Find(o => o.EntryID == appt.iCalUID);

            if (outAppt == null) //Deleted event
            {
                return(null);
            }

            Event googleAppointment = new Event();

            googleAppointment.Id             = appt.googleId;
            googleAppointment.ICalUID        = appt.iCalUID;
            googleAppointment.Summary        = outAppt.Subject;
            googleAppointment.Start          = new EventDateTime();
            googleAppointment.Start.DateTime = outAppt.Start;
            googleAppointment.Start.TimeZone = outAppt.StartTimeZone.Name;
            googleAppointment.End            = new EventDateTime();
            googleAppointment.End.DateTime   = outAppt.End;
            googleAppointment.End.TimeZone   = outAppt.EndTimeZone.Name;
            googleAppointment.Description    = outAppt.Body;
            googleAppointment.Location       = outAppt.Location;

            if (outAppt.IsRecurring)
            {
                googleAppointment.Recurrence = new String[] {
                    OutlookRecurrenceToGoogleRecurrence.convert(outAppt.GetRecurrencePattern())
                };
            }

            return(googleAppointment);
        }
        private void processOutlookExceptions(ref AppointmentItem ai, Event ev, Boolean forceCompare)
        {
            if (!HasExceptions(ev, checkLocalCacheOnly: true))
            {
                return;
            }

            RecurrencePattern oPattern = null;

            try {
                oPattern = ai.GetRecurrencePattern();
                foreach (Event gExcp in Recurrence.Instance.googleExceptions.Where(exp => exp.RecurringEventId == ev.Id))
                {
                    DateTime oExcpDate = gExcp.OriginalStartTime.DateTime ?? DateTime.Parse(gExcp.OriginalStartTime.Date);
                    log.Fine("Found Google exception for " + oExcpDate.ToString());

                    AppointmentItem newAiExcp = null;
                    try {
                        getOutlookInstance(oPattern, oExcpDate, ref newAiExcp);
                        if (newAiExcp == null)
                        {
                            continue;
                        }

                        if (gExcp.Status == "cancelled")
                        {
                            Forms.Main.Instance.Console.Update(OutlookOgcs.Calendar.GetEventSummary(newAiExcp) + "<br/>Deleted.", Console.Markup.calendar);
                            newAiExcp.Delete();
                        }
                        else if (Settings.Instance.ExcludeDeclinedInvites && gExcp.Attendees != null && gExcp.Attendees.Count(a => a.Self == true && a.ResponseStatus == "declined") == 1)
                        {
                            Forms.Main.Instance.Console.Update(OutlookOgcs.Calendar.GetEventSummary(newAiExcp) + "<br/>Declined.", Console.Markup.calendar);
                            newAiExcp.Delete();
                        }
                        else
                        {
                            int itemModified = 0;
                            OutlookOgcs.Calendar.Instance.UpdateCalendarEntry(ref newAiExcp, gExcp, ref itemModified, forceCompare);
                            if (itemModified > 0)
                            {
                                try {
                                    newAiExcp.Save();
                                } catch (System.Exception ex) {
                                    OGCSexception.Analyse(ex);
                                    if (ex.Message == "Cannot save this item.")
                                    {
                                        Forms.Main.Instance.Console.Update("Uh oh! Outlook wasn't able to save this recurrence exception! " +
                                                                           "You may have two occurences on the same day, which it doesn't allow.", Console.Markup.warning);
                                    }
                                }
                            }
                        }
                    } finally {
                        newAiExcp = (AppointmentItem)OutlookOgcs.Calendar.ReleaseObject(newAiExcp);
                    }
                }
            } finally {
                oPattern = (RecurrencePattern)OutlookOgcs.Calendar.ReleaseObject(oPattern);
            }
        }
Пример #3
0
        public static void CreateGoogleExceptions(AppointmentItem ai, String recurringEventId)
        {
            if (!ai.IsRecurring) return;

            log.Debug("Creating Google recurrence exceptions.");
            List<Event> gRecurrences = GoogleCalendar.Instance.GetCalendarEntriesInRecurrence(recurringEventId);
            if (gRecurrences != null) {
                Microsoft.Office.Interop.Outlook.Exceptions exps = ai.GetRecurrencePattern().Exceptions;
                foreach (Microsoft.Office.Interop.Outlook.Exception oExcp in exps) {
                    for (int g = 0; g < gRecurrences.Count; g++) {
                        Event ev = gRecurrences[g];
                        String gDate = ev.OriginalStartTime.DateTime ?? ev.OriginalStartTime.Date;
                        Boolean isDeleted = exceptionIsDeleted(oExcp);
                        if (isDeleted && !ai.AllDayEvent) { //Deleted items get truncated?!
                            gDate = GoogleCalendar.GoogleTimeFrom(DateTime.Parse(gDate).Date);
                        }
                        if (oExcp.OriginalDate == DateTime.Parse(gDate)) {
                            if (isDeleted) {
                                MainForm.Instance.Logboxout(GoogleCalendar.GetEventSummary(ev));
                                MainForm.Instance.Logboxout("Recurrence deleted.");
                                ev.Status = "cancelled";
                                GoogleCalendar.Instance.UpdateCalendarEntry_save(ref ev);
                            } else {
                                int exceptionItemsModified = 0;
                                Event modifiedEv = GoogleCalendar.Instance.UpdateCalendarEntry(oExcp.AppointmentItem, ev, ref exceptionItemsModified, forceCompare: true);
                                if (exceptionItemsModified > 0) {
                                    GoogleCalendar.Instance.UpdateCalendarEntry_save(ref modifiedEv);
                                }
                            }
                            break;
                        }
                    }
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Gets the Outlook AppointmentItem representation of this CalendarItem
        /// </summary>
        /// <param name="item">The AppointmentItem to edit</param>
        /// <returns>An Outlook AppointmentItem representation of this CalendarItem</returns>
        public AppointmentItem GetOutlookAppointment(AppointmentItem item)
        {
            try
            {
                item.Start       = DateTime.Parse(Start);
                item.End         = DateTime.Parse(End);
                item.Location    = Location;
                item.Body        = Body;
                item.Subject     = Subject;
                item.AllDayEvent = IsAllDayEvent;

                Microsoft.Office.Interop.Outlook.TimeZone startTz = OutlookSync.Syncer.CurrentApplication.TimeZones[TimeZoneConverter.IanaToWindows(StartTimeZone)];
                Microsoft.Office.Interop.Outlook.TimeZone endTz   = OutlookSync.Syncer.CurrentApplication.TimeZones[TimeZoneConverter.IanaToWindows(EndTimeZone)];

                item.StartTimeZone = startTz;
                item.EndTimeZone   = endTz;

                if (!m_isUsingDefaultReminders)
                {
                    item.ReminderMinutesBeforeStart = ReminderTime;
                    item.ReminderSet = true;
                }

                if (Recurrence != null)
                {
                    var pattern = item.GetRecurrencePattern();
                    Recurrence.GetOutlookPattern(ref pattern, IsAllDayEvent);
                }

                foreach (var attendee in Attendees)
                {
                    var  recipt = item.Recipients.Add(attendee.Name);
                    bool result = recipt.Resolve();

                    if (!result)
                    {
                        ContactItem contact = new ContactItem(attendee.Name, attendee.Email);
                        result = contact.CreateContact();
                    }

                    result &= recipt.Resolve();
                    if (result)
                    {
                        recipt.AddressEntry.Address = attendee.Email;
                        recipt.Type = attendee.Required
                            ? (int)OlMeetingRecipientType.olRequired
                            : (int)OlMeetingRecipientType.olOptional;
                    }
                }

                return(item);
            } catch (COMException ex)
            {
                Log.Write(ex);
                MessageBox.Show(
                    "CalendarItem: There has been an error when trying to create a outlook appointment item from a CalendarItem.", "Unknown Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            return(null);
        }
Пример #5
0
        private void processOutlookExceptions(AppointmentItem ai, Event ev, Boolean forceCompare)
        {
            if (!HasExceptions(ev, checkLocalCacheOnly: true))
            {
                return;
            }

            if (!ai.Saved)
            {
                ai.Save();
            }

            RecurrencePattern oPattern = ai.GetRecurrencePattern();

            foreach (Event gExcp in Recurrence.Instance.googleExceptions.Where(exp => exp.RecurringEventId == ev.Id))
            {
                log.Fine("Found Google exception for " + (gExcp.OriginalStartTime.DateTime ?? gExcp.OriginalStartTime.Date));

                DateTime        oExcpDate = DateTime.Parse(gExcp.OriginalStartTime.DateTime ?? gExcp.OriginalStartTime.Date);
                AppointmentItem newAiExcp = getOutlookInstance(oPattern, oExcpDate);
                if (newAiExcp == null)
                {
                    continue;
                }

                if (gExcp.Status != "cancelled")
                {
                    int itemModified = 0;
                    newAiExcp = OutlookCalendar.Instance.UpdateCalendarEntry(newAiExcp, gExcp, ref itemModified, forceCompare);
                    if (itemModified > 0)
                    {
                        try {
                            newAiExcp.Save();
                        } catch (System.Exception ex) {
                            log.Warn(ex.Message);
                            if (ex.Message == "Cannot save this item.")
                            {
                                MainForm.Instance.Logboxout("Uh oh! Outlook wasn't able to save this recurrence exception! " +
                                                            "You may have two occurences on the same day, which it doesn't allow.");
                            }
                        }
                    }
                }
                else
                {
                    MainForm.Instance.Logboxout(OutlookCalendar.GetEventSummary(ai) + "\r\nDeleted.");
                    newAiExcp.Delete();
                }
                newAiExcp = (AppointmentItem)OutlookCalendar.ReleaseObject(newAiExcp);
            }
            if (!ai.Saved)
            {
                ai.Save();
            }
            oPattern = (RecurrencePattern)OutlookCalendar.ReleaseObject(oPattern);
        }
        public List<String> BuildGooglePattern(AppointmentItem ai, Event ev) {
            if (!ai.IsRecurring || ai.RecurrenceState != OlRecurrenceState.olApptMaster) return null;

            log.Debug("Creating Google iCalendar definition for recurring event.");
            List<String> gPattern = new List<String>();
            gPattern.Add("RRULE:" + buildRrule(ai.GetRecurrencePattern()));

            log.Debug(string.Join("\r\n", gPattern.ToArray()));
            return gPattern;
        }
Пример #7
0
        /// <summary>
        /// Merges the recurrence.
        /// </summary>
        /// <param name="outlookCalendarItem">The outlook calendar item.</param>
        /// <param name="recurrence">The recurrence.</param>
        /// <returns>True if Change.</returns>
        public static bool MergeRecurrence(this AppointmentItem outlookCalendarItem, Recurrence recurrence)
        {
            if (recurrence != null && !string.IsNullOrWhiteSpace(recurrence.Value))
            {
                var result = false;
                var outlookRecurrencePattern = outlookCalendarItem.GetRecurrencePattern();
                var googleRecurrencePattern  = RecurrenceSerializer.Deserialize(recurrence.Value);

                try { result |= outlookCalendarItem.ApplyProperty(r => r.AllDayEvent, googleRecurrencePattern.AllDayEvent); } catch (TargetInvocationException) { }
                result |= outlookRecurrencePattern.ApplyProperty(r => r.RecurrenceType, googleRecurrencePattern.RecurrenceType);
                result |= outlookRecurrencePattern.ApplyProperty(r => r.PatternStartDate, googleRecurrencePattern.StartPattern.HasValue ? googleRecurrencePattern.StartPattern.Value.Date : DateTime.Today);
                if (googleRecurrencePattern.EndPattern.HasValue)
                {
                    result |= outlookRecurrencePattern.ApplyProperty(r => r.PatternEndDate, googleRecurrencePattern.EndPattern.Value.Date);
                }
                else
                {
                    result |= outlookRecurrencePattern.ApplyProperty(r => r.NoEndDate, true);
                }

                result |= outlookRecurrencePattern.ApplyProperty(r => r.DayOfMonth, googleRecurrencePattern.DayOfMonth);
                result |= outlookRecurrencePattern.ApplyProperty(r => r.DayOfWeekMask, googleRecurrencePattern.DayOfWeek);
                result |= outlookRecurrencePattern.ApplyProperty(r => r.MonthOfYear, googleRecurrencePattern.MonthOfYear);

                if (outlookRecurrencePattern.StartTime.TimeOfDay.Ticks != googleRecurrencePattern.StartTime.TimeOfDay.Ticks)
                {
                    result |= outlookRecurrencePattern.ApplyProperty(r => r.StartTime, googleRecurrencePattern.StartTime);
                }

                if (outlookRecurrencePattern.EndTime.TimeOfDay.Ticks != googleRecurrencePattern.EndTime.TimeOfDay.Ticks)
                {
                    result |= outlookRecurrencePattern.ApplyProperty(r => r.EndTime, googleRecurrencePattern.EndTime);
                }

                if (googleRecurrencePattern.Count.HasValue)
                {
                    result |= outlookRecurrencePattern.ApplyProperty(r => r.Occurrences, googleRecurrencePattern.Count.Value);
                }

                if (googleRecurrencePattern.Interval.HasValue)
                {
                    result |= outlookRecurrencePattern.ApplyProperty(r => r.Interval, googleRecurrencePattern.Interval.Value);
                }

                return(result);
            }

            if (outlookCalendarItem.RecurrenceState == OlRecurrenceState.olApptNotRecurring)
            {
                outlookCalendarItem.ClearRecurrencePattern();
                return(true);
            }

            return(false);
        }
Пример #8
0
        //internal EventSchedule(Event googleItem, List<Event> recurrenceExceptions = null)
        //{
        //    this.AllDayEvent = !string.IsNullOrEmpty(googleItem.Start.Date);
        //    this.TimeZone = googleItem.Start.TimeZone;
        //    if (this.AllDayEvent)
        //    {
        //        this.StartTime = DateTime.Parse(googleItem.Start.Date);
        //        this.EndTime = DateTime.Parse(googleItem.End.Date);
        //    } else
        //    {
        //        this.StartTime = googleItem.Start.DateTime.Value;
        //        this.EndTime = googleItem.End.DateTime.Value;
        //    }
        //    if (googleItem.Recurrence != null)
        //    {
        //        this.RecurrencePattern = new EventRecurrence(googleItem, recurrenceExceptions);
        //    }
        //}

        internal EventSchedule(AppointmentItem outlookItem)
        {
            this.StartTime   = outlookItem.Start;
            this.EndTime     = outlookItem.End;
            this.AllDayEvent = outlookItem.AllDayEvent;
            this.TimeZone    = outlookItem.StartTimeZone.ID;
            if (outlookItem.IsRecurring && (outlookItem.RecurrenceState == OlRecurrenceState.olApptMaster))
            {
                this.RecurrencePattern = new EventRecurrence(outlookItem.GetRecurrencePattern());
            }
        }
Пример #9
0
        public void TestReplaceCalendar()
        {
            Application             app          = new Application();
            OutlookCalendarWithSifE agent        = new OutlookCalendarWithSifE(app);
            OutlookCalendar         outlookAgent = new OutlookCalendar(app, CalendarPeriod.All);


            string existingEntryId = AddCalendar();

            XElement x       = XElement.Load(MockPath + "SifE.xml");
            string   entryId = agent.ReplaceItem(x.ToString(), existingEntryId);

            Assert.IsTrue(entryId == existingEntryId);

            AppointmentItem appointment = outlookAgent.GetItemByEntryId(entryId);

            Assert.AreEqual(appointment.Subject, x.Element("Subject").Value);
            Assert.AreEqual(((int)appointment.BusyStatus).ToString(), x.Element("BusyStatus").Value);
            Assert.AreEqual(appointment.Categories, x.Element("Categories").Value);
            Assert.AreEqual(appointment.Companies, x.Element("Companies").Value);
            Assert.AreEqual(((int)appointment.Importance).ToString(), x.Element("Importance").Value);
            Assert.AreEqual(appointment.AllDayEvent, x.Element("AllDayEvent").Value == "0"?false:true);
            //   Assert.AreEqual(appointment.IsRecurring, x.Element("IsRecurring").Value=="0"?false:true);no need to check recurring events in sync.
            Assert.AreEqual(appointment.Location, x.Element("Location").Value);
            Assert.AreEqual(((int)appointment.MeetingStatus).ToString(), x.Element("MeetingStatus").Value);
            Assert.AreEqual(appointment.Mileage, x.Element("Mileage").Value);
            Assert.AreEqual(appointment.ReminderMinutesBeforeStart.ToString(), x.Element("ReminderMinutesBeforeStart").Value);
            Assert.AreEqual(appointment.ReminderSet, x.Element("ReminderSet").Value == "0"?false:true);
            Assert.AreEqual(appointment.ReminderSoundFile, x.Element("ReminderSoundFile").Value);
            Assert.AreEqual(DataUtility.DateTimeToIsoText(appointment.ReplyTime.ToUniversalTime()), x.Element("ReplyTime").Value);
            //     Assert.AreEqual(((int)appointment.Sensitivity).ToString(), x.Element("Sensitivity").Value);

            if (appointment.IsRecurring)
            {
                Microsoft.Office.Interop.Outlook.RecurrencePattern pattern = appointment.GetRecurrencePattern();
                Assert.AreEqual(pattern.Interval.ToString(), x.Element("Interval").Value);
                Assert.AreEqual(pattern.MonthOfYear.ToString(), x.Element("MonthOfYear").Value);
                Assert.AreEqual(pattern.DayOfMonth.ToString(), x.Element("DayOfMonth").Value);
                Assert.AreEqual(((int)pattern.DayOfWeekMask).ToString(), x.Element("DayOfWeekMask").Value);
                Assert.AreEqual(pattern.Instance.ToString(), x.Element("Instance").Value);
                Assert.AreEqual(DataUtility.DateTimeToIsoText(pattern.PatternStartDate), x.Element("PatternStartDate").Value);
                Assert.AreEqual(DataUtility.DateTimeToIsoText(pattern.PatternEndDate), x.Element("PatternEndDate").Value);
                Assert.AreEqual(pattern.NoEndDate, x.Element("NoEndDate").Value == "0" ? false : true);
                //     Assert.AreEqual(pattern.Occurrences.ToString(), x.Element("Occurrences").Value); no need to test
            }
            else
            {
                Assert.AreEqual(appointment.Start.ToUniversalTime().ToString("yyyyMMddTHHmmssZ"), x.Element("Start").Value);
                Assert.AreEqual(appointment.End.ToUniversalTime().ToString("yyyyMMddTHHmmssZ"), x.Element("End").Value);
            }
        }
Пример #10
0
        public void CompareOutlookPattern(Event ev, AppointmentItem ai, SyncDirection syncDirection, System.Text.StringBuilder sb, ref int itemModified)
        {
            if (ev.Recurrence == null)
            {
                return;
            }

            log.Fine("Building a temporary recurrent Appointment generated from Event");
            AppointmentItem evAI = OutlookCalendar.Instance.IOutlook.UseOutlookCalendar().Items.Add() as AppointmentItem;

            evAI.Start = DateTime.Parse(ev.Start.Date ?? ev.Start.DateTime);
            RecurrencePattern evOpattern;
            RecurrencePattern aiOpattern = ai.GetRecurrencePattern();

            BuildOutlookPattern(ev, evAI, out evOpattern);
            log.Fine("Comparing Google recurrence to Outlook equivalent");

            if (MainForm.CompareAttribute("Recurrence Type", syncDirection,
                                          evOpattern.RecurrenceType.ToString(), aiOpattern.RecurrenceType.ToString(), sb, ref itemModified))
            {
                aiOpattern.RecurrenceType = evOpattern.RecurrenceType;
            }
            if (MainForm.CompareAttribute("Recurrence Occurences", syncDirection,
                                          evOpattern.Occurrences.ToString(), aiOpattern.Occurrences.ToString(), sb, ref itemModified))
            {
                aiOpattern.Occurrences = evOpattern.Occurrences;
            }
            if (MainForm.CompareAttribute("Recurrence Interval", syncDirection,
                                          evOpattern.Interval.ToString(), aiOpattern.Interval.ToString(), sb, ref itemModified))
            {
                aiOpattern.Interval = evOpattern.Interval;
            }
            if (MainForm.CompareAttribute("Recurrence Instance", syncDirection,
                                          evOpattern.Instance.ToString(), aiOpattern.Instance.ToString(), sb, ref itemModified))
            {
                aiOpattern.Instance = evOpattern.Instance;
            }
            if (MainForm.CompareAttribute("Recurrence DoW", syncDirection,
                                          evOpattern.DayOfWeekMask.ToString(), aiOpattern.DayOfWeekMask.ToString(), sb, ref itemModified))
            {
                aiOpattern.DayOfWeekMask = evOpattern.DayOfWeekMask;
            }
            if (MainForm.CompareAttribute("Recurrence MoY", syncDirection,
                                          evOpattern.MonthOfYear.ToString(), aiOpattern.MonthOfYear.ToString(), sb, ref itemModified))
            {
                aiOpattern.MonthOfYear = evOpattern.MonthOfYear;
            }
            aiOpattern = (RecurrencePattern)OutlookCalendar.ReleaseObject(aiOpattern);
            evOpattern = (RecurrencePattern)OutlookCalendar.ReleaseObject(evOpattern);
            evAI       = (AppointmentItem)OutlookCalendar.ReleaseObject(evAI);
        }
Пример #11
0
        internal void GetOutlookRecurrence(AppointmentItem outlookItem)
        {
            RecurrencePattern outlookRec = outlookItem.GetRecurrencePattern();

            if (!this.AllDayEvent)
            {
                /// Set time of the event taking consideration difference of time zones.
                /// This makes sense only in case the event isn't all day one
                /// Google event time is already converted to local time zone
                var googleTimeZone  = TimeZoneInfo.Local;
                var outlookTimeZone = TimeZoneInfo.FindSystemTimeZoneById(outlookItem.StartTimeZone.ID);
                /// StartTime property contains only time (not date)
                outlookRec.StartTime = TimeZoneInfo.ConvertTime(this.StartTime, googleTimeZone, outlookTimeZone);
            }

            outlookRec.Duration       = (int)(this.EndTime - this.StartTime).TotalMinutes;
            outlookRec.RecurrenceType = (OlRecurrenceType)this.RecurrencePattern.Frequency;
            if ((this.RecurrencePattern.Frequency == RecurrenceFrequency.Weekly) || (this.RecurrencePattern.Frequency == RecurrenceFrequency.MonthlyNth))
            {
                outlookRec.DayOfWeekMask = (OlDaysOfWeek)this.RecurrencePattern.DayOfWeekMask;
            }
            if (this.RecurrencePattern.Interval > 1)
            {
                if ((outlookRec.RecurrenceType != OlRecurrenceType.olRecursYearly) || (VSTO.Properties.Settings.Default.OutlookVersion >= 14))
                {
                    outlookRec.Interval = this.RecurrencePattern.Interval;
                }
            }
            outlookRec.PatternStartDate = this.RecurrencePattern.StartDate;
            if (this.RecurrencePattern.EndMethod == EndBy.Date)
            {
                outlookRec.PatternEndDate = this.RecurrencePattern.EndDate;
            }
            if (this.RecurrencePattern.EndMethod == EndBy.OccurencesCount)
            {
                outlookRec.Occurrences = this.RecurrencePattern.Count;
            }
            if ((this.RecurrencePattern.Frequency == RecurrenceFrequency.Monthly) || (this.RecurrencePattern.Frequency == RecurrenceFrequency.Yearly))
            {
                outlookRec.DayOfMonth = this.RecurrencePattern.DayOfMonth;
            }
            /// As it was found out RecurrencePattern.Instance is valid for olRecursMonthNth only.
            /// Not sure yet whether Google provides such frequency model. If not - it will be just omited
            //outlookRec.Instance = this.WeekInterval;
            if (this.RecurrencePattern.Frequency == RecurrenceFrequency.Yearly)
            {
                outlookRec.MonthOfYear = this.RecurrencePattern.Month;
            }
            //outlookRec.NoEndDate = this.EndMethod == EndBy.NoEnd;
        }
Пример #12
0
        public static Boolean HasExceptions(AppointmentItem ai)
        {
            RecurrencePattern rp    = null;
            Exceptions        excps = null;

            try {
                rp    = ai.GetRecurrencePattern();
                excps = rp.Exceptions;
                return(excps.Count != 0);
            } finally {
                excps = (Exceptions)OutlookOgcs.Calendar.ReleaseObject(excps);
                rp    = (RecurrencePattern)OutlookOgcs.Calendar.ReleaseObject(rp);
            }
        }
Пример #13
0
        public List <String> BuildGooglePattern(AppointmentItem ai, Event ev)
        {
            if (!ai.IsRecurring || ai.RecurrenceState != OlRecurrenceState.olApptMaster)
            {
                return(null);
            }

            log.Debug("Creating Google iCalendar definition for recurring event.");
            List <String> gPattern = new List <String>();

            gPattern.Add("RRULE:" + buildRrule(ai.GetRecurrencePattern()));

            log.Debug(string.Join("\r\n", gPattern.ToArray()));
            return(gPattern);
        }
Пример #14
0
 public AppointmentSchedule(AppointmentItem appointment)
 {
     _appointment = appointment;
     if (appointment.IsRecurring && appointment.RecurrenceState == OlRecurrenceState.olApptMaster)
     {
         try
         {
             Recurrence = new AppointmentRecurrence(_appointment.GetRecurrencePattern());
         }
         catch (ArgumentOutOfRangeException ex)
         {
             Logger.Warning(ex.Message);
         }
     }
 }
Пример #15
0
        public static void CreateGoogleExceptions(AppointmentItem ai, String recurringEventId)
        {
            if (!ai.IsRecurring)
            {
                return;
            }

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

            if (gRecurrences != null)
            {
                Microsoft.Office.Interop.Outlook.Exceptions exps = ai.GetRecurrencePattern().Exceptions;
                foreach (Microsoft.Office.Interop.Outlook.Exception oExcp in exps)
                {
                    for (int g = 0; g < gRecurrences.Count; g++)
                    {
                        Event   ev        = gRecurrences[g];
                        String  gDate     = ev.OriginalStartTime.DateTime ?? ev.OriginalStartTime.Date;
                        Boolean isDeleted = exceptionIsDeleted(oExcp);
                        if (isDeleted && !ai.AllDayEvent)   //Deleted items get truncated?!
                        {
                            gDate = GoogleCalendar.GoogleTimeFrom(DateTime.Parse(gDate).Date);
                        }
                        if (oExcp.OriginalDate == DateTime.Parse(gDate))
                        {
                            if (isDeleted)
                            {
                                MainForm.Instance.Logboxout(GoogleCalendar.GetEventSummary(ev));
                                MainForm.Instance.Logboxout("Recurrence deleted.");
                                ev.Status = "cancelled";
                                GoogleCalendar.Instance.UpdateCalendarEntry_save(ref ev);
                            }
                            else
                            {
                                int   exceptionItemsModified = 0;
                                Event modifiedEv             = GoogleCalendar.Instance.UpdateCalendarEntry(oExcp.AppointmentItem, ev, ref exceptionItemsModified, forceCompare: true);
                                if (exceptionItemsModified > 0)
                                {
                                    GoogleCalendar.Instance.UpdateCalendarEntry_save(ref modifiedEv);
                                }
                            }
                            break;
                        }
                    }
                }
            }
        }
Пример #16
0
        private void processOutlookExceptions(AppointmentItem ai, Event ev, Boolean forceCompare)
        {
            if (!HasExceptions(ev, checkLocalCacheOnly: true))
            {
                return;
            }

            if (!ai.Saved)
            {
                ai.Save();
            }

            RecurrencePattern oPattern = ai.GetRecurrencePattern();

            foreach (Event gExcp in Recurrence.Instance.googleExceptions.Where(exp => exp.RecurringEventId == ev.Id))
            {
                log.Fine("Found Google exception for " + (gExcp.OriginalStartTime.DateTime ?? gExcp.OriginalStartTime.Date));

                DateTime        oExcpDate = DateTime.Parse(gExcp.OriginalStartTime.DateTime ?? gExcp.OriginalStartTime.Date);
                AppointmentItem newAiExcp = getOutlookInstance(oPattern, oExcpDate);
                if (newAiExcp == null)
                {
                    continue;
                }

                if (gExcp.Status != "cancelled")
                {
                    int itemModified = 0;
                    newAiExcp = OutlookCalendar.Instance.UpdateCalendarEntry(newAiExcp, gExcp, ref itemModified, forceCompare);
                    if (itemModified > 0)
                    {
                        newAiExcp.Save();
                    }
                }
                else
                {
                    MainForm.Instance.Logboxout(OutlookCalendar.GetEventSummary(ai) + "\r\nDeleted.");
                    newAiExcp.Delete();
                }
                newAiExcp = (AppointmentItem)OutlookCalendar.ReleaseObject(newAiExcp);
            }
            if (!ai.Saved)
            {
                ai.Save();
            }
            oPattern = (RecurrencePattern)OutlookCalendar.ReleaseObject(oPattern);
        }
Пример #17
0
        public static void DeleteEventOutlook(CancelMeetingRoomForm data)
        {
            try
            {
                Application app = new Application();

                MAPIFolder        calendar      = app.Session.GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
                Items             calendarItems = calendar.Items;
                AppointmentItem   item          = calendarItems["Test Appointment"] as AppointmentItem;
                RecurrencePattern pattern       = item.GetRecurrencePattern();
                AppointmentItem   itemDelete    = pattern.GetOccurrence(new DateTime(2006, 6, 28, 8, 0, 0));

                if (itemDelete != null)
                {
                    itemDelete.Delete();
                }
            }
            catch (System.Exception)
            {
            }
        }
Пример #18
0
        public List <String> BuildGooglePattern(AppointmentItem ai, Event ev)
        {
            if (!ai.IsRecurring || ai.RecurrenceState != OlRecurrenceState.olApptMaster)
            {
                return(null);
            }

            log.Debug("Creating Google iCalendar definition for recurring event.");
            List <String>     gPattern = new List <String>();
            RecurrencePattern rp       = null;

            try {
                rp = ai.GetRecurrencePattern();
                DateTime localEnd = rp.PatternEndDate + ai.EndInEndTimeZone.TimeOfDay;
                DateTime utcEnd   = TimeZoneInfo.ConvertTimeToUtc(localEnd, TimeZoneInfo.FindSystemTimeZoneById(ai.EndTimeZone.ID));
                gPattern.Add("RRULE:" + buildRrule(rp, utcEnd));
            } finally {
                rp = (RecurrencePattern)OutlookOgcs.Calendar.ReleaseObject(rp);
            }
            log.Debug(string.Join("\r\n", gPattern.ToArray()));
            return(gPattern);
        }
Пример #19
0
        public static void AddItemCalendar(List <BirthdayItem> listItem, int hour_begin, int min_begin, int duration, int remind_min)
        {
            Application Application = null;

            Application = new Application();
            MAPIFolder primaryCalendar = Application.ActiveExplorer().Session.GetDefaultFolder(OlDefaultFolders.olFolderCalendar);

            foreach (var item in listItem)
            {
                //var personalCalendar = primaryCalendar.Folders["Birthday"];
                //if (personalCalendar == null) return;

                AppointmentItem newEvent = primaryCalendar.Items.Add(OlItemType.olAppointmentItem) as AppointmentItem;
                //AppointmentItem newEvent = personalCalendar.Items.Add(OlItemType.olAppointmentItem) as AppointmentItem;
                if (newEvent != null)
                {
                    var date = new DateTime(DateTime.Now.Year, item.Birthday.Month, item.Birthday.Day, hour_begin, min_begin, 0);
                    newEvent.Start = date;
                    //newEvent.End = item.EndDateTime;

                    var recur = newEvent.GetRecurrencePattern();
                    recur.RecurrenceType = OlRecurrenceType.olRecursYearly;

                    recur.PatternStartDate = date;
                    recur.StartTime        = date;
                    recur.Duration         = duration;
                    recur.NoEndDate        = true;
                    //recur.EndTime = DateTime.Now.AddMinutes(10);
                    newEvent.ReminderMinutesBeforeStart = remind_min;
                    newEvent.Subject = $"[B] День рождения {item.Name}";
                    newEvent.Body    = $"День рождения {item.Name}. Дата рождения {item.Birthday:d}";
                    newEvent.Save();
                    AddProcProgressBar?.Invoke(null, null);
                }
            }
            Application.ActiveExplorer().CurrentFolder.Display();
        }
        private void buildOutlookPattern(Event ev, AppointmentItem ai, out RecurrencePattern oPattern)
        {
            if (ev.Recurrence == null)
            {
                oPattern = null; return;
            }

            Dictionary <String, String> ruleBook = explodeRrule(ev.Recurrence);

            if (ruleBook == null)
            {
                throw new ApplicationException("WARNING: The recurrence pattern is not compatible with Outlook. This event cannot be synced.");
            }
            log.Fine("Building Outlook recurrence pattern");
            oPattern = ai.GetRecurrencePattern();

            #region RECURRENCE PATTERN
            //RRULE:FREQ=WEEKLY;UNTIL=20150906T000000Z;BYDAY=SA

            switch (ruleBook["FREQ"])
            {
            case "DAILY": {
                oPattern.RecurrenceType = OlRecurrenceType.olRecursDaily;
                break;
            }

            case "WEEKLY": {
                oPattern.RecurrenceType = OlRecurrenceType.olRecursWeekly;
                // Need to work out dayMask from "BY" pattern
                // Eg "BYDAY=MO,TU,WE,TH,FR"
                OlDaysOfWeek dowMask = getDOWmask(ruleBook);
                if (dowMask != 0)
                {
                    oPattern.DayOfWeekMask = dowMask;
                }
                break;
            }

            case "MONTHLY": {
                oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthly;
                if (ruleBook.ContainsKey("BYSETPOS"))
                {
                    oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth;
                    int gInstance = Convert.ToInt16(ruleBook["BYSETPOS"]);
                    oPattern.Instance      = (gInstance == -1) ? 5 : gInstance;
                    oPattern.DayOfWeekMask = getDOWmask(ruleBook);
                    if (oPattern.DayOfWeekMask == (OlDaysOfWeek)127 && gInstance == -1 &&
                        (ev.Start.DateTime ?? DateTime.Parse(ev.Start.Date)).Day > 28)
                    {
                        //In Outlook this is simply a monthly recurring
                        oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthly;
                    }
                }
                if (ruleBook.ContainsKey("BYDAY"))
                {
                    if (ruleBook["BYDAY"].StartsWith("-1"))
                    {
                        oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth;
                        oPattern.Instance       = 5;
                        oPattern.DayOfWeekMask  = getDOWmask(ruleBook["BYDAY"].TrimStart("-1".ToCharArray()));
                    }
                    else if ("1,2,3,4".Contains(ruleBook["BYDAY"].Substring(0, 1)))
                    {
                        oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth;
                        oPattern.Instance       = Convert.ToInt16(ruleBook["BYDAY"].Substring(0, 1));
                        oPattern.DayOfWeekMask  = getDOWmask(ruleBook["BYDAY"].TrimStart(oPattern.Instance.ToString().ToCharArray()));
                    }
                }
                break;
            }

            case "YEARLY": {
                oPattern.RecurrenceType = OlRecurrenceType.olRecursYearly;
                //Google interval is years, Outlook is months
                if (ruleBook.ContainsKey("INTERVAL") && Convert.ToInt16(ruleBook["INTERVAL"]) > 1)
                {
                    oPattern.Interval = Convert.ToInt16(ruleBook["INTERVAL"]) * 12;
                }
                if (ruleBook.ContainsKey("BYSETPOS"))
                {
                    oPattern.RecurrenceType = OlRecurrenceType.olRecursYearNth;
                    int gInstance = Convert.ToInt16(ruleBook["BYSETPOS"]);
                    oPattern.Instance = (gInstance == -1) ? 5 : gInstance;

                    oPattern.DayOfWeekMask = getDOWmask(ruleBook);
                    if (ruleBook.ContainsKey("BYMONTH"))
                    {
                        oPattern.MonthOfYear = Convert.ToInt16(ruleBook["BYMONTH"]);
                    }
                }
                break;
            }
            }
            #endregion

            #region RANGE
            ai = OutlookOgcs.Calendar.Instance.IOutlook.WindowsTimeZone_set(ai, ev);
            oPattern.PatternStartDate = ev.Start.DateTime ?? DateTime.Parse(ev.Start.Date);
            if (ruleBook.ContainsKey("INTERVAL") && Convert.ToInt16(ruleBook["INTERVAL"]) > 1 && ruleBook["FREQ"] != "YEARLY")
            {
                oPattern.Interval = Convert.ToInt16(ruleBook["INTERVAL"]);
            }
            if (ruleBook.ContainsKey("COUNT"))
            {
                oPattern.Occurrences = Convert.ToInt16(ruleBook["COUNT"]);
            }
            if (ruleBook.ContainsKey("UNTIL"))
            {
                if (ruleBook["UNTIL"].StartsWith("4500"))
                {
                    log.Warn("Outlook can't handle end dates this far in the future. Converting to no end date.");
                    oPattern.NoEndDate = true;
                }
                else
                {
                    oPattern.PatternEndDate = DateTime.ParseExact(ruleBook["UNTIL"].ToString().Substring(0, 8), "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture).Date;
                }
            }
            if (!ruleBook.ContainsKey("COUNT") && !ruleBook.ContainsKey("UNTIL"))
            {
                oPattern.NoEndDate = true;
            }
            #endregion
        }
Пример #21
0
        private void buildOutlookPattern(Event ev, AppointmentItem ai, out RecurrencePattern oPattern)
        {
            if (ev.Recurrence == null)
            {
                oPattern = null; return;
            }

            Dictionary <String, String> ruleBook = explodeRrule(ev.Recurrence);

            if (ruleBook == null)
            {
                throw new ApplicationException("WARNING: The recurrence pattern is not compatible with Outlook. This event cannot be synced.");
            }
            log.Fine("Building Outlook recurrence pattern");
            oPattern = ai.GetRecurrencePattern();

            #region RECURRENCE PATTERN
            //RRULE:FREQ=WEEKLY;UNTIL=20150906T000000Z;BYDAY=SA

            switch (ruleBook["FREQ"])
            {
            case "DAILY": {
                oPattern.RecurrenceType = OlRecurrenceType.olRecursDaily;
                break;
            }

            case "WEEKLY": {
                oPattern.RecurrenceType = OlRecurrenceType.olRecursWeekly;
                // Need to work out dayMask from "BY" pattern
                // Eg "BYDAY=MO,TU,WE,TH,FR"
                OlDaysOfWeek dowMask = getDOWmask(ruleBook);
                if (dowMask != 0)
                {
                    oPattern.DayOfWeekMask = dowMask;
                }
                break;
            }

            case "MONTHLY": {
                oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthly;
                if (ruleBook.ContainsKey("BYSETPOS"))
                {
                    oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth;
                    int gInstance = Convert.ToInt16(ruleBook["BYSETPOS"]);
                    oPattern.Instance      = (gInstance == -1) ? 5 : gInstance;
                    oPattern.DayOfWeekMask = getDOWmask(ruleBook);
                    if (oPattern.DayOfWeekMask == (OlDaysOfWeek)127 && gInstance == -1 &&
                        (ev.Start.DateTime ?? DateTime.Parse(ev.Start.Date)).Day > 28)
                    {
                        //In Outlook this is simply a monthly recurring
                        oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthly;
                    }
                }
                if (ruleBook.ContainsKey("BYDAY"))
                {
                    if (ruleBook["BYDAY"].StartsWith("-1"))
                    {
                        oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth;
                        oPattern.Instance       = 5;
                        oPattern.DayOfWeekMask  = getDOWmask(ruleBook["BYDAY"].TrimStart("-1".ToCharArray()));
                    }
                    else if ("1,2,3,4".Contains(ruleBook["BYDAY"].Substring(0, 1)))
                    {
                        oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth;
                        oPattern.Instance       = Convert.ToInt16(ruleBook["BYDAY"].Substring(0, 1));
                        oPattern.DayOfWeekMask  = getDOWmask(ruleBook["BYDAY"].TrimStart(oPattern.Instance.ToString().ToCharArray()));
                    }
                }
                break;
            }

            case "YEARLY": {
                oPattern.RecurrenceType = OlRecurrenceType.olRecursYearly;
                //Google interval is years, Outlook is months
                if (ruleBook.ContainsKey("INTERVAL") && Convert.ToInt16(ruleBook["INTERVAL"]) > 1)
                {
                    oPattern.Interval = Convert.ToInt16(ruleBook["INTERVAL"]) * 12;
                }
                if (ruleBook.ContainsKey("BYSETPOS"))
                {
                    oPattern.RecurrenceType = OlRecurrenceType.olRecursYearNth;
                    int gInstance = Convert.ToInt16(ruleBook["BYSETPOS"]);
                    oPattern.Instance = (gInstance == -1) ? 5 : gInstance;

                    oPattern.DayOfWeekMask = getDOWmask(ruleBook);
                    if (ruleBook.ContainsKey("BYMONTH"))
                    {
                        oPattern.MonthOfYear = Convert.ToInt16(ruleBook["BYMONTH"]);
                    }
                }
                break;
            }
            }
            #endregion

            #region RANGE
            ai = OutlookOgcs.Calendar.Instance.IOutlook.WindowsTimeZone_set(ai, ev);
            oPattern.PatternStartDate = ev.Start.DateTime ?? DateTime.Parse(ev.Start.Date);
            if (ruleBook.ContainsKey("INTERVAL") && Convert.ToInt16(ruleBook["INTERVAL"]) > 1 && ruleBook["FREQ"] != "YEARLY")
            {
                oPattern.Interval = Convert.ToInt16(ruleBook["INTERVAL"]);
            }
            if (ruleBook.ContainsKey("COUNT"))
            {
                oPattern.Occurrences = Convert.ToInt16(ruleBook["COUNT"]);
            }
            if (ruleBook.ContainsKey("UNTIL"))
            {
                if (ruleBook["UNTIL"].StartsWith("4500"))
                {
                    log.Warn("Outlook can't handle end dates this far in the future. Converting to no end date.");
                    oPattern.NoEndDate = true;
                }
                else
                {
                    DateTime endDate;
                    if (ruleBook["UNTIL"].Length == 8 && !ruleBook["UNTIL"].EndsWith("Z"))
                    {
                        endDate = DateTime.ParseExact(ruleBook["UNTIL"], "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture).Date;
                    }
                    else
                    {
                        endDate = DateTime.ParseExact(ruleBook["UNTIL"], "yyyyMMddTHHmmssZ", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AdjustToUniversal);
                        endDate = endDate.AddHours(TimezoneDB.GetUtcOffset(ev.End.TimeZone)).Date;
                    }
                    if (endDate < oPattern.PatternStartDate)
                    {
                        log.Debug("PatternStartDate: " + oPattern.PatternStartDate.ToString("yyyyMMddHHmmss"));
                        log.Debug("PatternEndDate:   " + ruleBook["UNTIL"].ToString());
                        String summary = GoogleOgcs.Calendar.GetEventSummary(ev, onlyIfNotVerbose: true);
                        Forms.Main.Instance.Console.Update(summary + "The recurring Google event has an end date <i>before</i> the start date, which Outlook doesn't allow.<br/>" +
                                                           "The synced Outlook recurrence has been changed to a single occurrence.", Console.Markup.warning);
                        oPattern.Occurrences = 1;
                    }
                    else
                    {
                        oPattern.PatternEndDate = endDate;
                    }
                }
            }
            if (!ruleBook.ContainsKey("COUNT") && !ruleBook.ContainsKey("UNTIL"))
            {
                oPattern.NoEndDate = true;
            }
            #endregion
        }
Пример #22
0
        public static void UpdateGoogleExceptions(AppointmentItem ai, Event ev)
        {
            if (ai.IsRecurring)
            {
                RecurrencePattern recurrence = ai.GetRecurrencePattern();
                try {
                    if (recurrence.Exceptions.Count > 0)
                    {
                        log.Debug(OutlookCalendar.GetEventSummary(ai));
                        log.Debug("This is a recurring appointment with " + recurrence.Exceptions.Count + " exceptions that will now be iteratively compared.");
                        foreach (Microsoft.Office.Interop.Outlook.Exception oExcp in recurrence.Exceptions)
                        {
                            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 = oIsDeleted ? oExcp.OriginalDate : oExcp.AppointmentItem.Start;
                            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(oExcp, ev.RecurringEventId ?? ev.Id, OutlookCalendar.Instance.IOutlook.GetGlobalApptID(ai));
                            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;
                                }
                                try {
                                    GoogleCalendar.Instance.UpdateCalendarEntry(oExcp.AppointmentItem, gExcp, ref excp_itemModified);
                                } catch (System.Exception ex) {
                                    if (oIsDeleted)
                                    {
                                        if (gExcp.Status != "cancelled")
                                        {
                                            gExcp.Status = "cancelled";
                                            excp_itemModified++;
                                        }
                                    }
                                    else
                                    {
                                        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 {
                    recurrence = (RecurrencePattern)OutlookCalendar.ReleaseObject(recurrence);
                }
            }
        }
Пример #23
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);
                }
            }
        }
        public void CompareOutlookPattern(Event ev, AppointmentItem ai, System.Text.StringBuilder sb, ref int itemModified) {
            if (ev.Recurrence == null) return;

            log.Fine("Building a temporary recurrent Appointment generated from Event");
            AppointmentItem evAI = OutlookCalendar.Instance.IOutlook.UseOutlookCalendar().Items.Add() as AppointmentItem;
            RecurrencePattern evOpattern;
            RecurrencePattern aiOpattern = ai.GetRecurrencePattern();
            BuildOutlookPattern(ev, evAI, out evOpattern);
            log.Fine("Comparing Google recurrence to Outlook equivalent");

            if (MainForm.CompareAttribute("Recurrence Type", Settings.Instance.SyncDirection,
                evOpattern.RecurrenceType.ToString(), aiOpattern.RecurrenceType.ToString(), sb, ref itemModified)) {
                aiOpattern.RecurrenceType = evOpattern.RecurrenceType;
            }
            if (MainForm.CompareAttribute("Recurrence Interval", Settings.Instance.SyncDirection,
                evOpattern.Interval.ToString(), aiOpattern.Interval.ToString(), sb, ref itemModified)) {
                aiOpattern.Interval = evOpattern.Interval;
            }
            if (MainForm.CompareAttribute("Recurrence Instance", Settings.Instance.SyncDirection,
                evOpattern.Instance.ToString(), aiOpattern.Instance.ToString(), sb, ref itemModified)) {
                aiOpattern.Instance= evOpattern.Instance;
            }
            if (MainForm.CompareAttribute("Recurrence DoW", Settings.Instance.SyncDirection,
                evOpattern.DayOfWeekMask.ToString(), aiOpattern.DayOfWeekMask.ToString(), sb, ref itemModified)) {
                aiOpattern.DayOfWeekMask = evOpattern.DayOfWeekMask;
            }
            if (MainForm.CompareAttribute("Recurrence MoY", Settings.Instance.SyncDirection,
                evOpattern.MonthOfYear.ToString(), aiOpattern.MonthOfYear.ToString(), sb, ref itemModified)) {
                aiOpattern.MonthOfYear = evOpattern.MonthOfYear;
            }
            aiOpattern = (RecurrencePattern)OutlookCalendar.ReleaseObject(aiOpattern);
            evOpattern = (RecurrencePattern)OutlookCalendar.ReleaseObject(evOpattern);
            evAI = (AppointmentItem)OutlookCalendar.ReleaseObject(evAI);
        }
Пример #25
0
        private String FormattedEvent(AppointmentItem item, String created, bool cancelled, bool expandRecurring)
        {
            String str = "BEGIN:VEVENT\r\n";

            str += "CREATED:" + created + "\r\n";

            // If we're not expanding recurring events, this is an exception, which means it's cancelled
            if (!expandRecurring)
            {
                str += "TRANSP:TRANSPARENT\r\n";
            }
            else
            {
                str += "TRANSP:OPAQUE\r\n";
            }

            str += wrapString("DESCRIPTION:" + item.Body.Replace("\r\n", "\\n").Replace(",", "\\,") + "\\n") + "\r\n";

            str += wrapString("SUMMARY:" + item.Subject) + "\r\n";

            str += wrapString("UID:" + item.GlobalAppointmentID) + "\r\n";

            str += wrapString("ORGANIZER;CN=\"" + item.GetOrganizer().Name + "\":mailto:" + item.GetOrganizer().PropertyAccessor.GetProperty(@"http://schemas.microsoft.com/mapi/proptag/0x39FE001E").ToString()) + "\r\n";

            Recipients recipients = item.Recipients;

            if (recipients.Count > 1)
            {
                foreach (Recipient recipient in recipients)
                {
                    String recip = "ATTENDEE;CN=\"" + recipient.Name + "\"";
                    switch (recipient.Type)
                    {
                    case (int)NetOffice.OutlookApi.Enums.OlMeetingRecipientType.olOptional:
                        recip += ";ROLE=OPT-PARTICIPANT";
                        break;

                    case (int)NetOffice.OutlookApi.Enums.OlMeetingRecipientType.olRequired:
                        recip += ";ROLE=REQ-PARTICIPANT";
                        break;

                    case (int)NetOffice.OutlookApi.Enums.OlMeetingRecipientType.olOrganizer:
                        recip += ";ROLE=CHAIR";
                        break;

                    case (int)NetOffice.OutlookApi.Enums.OlMeetingRecipientType.olResource:
                        recip += ";ROLE=NON-PARTICIPANT";
                        break;
                    }
                    if (item.ResponseRequested)
                    {
                        recip += ";RSVP=TRUE";
                    }
                    switch (recipient.MeetingResponseStatus)
                    {
                    case NetOffice.OutlookApi.Enums.OlResponseStatus.olResponseAccepted:
                        recip += ";PARTSTAT=ACCEPTED";
                        break;

                    case NetOffice.OutlookApi.Enums.OlResponseStatus.olResponseDeclined:
                        recip += ";PARTSTAT=DECLINED";
                        break;

                    case NetOffice.OutlookApi.Enums.OlResponseStatus.olResponseNotResponded:
                        recip += ";PARTSTAT=NEEDS-ACTION";
                        break;

                    case NetOffice.OutlookApi.Enums.OlResponseStatus.olResponseOrganized:
                        recip += ";PARTSTAT=ACCEPTED";
                        break;

                    case NetOffice.OutlookApi.Enums.OlResponseStatus.olResponseTentative:
                        recip += ";PARTSTAT=TENTATIVE";
                        break;
                    }
                    str += wrapString(recip + ":mailto:" + recipient.PropertyAccessor.GetProperty(@"http://schemas.microsoft.com/mapi/proptag/0x39FE001E").ToString()) + "\r\n";
                }
            }

            if (item.Location.Length > 0)
            {
                str += wrapString("LOCATION:" + item.Location) + "\r\n";
            }

            {
                str += "PRIORITY:";
                switch (item.Importance)
                {
                case NetOffice.OutlookApi.Enums.OlImportance.olImportanceNormal:
                    str += "5" + "\r\n";
                    break;

                case NetOffice.OutlookApi.Enums.OlImportance.olImportanceLow:
                    str += "6" + "\r\n";
                    break;

                case NetOffice.OutlookApi.Enums.OlImportance.olImportanceHigh:
                    str += "1" + "\r\n";
                    break;
                }
            }
            {
                // SENSITIVITY
                switch (item.Sensitivity)
                {
                case NetOffice.OutlookApi.Enums.OlSensitivity.olNormal:
                    str += "CLASS:PUBLIC" + "\r\n";
                    break;

                case NetOffice.OutlookApi.Enums.OlSensitivity.olConfidential:
                    str += "CLASS:CONFIDENTIAL" + "\r\n";
                    break;

                case NetOffice.OutlookApi.Enums.OlSensitivity.olPrivate:
                    str += "CLASS:PRIVATE" + "\r\n";
                    break;

                case NetOffice.OutlookApi.Enums.OlSensitivity.olPersonal:
                    str += "CLASS:PRIVATE" + "\r\n";
                    break;
                }
            }

            if (item.AllDayEvent)
            {
                str += "DTSTART;VALUE=DATE:" + item.Start.ToString(@"yyyyMMdd") + "\r\n";
                str += "DTEND;VALUE=DATE:" + item.End.ToString(@"yyyyMMdd") + "\r\n";
            }
            else
            {
                str += "DTSTART;TZID=" + TZConvert.WindowsToIana(item.StartTimeZone.ID, "NL") + ":" + item.StartInStartTimeZone.ToString(@"yyyyMMdd\THHmmss") + "\r\n";
                str += "DTEND;TZID=" + TZConvert.WindowsToIana(item.EndTimeZone.ID, "NL") + ":" + item.EndInEndTimeZone.ToString(@"yyyyMMdd\THHmmss") + "\r\n";
            }

            str += "LAST-MODIFIED:" + item.LastModificationTime.ToUniversalTime().ToString(@"yyyyMMdd\THHmmssZ") + "\r\n";
            str += "DTSTAMP:" + item.CreationTime.ToUniversalTime().ToString(@"yyyyMMdd\THHmmssZ") + "\r\n";

            // Reminder
            if (item.ReminderSet)
            {
                str += "BEGIN:VALARM\r\n";

                str += "TRIGGER:-PT" + item.ReminderMinutesBeforeStart + "M\r\n";

                str += "ACTION:DISPLAY\r\n";
                str += "DESCRIPTION:Reminder\r\n";

                str += "END:VALARM\r\n";
            }

            if (expandRecurring && item.IsRecurring)
            {
                Console.WriteLine("Recurring meeting: " + item.Subject);

                RecurrencePattern rp = item.GetRecurrencePattern();

                str += "RRULE:";
                switch (rp.RecurrenceType)
                {
                case NetOffice.OutlookApi.Enums.OlRecurrenceType.olRecursDaily:
                    str += "FREQ=DAILY";
                    break;

                case NetOffice.OutlookApi.Enums.OlRecurrenceType.olRecursMonthly:
                    str += "FREQ=MONTHLY";
                    break;

                case NetOffice.OutlookApi.Enums.OlRecurrenceType.olRecursMonthNth:
                    str += "FREQ=MONTHLY";
                    break;

                case NetOffice.OutlookApi.Enums.OlRecurrenceType.olRecursWeekly:
                    str += "FREQ=WEEKLY";
                    break;

                case NetOffice.OutlookApi.Enums.OlRecurrenceType.olRecursYearly:
                    str += "FREQ=YEARLY";
                    break;

                case NetOffice.OutlookApi.Enums.OlRecurrenceType.olRecursYearNth:
                    break;
                }

                if (!rp.NoEndDate)
                {
                    // There is an end-date, either in occurrences or an end-date
                    if (rp.PatternEndDate != null)
                    {
                        str += ";UNTIL=" + rp.PatternEndDate.ToUniversalTime().ToString(@"yyyyMMdd\THHmmssZ");
                    }
                    else
                    {
                        str += ";COUNT=" + rp.Occurrences;
                    }
                }

                if (rp.Interval > 1)
                {
                    str += ";INTERVAL=" + rp.Interval;
                }

                string days = "";

                if ((rp.DayOfWeekMask & NetOffice.OutlookApi.Enums.OlDaysOfWeek.olMonday) == NetOffice.OutlookApi.Enums.OlDaysOfWeek.olMonday)
                {
                    if (days.Length > 0)
                    {
                        days += ",";
                    }
                    days += "MO";
                }
                if ((rp.DayOfWeekMask & NetOffice.OutlookApi.Enums.OlDaysOfWeek.olTuesday) == NetOffice.OutlookApi.Enums.OlDaysOfWeek.olTuesday)
                {
                    if (days.Length > 0)
                    {
                        days += ",";
                    }
                    days += "TU";
                }
                if ((rp.DayOfWeekMask & NetOffice.OutlookApi.Enums.OlDaysOfWeek.olWednesday) == NetOffice.OutlookApi.Enums.OlDaysOfWeek.olWednesday)
                {
                    if (days.Length > 0)
                    {
                        days += ",";
                    }
                    days += "WE";
                }
                if ((rp.DayOfWeekMask & NetOffice.OutlookApi.Enums.OlDaysOfWeek.olThursday) == NetOffice.OutlookApi.Enums.OlDaysOfWeek.olThursday)
                {
                    if (days.Length > 0)
                    {
                        days += ",";
                    }
                    days += "TH";
                }
                if ((rp.DayOfWeekMask & NetOffice.OutlookApi.Enums.OlDaysOfWeek.olFriday) == NetOffice.OutlookApi.Enums.OlDaysOfWeek.olFriday)
                {
                    if (days.Length > 0)
                    {
                        days += ",";
                    }
                    days += "FR";
                }
                if ((rp.DayOfWeekMask & NetOffice.OutlookApi.Enums.OlDaysOfWeek.olSaturday) == NetOffice.OutlookApi.Enums.OlDaysOfWeek.olSaturday)
                {
                    if (days.Length > 0)
                    {
                        days += ",";
                    }
                    days += "SA";
                }
                if ((rp.DayOfWeekMask & NetOffice.OutlookApi.Enums.OlDaysOfWeek.olSunday) == NetOffice.OutlookApi.Enums.OlDaysOfWeek.olSunday)
                {
                    if (days.Length > 0)
                    {
                        days += ",";
                    }
                    days += "SU";
                }

                str += ";BYDAY=" + days;

                if (rp.RecurrenceType == NetOffice.OutlookApi.Enums.OlRecurrenceType.olRecursMonthNth)
                {
                    str += ";BYSETPOS=1";
                }

                str += "\r\n";

                str += "END:VEVENT" + "\r\n";

                Exceptions exceptions = rp.Exceptions;

                foreach (NetOffice.OutlookApi.Exception exc in exceptions)
                {
                    Console.WriteLine("Found an exception to item " + item.Subject);
                    try
                    {
                        str += FormattedEvent(exc.AppointmentItem, created, true, false);
                        Console.WriteLine("Wrote the exception");
                    }
                    catch (System.Runtime.InteropServices.COMException e)
                    {
                        // Let's ignore any errors for the moment, they come from items out of the current range i think...
                        Console.WriteLine("Error writing exception: " + e.Message);
                    }
                }
            }
            else
            {
                str += "END:VEVENT" + "\r\n";
            }

            return(str);
        }
Пример #26
0
        public AppointmentItem UpdateCalendarEntry(AppointmentItem ai, Event ev, ref int itemModified, Boolean forceCompare = false)
        {
            if (ai.RecurrenceState == OlRecurrenceState.olApptMaster) { //The exception child objects might have changed
                log.Debug("Processing recurring master appointment.");
            } else {
                if (!(MainForm.Instance.ManualForceCompare || forceCompare)) { //Needed if the exception has just been created, but now needs updating
                    if (Settings.Instance.SyncDirection != SyncDirection.Bidirectional) {
                        if (DateTime.Parse(GoogleCalendar.GoogleTimeFrom(ai.LastModificationTime)) > DateTime.Parse(ev.Updated))
                            return null;
                    } else {
                        if (GoogleCalendar.GetOGCSlastModified(ev).AddSeconds(5) >= DateTime.Parse(ev.Updated))
                            //Google last modified by OGCS
                            return null;
                        if (DateTime.Parse(GoogleCalendar.GoogleTimeFrom(ai.LastModificationTime)) > DateTime.Parse(ev.Updated))
                            return null;
                    }
                }
            }

            String evSummary = GoogleCalendar.GetEventSummary(ev);
            log.Debug("Processing >> " + evSummary);

            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            sb.AppendLine(evSummary);

            if (ai.RecurrenceState != OlRecurrenceState.olApptMaster) {
                if (ai.AllDayEvent != (ev.Start.DateTime == null)) {
                    sb.AppendLine("All-Day: " + ai.AllDayEvent + " => " + (ev.Start.DateTime == null));
                    ai.AllDayEvent = (ev.Start.DateTime == null);
                    itemModified++;
                }
            }

            RecurrencePattern oPattern = (ai.RecurrenceState == OlRecurrenceState.olApptMaster) ? ai.GetRecurrencePattern() : null;
            Recurrence.Instance.CompareOutlookPattern(ev, ai, SyncDirection.GoogleToOutlook, sb, ref itemModified);

            DateTime evParsedDate = DateTime.Parse(ev.Start.Date ?? ev.Start.DateTime);
            if (MainForm.CompareAttribute("Start time", SyncDirection.GoogleToOutlook,
                GoogleCalendar.GoogleTimeFrom(evParsedDate),
                GoogleCalendar.GoogleTimeFrom(ai.Start), sb, ref itemModified))
            {
                if (ai.RecurrenceState == OlRecurrenceState.olApptMaster) {
                    oPattern.PatternStartDate = evParsedDate;
                    oPattern.StartTime = evParsedDate;
                } else {
                    ai.Start = evParsedDate;
                }
            }

            evParsedDate = DateTime.Parse(ev.End.Date ?? ev.End.DateTime);
            if (MainForm.CompareAttribute("End time", SyncDirection.GoogleToOutlook,
                GoogleCalendar.GoogleTimeFrom(evParsedDate),
                GoogleCalendar.GoogleTimeFrom(ai.End), sb, ref itemModified))
            {
                if (ai.RecurrenceState == OlRecurrenceState.olApptMaster) {
                    oPattern.EndTime = evParsedDate;
                } else {
                    ai.End = evParsedDate;
                }
            }

            if (oPattern != null) {
                oPattern.Duration = Convert.ToInt32((evParsedDate - DateTime.Parse(ev.Start.Date ?? ev.Start.DateTime)).TotalMinutes);
                oPattern = (RecurrencePattern)ReleaseObject(oPattern);
            }

            if (ai.RecurrenceState == OlRecurrenceState.olApptMaster) {
                if (ev.Recurrence == null || ev.RecurringEventId != null) {
                    log.Debug("Converting to non-recurring events.");
                    ai.ClearRecurrencePattern();
                    itemModified++;
                } else {
                    Recurrence.Instance.UpdateOutlookExceptions(ai, ev);
                }
            } else if (ai.RecurrenceState == OlRecurrenceState.olApptNotRecurring) {
                if (!ai.IsRecurring && ev.Recurrence != null && ev.RecurringEventId == null) {
                    log.Debug("Converting to recurring appointment.");
                    Recurrence.Instance.CreateOutlookExceptions(ai, ev);
                    itemModified++;
                }
            }

            String summaryObfuscated = Obfuscate.ApplyRegex(ev.Summary, SyncDirection.GoogleToOutlook);
            if (MainForm.CompareAttribute("Subject", SyncDirection.GoogleToOutlook, summaryObfuscated, ai.Subject, sb, ref itemModified)) {
                ai.Subject = summaryObfuscated;
            }
            if (!Settings.Instance.AddDescription) ev.Description = "";
            if (Settings.Instance.SyncDirection == SyncDirection.GoogleToOutlook || !Settings.Instance.AddDescription_OnlyToGoogle) {
                if (MainForm.CompareAttribute("Description", SyncDirection.GoogleToOutlook, ev.Description, ai.Body, sb, ref itemModified))
                    ai.Body = ev.Description;
            }

            if (MainForm.CompareAttribute("Location", SyncDirection.GoogleToOutlook, ev.Location, ai.Location, sb, ref itemModified))
                ai.Location = ev.Location;

            String oPrivacy = (ai.Sensitivity == OlSensitivity.olNormal) ? "default" : "private";
            String gPrivacy = ev.Visibility ?? "default";
            if (MainForm.CompareAttribute("Private", SyncDirection.GoogleToOutlook, gPrivacy, oPrivacy, sb, ref itemModified)) {
                ai.Sensitivity = (ev.Visibility != null && ev.Visibility == "private") ? OlSensitivity.olPrivate : OlSensitivity.olNormal;
            }
            String oFreeBusy = (ai.BusyStatus == OlBusyStatus.olFree) ? "transparent" : "opaque";
            String gFreeBusy = ev.Transparency ?? "opaque";
            if (MainForm.CompareAttribute("Free/Busy", SyncDirection.GoogleToOutlook, gFreeBusy, oFreeBusy, sb, ref itemModified)) {
                ai.BusyStatus = (ev.Transparency != null && ev.Transparency == "transparent") ? OlBusyStatus.olFree : OlBusyStatus.olBusy;
            }

            if (Settings.Instance.AddAttendees) {
                if (ev.Description != null && ev.Description.Contains("===--- Attendees ---===")) {
                    //Protect against <v1.2.4 where attendees were stored as text
                    log.Info("This event still has attendee information in the description - cannot sync them.");
                } else if (Settings.Instance.SyncDirection == SyncDirection.Bidirectional &&
                    ev.Attendees != null && ev.Attendees.Count == 0 && ai.Recipients.Count > 150) {
                        log.Info("Attendees not being synced - there are too many ("+ ai.Recipients.Count +") for Google.");
                } else {
                    //Build a list of Outlook attendees. Any remaining at the end of the diff must be deleted.
                    List<Recipient> removeRecipient = new List<Recipient>();
                    if (ai.Recipients != null) {
                        foreach (Recipient recipient in ai.Recipients) {
                            if (recipient.Name != ai.Organizer)
                                removeRecipient.Add(recipient);
                        }
                    }
                    if (ev.Attendees != null) {
                        for (int g = ev.Attendees.Count - 1; g >= 0; g--) {
                            bool foundRecipient = false;
                            EventAttendee attendee = ev.Attendees[g];

                            foreach (Recipient recipient in ai.Recipients) {
                                if (!recipient.Resolved) recipient.Resolve();
                                String recipientSMTP = IOutlook.GetRecipientEmail(recipient);
                                if (recipientSMTP.ToLower() == attendee.Email.ToLower()) {
                                    foundRecipient = true;
                                    removeRecipient.Remove(recipient);

                                    //Optional attendee
                                    bool oOptional = (ai.OptionalAttendees != null && ai.OptionalAttendees.Contains(attendee.DisplayName ?? attendee.Email));
                                    bool gOptional = (attendee.Optional == null) ? false : (bool)attendee.Optional;
                                    if (MainForm.CompareAttribute("Recipient " + recipient.Name + " - Optional Check",
                                        SyncDirection.GoogleToOutlook, gOptional, oOptional, sb, ref itemModified)) {
                                        if (gOptional) {
                                            recipient.Type = (int)OlMeetingRecipientType.olOptional;
                                        } else {
                                            recipient.Type = (int)OlMeetingRecipientType.olRequired;
                                        }
                                    }
                                    //Response is readonly in Outlook :(
                                    break;
                                }
                            }
                            if (!foundRecipient &&
                                (attendee.DisplayName != ai.Organizer)) //Attendee in Google is owner in Outlook, so can't also be added as a recipient)
                                {
                                sb.AppendLine("Recipient added: " + (attendee.DisplayName ?? attendee.Email));
                                createRecipient(attendee, ai);
                                itemModified++;
                            }
                        }
                    }

                    foreach (Recipient recipient in removeRecipient) {
                        sb.AppendLine("Recipient removed: " + recipient.Name);
                        recipient.Delete();
                        itemModified++;
                    }
                }
            }
            //Reminders
            if (Settings.Instance.AddReminders) {
                if (ev.Reminders.Overrides != null) {
                    //Find the popup reminder in Google
                    for (int r = ev.Reminders.Overrides.Count - 1; r >= 0; r--) {
                        EventReminder reminder = ev.Reminders.Overrides[r];
                        if (reminder.Method == "popup") {
                            if (ai.ReminderSet) {
                                if (MainForm.CompareAttribute("Reminder", SyncDirection.GoogleToOutlook, reminder.Minutes.ToString(), ai.ReminderMinutesBeforeStart.ToString(), sb, ref itemModified)) {
                                    ai.ReminderMinutesBeforeStart = (int)reminder.Minutes;
                                }
                            } else {
                                sb.AppendLine("Reminder: nothing => " + reminder.Minutes);
                                ai.ReminderSet = true;
                                ai.ReminderMinutesBeforeStart = (int)reminder.Minutes;
                                itemModified++;
                            } //if Outlook reminders set
                        } //if google reminder found
                    } //foreach reminder

                } else { //no google reminders set
                    if (ai.ReminderSet && IsOKtoSyncReminder(ai)) {
                        sb.AppendLine("Reminder: " + ai.ReminderMinutesBeforeStart + " => removed");
                        ai.ReminderSet = false;
                        itemModified++;
                    }
                }
            }
            if (itemModified > 0) {
                MainForm.Instance.Logboxout(sb.ToString(), false, verbose: true);
                MainForm.Instance.Logboxout(itemModified + " attributes updated.", verbose: true);
                System.Windows.Forms.Application.DoEvents();
            }
            return ai;
        }
Пример #27
0
        /// <summary>
        /// Merges the with.
        /// </summary>
        /// <param name="googleCalendarItem">The google calendar item.</param>
        /// <param name="outlookCalendarItem">The outlook calendar item.</param>
        /// <returns>True if Changed.</returns>
        public static bool MergeWith(this EventEntry googleCalendarItem, AppointmentItem outlookCalendarItem)
        {
            var result = false;

            result |= googleCalendarItem.Title.ApplyProperty(g => g.Text, outlookCalendarItem.Subject);
            result |= googleCalendarItem.Content.ApplyProperty(g => g.Content, outlookCalendarItem.Body);

            if (googleCalendarItem.EventTransparency == null)
            {
                googleCalendarItem.EventTransparency = new EventEntry.Transparency();
            }
            result |= googleCalendarItem.EventTransparency.ApplyProperty(g => g.Value, outlookCalendarItem.BusyStatus.GetStatus());

            if (googleCalendarItem.EventVisibility == null)
            {
                googleCalendarItem.EventVisibility = new EventEntry.Visibility();
            }
            result |= googleCalendarItem.EventVisibility.ApplyProperty(g => g.Value, outlookCalendarItem.Sensitivity.GetStatus());

            result |= googleCalendarItem.Locations.Merge(outlookCalendarItem.Location);
            result |= googleCalendarItem.Participants.Merge(outlookCalendarItem);

            if (outlookCalendarItem.RecurrenceState == OlRecurrenceState.olApptNotRecurring)
            {
                When time = googleCalendarItem.Times.FirstOrInstance();
                if (!googleCalendarItem.Times.Any())
                {
                    googleCalendarItem.Times.Add(time);
                }

                result |= time.ApplyProperty(t => t.AllDay, outlookCalendarItem.AllDayEvent);
                result |= time.ApplyProperty(t => t.StartTime, outlookCalendarItem.Start);
                result |= time.ApplyProperty(t => t.EndTime, outlookCalendarItem.End);

                if (outlookCalendarItem.ReminderSet)
                {
                    Google.GData.Extensions.Reminder reminder = time.Reminders.FirstOrInstance(t => t.Method == Google.GData.Extensions.Reminder.ReminderMethod.alert);
                    var timespan = TimeSpan.FromMinutes(outlookCalendarItem.ReminderMinutesBeforeStart);
                    result |= reminder.ApplyProperty(r => r.Method, Google.GData.Extensions.Reminder.ReminderMethod.alert);
                    result |= reminder.ApplyProperty(r => r.Minutes, timespan.Minutes);
                    result |= reminder.ApplyProperty(r => r.Hours, timespan.Hours);
                    result |= reminder.ApplyProperty(r => r.Days, timespan.Days);
                }
            }
            else
            {
                if (googleCalendarItem.Recurrence == null)
                {
                    googleCalendarItem.Recurrence = new Recurrence();
                }
                result |= googleCalendarItem.Recurrence.ApplyProperty(r => r.Value, RecurrenceSerializer.Serialize(outlookCalendarItem.GetRecurrencePattern(), outlookCalendarItem.Start, outlookCalendarItem.AllDayEvent));
            }

            return(result);
        }
        private static void UpdateOutlookAppointment(AppointmentItem appointment, string mtg_id, MeetingRequest request, bool reload_pattern = false)
        {
            int mrbs_id = -1;

            int.TryParse(mtg_id.Substring(0, mtg_id.IndexOf(";")), out mrbs_id);

            // appointment.Subject = request.Description;

            if ((appointment.RecurrenceState != OlRecurrenceState.olApptMaster) || (appointment.EntryID == ""))
            {
                appointment.Start = request.Start;
                appointment.End   = request.End;
            }

            appointment.Location = String.Format("{0} - {1}", Database.GetAreaNameByRoomId(request.RoomId), Database.GetRoomNameById(request.RoomId));

            if (request.RepeatTypeId > 0)
            {
                RecurrencePattern pattern;

                if (reload_pattern)
                {
                    appointment.ClearRecurrencePattern();
                }

                pattern = appointment.GetRecurrencePattern();

                switch (request.RepeatTypeId)
                {
                case 1:
                    pattern.RecurrenceType = OlRecurrenceType.olRecursDaily;
                    pattern.Interval       = 1;
                    break;

                case 2:
                    char[] rev = request.RepeatWeeklyCode.ToCharArray();

                    pattern.RecurrenceType = OlRecurrenceType.olRecursWeekly;
                    pattern.Interval       = request.RepeatNumberOfWeeks;
                    pattern.DayOfWeekMask  = (OlDaysOfWeek)Convert.ToInt32(new string(request.RepeatWeeklyCode.ToCharArray().Reverse().ToArray()), 2);
                    break;

                case 3:
                    if (request.RepeatMonthlyByWeekday)
                    {
                        pattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth;
                        pattern.Interval       = 1;
                        pattern.DayOfWeekMask  = (OlDaysOfWeek)((int)Math.Pow(2, request.RepeatWeekdayOfMonth));
                        pattern.Instance       = request.RepeatWeekdaysOfMonth;
                    }
                    else
                    {
                        pattern.RecurrenceType = OlRecurrenceType.olRecursMonthly;
                        pattern.Interval       = 1;
                        pattern.DayOfMonth     = request.RepeatDayOfMonth;
                    }
                    break;

                case 4:
                    pattern.RecurrenceType = OlRecurrenceType.olRecursYearly;
                    break;
                }

                pattern.Duration         = (request.End - request.Start).Minutes;
                pattern.EndTime          = request.RepeatEnd.Date + request.End.TimeOfDay;
                pattern.NoEndDate        = false;
                pattern.PatternStartDate = request.Start;
                pattern.PatternEndDate   = request.RepeatEnd + request.End.TimeOfDay;
                pattern.StartTime        = request.Start;
            }

            try
            {
                appointment.UserProperties.Add("MJ-MRBS-ID", OlUserPropertyType.olText, true, OlFormatText.olFormatTextText);
            }
            catch (UnauthorizedAccessException)
            {
                //appointment.UserProperties.Add("MJ-MRBS-ID", OlUserPropertyType.olText, true, OlFormatText.olFormatTextText);
            }

            appointment.UserProperties["MJ-MRBS-ID"].Value = mtg_id;
            if (!appointment.Body.Contains("has been linked to a reservation in MRBS."))
            {
                appointment.Body += String.Format("\n\n\n***** This {0} has been linked to a reservation in MRBS. To change the {0} location, you must use the Modify Reservation button in the ribbon. *****", appointment.MeetingStatus == OlMeetingStatus.olNonMeeting ? "appointment" : "meeting");
            }

            appointment.Save();
            if (request.RepeatTypeId > 0)
            {
                RecurrencePattern pattern   = appointment.GetRecurrencePattern();
                List <Entry>      entries   = Database.GetAllEntries(mrbs_id);
                List <Entry>      conflicts = Database.FindConflicts(request, mrbs_id);

                foreach (Entry conflict in conflicts)
                {
                    DateTime start_time = Database.UnixTimeStampToDateTime(conflict.start_time);

                    AppointmentItem item = pattern.GetOccurrence(start_time);
                    item.Delete();
                }

                foreach (Entry entry in entries)
                {
                    try
                    {
                        DateTime        start_time = Database.UnixTimeStampToDateTime(entry.start_time);
                        AppointmentItem item       = pattern.GetOccurrence(start_time);
                        item.UserProperties.Add("MJ-MRBS-ID", OlUserPropertyType.olText, true, OlFormatText.olFormatTextText);
                        item.UserProperties["MJ-MRBS-ID"].Value = String.Format("{0};{1}", entry.id, entry.ical_uid);
                        item.Save();
                    }
                    catch { }
                }

                appointment.Save();
            }
        }
        public void BuildOutlookPattern(Event ev, AppointmentItem ai, out RecurrencePattern oPattern) {
            if (ev.Recurrence == null) { oPattern = null; return; }

            Dictionary<String, String> ruleBook = explodeRrule(ev.Recurrence);
            log.Fine("Building Outlook recurrence pattern");
            oPattern = ai.GetRecurrencePattern();
            #region RECURRENCE PATTERN
            //RRULE:FREQ=WEEKLY;UNTIL=20150906T000000Z;BYDAY=SA

            switch (ruleBook["FREQ"]) {
                case "DAILY": {
                        oPattern.RecurrenceType = OlRecurrenceType.olRecursDaily;
                        break;
                    }
                case "WEEKLY": {
                        oPattern.RecurrenceType = OlRecurrenceType.olRecursWeekly;
                        // Need to work out dayMask from "BY" pattern
                        // Eg "BYDAY=MO,TU,WE,TH,FR"
                        OlDaysOfWeek dowMask = getDOWmask(ruleBook);
                        if (dowMask != 0) {
                            oPattern.DayOfWeekMask = dowMask;
                        }
                        break;
                    }
                case "MONTHLY": {
                        oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthly;
                        if (ruleBook.ContainsKey("BYSETPOS")) {
                            oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth;
                            int gInstance = Convert.ToInt16(ruleBook["BYSETPOS"]);
                            oPattern.Instance = (gInstance == -1) ? 5 : gInstance;
                            oPattern.DayOfWeekMask = getDOWmask(ruleBook);
                            if (oPattern.DayOfWeekMask == (OlDaysOfWeek)127 && gInstance == -1 &&
                                DateTime.Parse(ev.Start.DateTime ?? ev.Start.Date).Day > 28) {
                                //In Outlook this is simply a monthly recurring
                                oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthly;
                                oPattern.DayOfWeekMask = 0;
                            }
                        }
                        if (ruleBook.ContainsKey("BYDAY")) {
                            if (ruleBook["BYDAY"].StartsWith("-1")) {
                                oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth;
                                oPattern.Instance = 5;
                                oPattern.DayOfWeekMask = getDOWmask(ruleBook["BYDAY"].TrimStart("-1".ToCharArray()));
                            } else if ("1,2,3,4".Contains(ruleBook["BYDAY"].Substring(0, 1))) {
                                oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth;
                                oPattern.Instance = Convert.ToInt16(ruleBook["BYDAY"].Substring(0, 1));
                                oPattern.DayOfWeekMask = getDOWmask(ruleBook["BYDAY"].TrimStart(oPattern.Instance.ToString().ToCharArray()));
                            }
                        }
                        break;
                    }

                case "YEARLY": {
                        oPattern.RecurrenceType = OlRecurrenceType.olRecursYearly;
                        //Google interval is years, Outlook is months
                        if (ruleBook.ContainsKey("INTERVAL"))
                            oPattern.Interval = Convert.ToInt16(ruleBook["INTERVAL"]) * 12;
                        if (ruleBook.ContainsKey("BYSETPOS")) {
                            oPattern.RecurrenceType = OlRecurrenceType.olRecursYearNth;
                            int gInstance = Convert.ToInt16(ruleBook["BYSETPOS"]);
                            oPattern.Instance = (gInstance == -1) ? 5 : gInstance;

                            oPattern.DayOfWeekMask = getDOWmask(ruleBook);
                            if (ruleBook.ContainsKey("BYMONTH")) {
                                oPattern.MonthOfYear = Convert.ToInt16(ruleBook["BYMONTH"]);
                            }
                        }
                        break;
                    }
            }
            #endregion

            #region RANGE
            if (ruleBook.ContainsKey("INTERVAL") && Convert.ToInt16(ruleBook["INTERVAL"]) > 1 && ruleBook["FREQ"] != "YEARLY")
                oPattern.Interval = Convert.ToInt16(ruleBook["INTERVAL"]);
            if (ruleBook.ContainsKey("COUNT"))
                oPattern.Occurrences = Convert.ToInt16(ruleBook["COUNT"]);
            if (ruleBook.ContainsKey("UNTIL"))
                oPattern.PatternEndDate = DateTime.ParseExact(ruleBook["UNTIL"], "yyyyMMddTHHmmssZ", System.Globalization.CultureInfo.InvariantCulture);
            #endregion

            ai = OutlookCalendar.Instance.IOutlook.WindowsTimeZone_set(ai, ev);
        }
 public static Boolean HasExceptions(AppointmentItem ai) {
     return ai.GetRecurrencePattern().Exceptions.Count != 0;
 }
Пример #31
0
        public void BuildOutlookPattern(Event ev, AppointmentItem ai, out RecurrencePattern oPattern)
        {
            if (ev.Recurrence == null)
            {
                oPattern = null; return;
            }

            Dictionary <String, String> ruleBook = explodeRrule(ev.Recurrence);

            log.Fine("Building Outlook recurrence pattern");
            oPattern = ai.GetRecurrencePattern();
            #region RECURRENCE PATTERN
            //RRULE:FREQ=WEEKLY;UNTIL=20150906T000000Z;BYDAY=SA

            switch (ruleBook["FREQ"])
            {
            case "DAILY": {
                oPattern.RecurrenceType = OlRecurrenceType.olRecursDaily;
                break;
            }

            case "WEEKLY": {
                oPattern.RecurrenceType = OlRecurrenceType.olRecursWeekly;
                // Need to work out dayMask from "BY" pattern
                // Eg "BYDAY=MO,TU,WE,TH,FR"
                OlDaysOfWeek dowMask = getDOWmask(ruleBook);
                if (dowMask != 0)
                {
                    oPattern.DayOfWeekMask = dowMask;
                }
                break;
            }

            case "MONTHLY": {
                oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthly;
                if (ruleBook.ContainsKey("BYSETPOS"))
                {
                    oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth;
                    int gInstance = Convert.ToInt16(ruleBook["BYSETPOS"]);
                    oPattern.Instance      = (gInstance == -1) ? 5 : gInstance;
                    oPattern.DayOfWeekMask = getDOWmask(ruleBook);
                    if (oPattern.DayOfWeekMask == (OlDaysOfWeek)127 && gInstance == -1 &&
                        DateTime.Parse(ev.Start.DateTime ?? ev.Start.Date).Day > 28)
                    {
                        //In Outlook this is simply a monthly recurring
                        oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthly;
                        oPattern.DayOfWeekMask  = 0;
                    }
                }
                if (ruleBook.ContainsKey("BYDAY"))
                {
                    if (ruleBook["BYDAY"].StartsWith("-1"))
                    {
                        oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth;
                        oPattern.Instance       = 5;
                        oPattern.DayOfWeekMask  = getDOWmask(ruleBook["BYDAY"].TrimStart("-1".ToCharArray()));
                    }
                    else if ("1,2,3,4".Contains(ruleBook["BYDAY"].Substring(0, 1)))
                    {
                        oPattern.RecurrenceType = OlRecurrenceType.olRecursMonthNth;
                        oPattern.Instance       = Convert.ToInt16(ruleBook["BYDAY"].Substring(0, 1));
                        oPattern.DayOfWeekMask  = getDOWmask(ruleBook["BYDAY"].TrimStart(oPattern.Instance.ToString().ToCharArray()));
                    }
                }
                break;
            }

            case "YEARLY": {
                oPattern.RecurrenceType = OlRecurrenceType.olRecursYearly;
                //Google interval is years, Outlook is months
                if (ruleBook.ContainsKey("INTERVAL"))
                {
                    oPattern.Interval = Convert.ToInt16(ruleBook["INTERVAL"]) * 12;
                }
                if (ruleBook.ContainsKey("BYSETPOS"))
                {
                    oPattern.RecurrenceType = OlRecurrenceType.olRecursYearNth;
                    int gInstance = Convert.ToInt16(ruleBook["BYSETPOS"]);
                    oPattern.Instance = (gInstance == -1) ? 5 : gInstance;

                    oPattern.DayOfWeekMask = getDOWmask(ruleBook);
                    if (ruleBook.ContainsKey("BYMONTH"))
                    {
                        oPattern.MonthOfYear = Convert.ToInt16(ruleBook["BYMONTH"]);
                    }
                }
                break;
            }
            }
            #endregion

            #region RANGE
            if (ruleBook.ContainsKey("INTERVAL") && Convert.ToInt16(ruleBook["INTERVAL"]) > 1 && ruleBook["FREQ"] != "YEARLY")
            {
                oPattern.Interval = Convert.ToInt16(ruleBook["INTERVAL"]);
            }
            if (ruleBook.ContainsKey("COUNT"))
            {
                oPattern.Occurrences = Convert.ToInt16(ruleBook["COUNT"]);
            }
            if (ruleBook.ContainsKey("UNTIL"))
            {
                if (ruleBook["UNTIL"].Length == 8)
                {
                    oPattern.PatternEndDate = DateTime.ParseExact(ruleBook["UNTIL"], "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture);
                }
                else
                {
                    if (ruleBook["UNTIL"].ToString().Substring(8) == "T000000Z" && ev.Start.DateTime != null)
                    {
                        oPattern.PatternEndDate = DateTime.ParseExact(ruleBook["UNTIL"], "yyyyMMddTHHmmssZ", System.Globalization.CultureInfo.InvariantCulture).AddDays(-1);
                    }
                    else
                    {
                        oPattern.PatternEndDate = DateTime.ParseExact(ruleBook["UNTIL"], "yyyyMMddTHHmmssZ", System.Globalization.CultureInfo.InvariantCulture);
                    }
                }
            }
            #endregion

            ai = OutlookCalendar.Instance.IOutlook.WindowsTimeZone_set(ai, ev);
        }
        private void processOutlookExceptions(AppointmentItem ai, Event ev, Boolean forceCompare) {
            if (!HasExceptions(ev, checkLocalCacheOnly: true)) return;

            if (!ai.Saved) ai.Save();

            RecurrencePattern oPattern = ai.GetRecurrencePattern();
            foreach (Event gExcp in Recurrence.Instance.googleExceptions.Where(exp => exp.RecurringEventId == ev.Id)) {
                log.Fine("Found Google exception for " + (gExcp.OriginalStartTime.DateTime ?? gExcp.OriginalStartTime.Date));

                DateTime oExcpDate = DateTime.Parse(gExcp.OriginalStartTime.DateTime ?? gExcp.OriginalStartTime.Date);
                AppointmentItem newAiExcp = getOutlookInstance(oPattern, oExcpDate);
                if (newAiExcp == null) continue;

                if (gExcp.Status != "cancelled") {
                    int itemModified = 0;
                    newAiExcp = OutlookCalendar.Instance.UpdateCalendarEntry(newAiExcp, gExcp, ref itemModified, forceCompare);
                    if (itemModified > 0) newAiExcp.Save();
                } else {
                    MainForm.Instance.Logboxout(OutlookCalendar.GetEventSummary(ai) +"\r\nDeleted.");
                    newAiExcp.Delete();
                }
                newAiExcp = (AppointmentItem)OutlookCalendar.ReleaseObject(newAiExcp);
            }
            if (!ai.Saved) ai.Save();
            oPattern = (RecurrencePattern)OutlookCalendar.ReleaseObject(oPattern);
        }
Пример #33
0
 public static Boolean HasExceptions(AppointmentItem ai)
 {
     return(ai.GetRecurrencePattern().Exceptions.Count != 0);
 }
Пример #34
0
        private List <AppointmentInfo> LoadAllData()
        {
            List <AppointmentInfo> allData = new List <AppointmentInfo>();

            Log.Write($"allData cleared.");
            try
            {
                foreach (var folder in AllMAPIFolders)
                {
                    Log.Write($"LoadAllData: {folder.Folder.FullFolderPath}");
                    try
                    {
                        SetStatus(folder.ToString(), 0);

                        Items items = folder.Folder.Items;
                        if (items == null)
                        {
                            Log.Write($"LoadAllData: Items in folder {folder.Folder.FullFolderPath} is null!");
                        }

                        items.IncludeRecurrences = true;

                        Log.Write($"LoadAllData: Total {items.Count} items");

                        int n            = 0;
                        int lastProgress = 0;
                        int p            = 0;

                        foreach (var item in items)
                        {
                            n += 1;
                            p  = 100 * n / items.Count;
                            if (p != lastProgress)
                            {
                                SetStatus(null, p);
                                lastProgress = p;
                            }

                            AppointmentItem ai = item as AppointmentItem;
                            if (ai == null)
                            {
                                continue;
                            }

                            //Log.Write($"LoadAllData: Processing item {n} - {ai.Subject}");

                            if (ai.Sensitivity != 0)
                            {
                                //    Log.Write("Skipping private event");
                                continue;
                            }

                            if (ai.IsRecurring)
                            {
                                //  Log.Write($"LoadAllData: {ai.Subject} is recurring...");
                                Microsoft.Office.Interop.Outlook.RecurrencePattern rp    = ai.GetRecurrencePattern();
                                Microsoft.Office.Interop.Outlook.AppointmentItem   recur = null;
                                for (DateTime cur = monthCalendar1.SelectionStart.AddHours(ai.Start.Hour).AddMinutes(ai.Start.Minute); cur < monthCalendar2.SelectionStart.AddDays(1); cur = cur.AddDays(1))
                                {
                                    try
                                    {
                                        recur = rp.GetOccurrence(cur);
                                        //Log.Write($"LoadAllData: Adding occurence of recurring item {ai.Subject} for date {cur}");
                                        allData.Add(new AppointmentInfo(recur, folder));
                                    }
                                    catch
                                    { }
                                }
                            }
                            else
                            {
                                if ((ai.Start >= monthCalendar1.SelectionStart) && (ai.End < monthCalendar2.SelectionStart.AddDays(1)))
                                {
                                    //Log.Write($"LoadAllData: Adding item {ai.Subject}");
                                    allData.Add(new AppointmentInfo(ai, folder));
                                }
                                else
                                {
                                    //Log.Write($"LoadAllData: {ai.Subject} is out of date frame, continuing...");
                                    continue;
                                }
                            }
                        }
                    }
                    catch (System.Exception ex)
                    {
                        Log.Write($"[EXCEPTION] Nastala výjimka při zpracování složky {folder.Folder.Name}:\r\n {ex.Message}");
                        MessageBox.Show($"Nastala výjimka při zpracování složky {folder.Folder.Name}:\r\n {ex.Message}", "Výjimka", MessageBoxButtons.OK);
                    }
                    finally
                    {
                        folder.WasProcessed = true;
                    }
                }
            }
            finally
            {
                SetStatus("Načteno", -1);
            }
            return(allData);
        }
Пример #35
0
        private SyncResult synchronize()
        {
            Console console = Forms.Main.Instance.Console;

            console.Update("Finding Calendar Entries", Console.Markup.mag_right, newLine: false);

            List <AppointmentItem> outlookEntries = null;
            List <Event>           googleEntries  = null;

            try {
                #region Read Outlook items
                console.Update("Scanning Outlook calendar...");
                outlookEntries = OutlookOgcs.Calendar.Instance.GetCalendarEntriesInRange(false);
                console.Update(outlookEntries.Count + " Outlook calendar entries found.", Console.Markup.sectionEnd, newLine: false);

                if (CancellationPending)
                {
                    return(SyncResult.UserCancelled);
                }
                #endregion

                #region Read Google items
                console.Update("Scanning Google calendar...");
                try {
                    googleEntries = GoogleOgcs.Calendar.Instance.GetCalendarEntriesInRange();
                } catch (AggregateException agex) {
                    OGCSexception.AnalyseAggregate(agex);
                } catch (Google.Apis.Auth.OAuth2.Responses.TokenResponseException ex) {
                    OGCSexception.AnalyseTokenResponse(ex, false);
                    return(SyncResult.Fail);
                } catch (System.Net.Http.HttpRequestException ex) {
                    OGCSexception.Analyse(ex);
                    ex.Data.Add("OGCS", "ERROR: Unable to connect to the Google calendar. Please try again.");
                    throw ex;
                } catch (System.Exception ex) {
                    OGCSexception.Analyse(ex);
                    ex.Data.Add("OGCS", "ERROR: Unable to connect to the Google calendar.");
                    if (OGCSexception.GetErrorCode(ex) == "0x8013153B") //ex.Message == "A task was canceled." - likely timed out.
                    {
                        ex.Data["OGCS"] += " Please try again.";
                    }
                    throw ex;
                }
                Recurrence.Instance.SeparateGoogleExceptions(googleEntries);
                if (Recurrence.Instance.GoogleExceptions != null && Recurrence.Instance.GoogleExceptions.Count > 0)
                {
                    console.Update(googleEntries.Count + " Google calendar entries found.");
                    console.Update(Recurrence.Instance.GoogleExceptions.Count + " are exceptions to recurring events.", Console.Markup.sectionEnd, newLine: false);
                }
                else
                {
                    console.Update(googleEntries.Count + " Google calendar entries found.", Console.Markup.sectionEnd, newLine: false);
                }

                if (CancellationPending)
                {
                    return(SyncResult.UserCancelled);
                }
                #endregion

                #region Normalise recurring items in sync window
                console.Update("Total inc. recurring items spanning sync date range...");
                //Outlook returns recurring items that span the sync date range, Google doesn't
                //So check for master Outlook items occurring before sync date range, and retrieve Google equivalent
                for (int o = outlookEntries.Count - 1; o >= 0; o--)
                {
                    log.Fine("Processing " + (o + 1) + "/" + outlookEntries.Count);
                    AppointmentItem ai = null;
                    try {
                        if (outlookEntries[o] is AppointmentItem)
                        {
                            ai = outlookEntries[o];
                        }
                        else if (outlookEntries[o] is MeetingItem)
                        {
                            log.Info("Calendar object appears to be a MeetingItem, so retrieving associated AppointmentItem.");
                            MeetingItem mi = outlookEntries[o] as MeetingItem;
                            outlookEntries[o] = mi.GetAssociatedAppointment(false);
                            ai = outlookEntries[o];
                        }
                        else
                        {
                            log.Warn("Unknown calendar object type - cannot sync it.");
                            skipCorruptedItem(ref outlookEntries, outlookEntries[o], "Unknown object type.");
                            outlookEntries[o] = (AppointmentItem)OutlookOgcs.Calendar.ReleaseObject(outlookEntries[o]);
                            continue;
                        }
                    } catch (System.Exception ex) {
                        log.Warn("Encountered error casting calendar object to AppointmentItem - cannot sync it.");
                        log.Debug(ex.Message);
                        skipCorruptedItem(ref outlookEntries, outlookEntries[o], ex.Message);
                        outlookEntries[o] = (AppointmentItem)OutlookOgcs.Calendar.ReleaseObject(outlookEntries[o]);
                        ai = (AppointmentItem)OutlookOgcs.Calendar.ReleaseObject(ai);
                        continue;
                    }

                    //Now let's check there's a start/end date - sometimes it can be missing, even though this shouldn't be possible!!
                    String entryID;
                    try {
                        entryID = outlookEntries[o].EntryID;
                        DateTime checkDates = ai.Start;
                        checkDates = ai.End;
                    } catch (System.Exception ex) {
                        log.Warn("Calendar item does not have a proper date range - cannot sync it.");
                        log.Debug(ex.Message);
                        skipCorruptedItem(ref outlookEntries, outlookEntries[o], ex.Message);
                        outlookEntries[o] = (AppointmentItem)OutlookOgcs.Calendar.ReleaseObject(outlookEntries[o]);
                        ai = (AppointmentItem)OutlookOgcs.Calendar.ReleaseObject(ai);
                        continue;
                    }

                    if (ai.IsRecurring && ai.Start.Date < Settings.Instance.SyncStart && ai.End.Date < Settings.Instance.SyncStart)
                    {
                        //We won't bother getting Google master event if appointment is yearly reoccurring in a month outside of sync range
                        //Otherwise, every sync, the master event will have to be retrieved, compared, concluded nothing's changed (probably) = waste of API calls
                        RecurrencePattern oPattern = ai.GetRecurrencePattern();
                        try {
                            if (oPattern.RecurrenceType.ToString().Contains("Year"))
                            {
                                log.Fine("It's an annual event.");
                                Boolean  monthInSyncRange = false;
                                DateTime monthMarker      = Settings.Instance.SyncStart;
                                while (Convert.ToInt32(monthMarker.ToString("yyyyMM")) <= Convert.ToInt32(Settings.Instance.SyncEnd.ToString("yyyyMM")) &&
                                       !monthInSyncRange)
                                {
                                    if (monthMarker.Month == ai.Start.Month)
                                    {
                                        monthInSyncRange = true;
                                    }
                                    monthMarker = monthMarker.AddMonths(1);
                                }
                                log.Fine("Found it to be " + (monthInSyncRange ? "inside" : "outside") + " sync range.");
                                if (!monthInSyncRange)
                                {
                                    outlookEntries.Remove(ai); log.Fine("Removed."); continue;
                                }
                            }
                            Event masterEv = Recurrence.Instance.GetGoogleMasterEvent(ai);
                            if (masterEv != null && masterEv.Status != "cancelled")
                            {
                                Event cachedEv = googleEntries.Find(x => x.Id == masterEv.Id);
                                if (cachedEv == null)
                                {
                                    googleEntries.Add(masterEv);
                                }
                                else
                                {
                                    if (masterEv.Updated > cachedEv.Updated)
                                    {
                                        log.Debug("Refreshing cache for this Event.");
                                        googleEntries.Remove(cachedEv);
                                        googleEntries.Add(masterEv);
                                    }
                                }
                            }
                        } catch (System.Exception ex) {
                            console.Update("Failed to retrieve master for Google recurring event outside of sync range.", Console.Markup.error);
                            throw ex;
                        } finally {
                            oPattern = (RecurrencePattern)OutlookOgcs.Calendar.ReleaseObject(oPattern);
                        }
                    }
                    //Completely dereference object and retrieve afresh (due to GetRecurrencePattern earlier)
                    ai = (AppointmentItem)OutlookOgcs.Calendar.ReleaseObject(ai);
                    OutlookOgcs.Calendar.Instance.IOutlook.GetAppointmentByID(entryID, out ai);
                    outlookEntries[o] = ai;
                }
                console.Update("Outlook " + outlookEntries.Count + ", Google " + googleEntries.Count);

                GoogleOgcs.Calendar.ExportToCSV("Outputting all Events.", "google_events.csv", googleEntries);
                OutlookOgcs.Calendar.ExportToCSV("Outputting all Appointments.", "outlook_appointments.csv", outlookEntries);
                if (CancellationPending)
                {
                    return(SyncResult.UserCancelled);
                }
                #endregion

                Boolean success    = true;
                String  bubbleText = "";
                if (Settings.Instance.SyncDirection != Direction.GoogleToOutlook)
                {
                    success = outlookToGoogle(outlookEntries, googleEntries, ref bubbleText);
                    if (CancellationPending)
                    {
                        return(SyncResult.UserCancelled);
                    }
                }
                if (!success)
                {
                    return(SyncResult.Fail);
                }
                if (Settings.Instance.SyncDirection != Direction.OutlookToGoogle)
                {
                    if (bubbleText != "")
                    {
                        bubbleText += "\r\n";
                    }
                    success = googleToOutlook(googleEntries, outlookEntries, ref bubbleText);
                    if (CancellationPending)
                    {
                        return(SyncResult.UserCancelled);
                    }
                }
                if (bubbleText != "")
                {
                    Forms.Main.Instance.NotificationTray.ShowBubbleInfo(bubbleText);
                }

                return(SyncResult.OK);
            } finally {
                for (int o = outlookEntries.Count() - 1; o >= 0; o--)
                {
                    outlookEntries[o] = (AppointmentItem)OutlookOgcs.Calendar.ReleaseObject(outlookEntries[o]);
                    outlookEntries.RemoveAt(o);
                }
            }
        }
Пример #36
0
        public AppointmentItem UpdateCalendarEntry(AppointmentItem ai, Event ev, ref int itemModified, Boolean forceCompare = false)
        {
            if (ai.RecurrenceState == OlRecurrenceState.olApptMaster)   //The exception child objects might have changed
            {
                log.Debug("Processing recurring master appointment.");
            }
            else
            {
                if (!forceCompare)   //Needed if the exception has just been created, but now needs updating
                {
                    if (Settings.Instance.SyncDirection != SyncDirection.Bidirectional)
                    {
                        if (DateTime.Parse(GoogleCalendar.GoogleTimeFrom(ai.LastModificationTime)) > DateTime.Parse(ev.Updated))
                        {
                            return(null);
                        }
                    }
                    else
                    {
                        if (GoogleCalendar.OGCSlastModified(ev).AddSeconds(5) >= DateTime.Parse(ev.Updated))
                        {
                            //Google last modified by OGCS
                            return(null);
                        }
                        if (DateTime.Parse(GoogleCalendar.GoogleTimeFrom(ai.LastModificationTime)) > DateTime.Parse(ev.Updated))
                        {
                            return(null);
                        }
                    }
                }
            }

            String evSummary = GoogleCalendar.GetEventSummary(ev);

            log.Debug("Processing >> " + evSummary);

            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            sb.AppendLine(evSummary);

            RecurrencePattern oPattern = (ai.RecurrenceState == OlRecurrenceState.olApptNotRecurring) ? null : ai.GetRecurrencePattern();

            if (ev.Start.Date != null)
            {
                if (ai.RecurrenceState != OlRecurrenceState.olApptMaster)
                {
                    ai.AllDayEvent = true;
                }
                if (MainForm.CompareAttribute("Start time", SyncDirection.GoogleToOutlook, ev.Start.Date, ai.Start.ToString("yyyy-MM-dd"), sb, ref itemModified))
                {
                    if (ai.RecurrenceState == OlRecurrenceState.olApptMaster)
                    {
                        oPattern.PatternStartDate = DateTime.Parse(ev.Start.Date);
                    }
                    else
                    {
                        ai.Start = DateTime.Parse(ev.Start.Date);
                    }
                }
                if (MainForm.CompareAttribute("End time", SyncDirection.GoogleToOutlook, ev.End.Date, ai.End.ToString("yyyy-MM-dd"), sb, ref itemModified))
                {
                    if (ai.RecurrenceState == OlRecurrenceState.olApptMaster)
                    {
                        oPattern.PatternEndDate = DateTime.Parse(ev.End.Date);
                    }
                    else
                    {
                        ai.End = DateTime.Parse(ev.End.Date);
                    }
                }
            }
            else
            {
                if (ai.RecurrenceState != OlRecurrenceState.olApptMaster)
                {
                    ai.AllDayEvent = false;
                }
                if (MainForm.CompareAttribute("Start time",
                                              SyncDirection.GoogleToOutlook,
                                              GoogleCalendar.GoogleTimeFrom(DateTime.Parse(ev.Start.DateTime)),
                                              GoogleCalendar.GoogleTimeFrom(ai.Start), sb, ref itemModified))
                {
                    if (ai.RecurrenceState == OlRecurrenceState.olApptMaster)
                    {
                        oPattern.PatternStartDate = DateTime.Parse(ev.Start.DateTime);
                    }
                    else
                    {
                        ai.Start = DateTime.Parse(ev.Start.DateTime);
                    }
                }
                if (MainForm.CompareAttribute("End time",
                                              SyncDirection.GoogleToOutlook,
                                              GoogleCalendar.GoogleTimeFrom(DateTime.Parse(ev.End.DateTime)),
                                              GoogleCalendar.GoogleTimeFrom(ai.End), sb, ref itemModified))
                {
                    if (ai.RecurrenceState == OlRecurrenceState.olApptMaster)
                    {
                        oPattern.PatternEndDate = DateTime.Parse(ev.End.DateTime);
                    }
                    else
                    {
                        ai.End = DateTime.Parse(ev.End.DateTime);
                    }
                }
            }
            oPattern = (RecurrencePattern)ReleaseObject(oPattern);

            if (ai.RecurrenceState == OlRecurrenceState.olApptMaster)
            {
                if (ev.Recurrence == null || ev.RecurringEventId != null)
                {
                    log.Debug("Converting to non-recurring events.");
                    ai.ClearRecurrencePattern();
                    itemModified++;
                }
                else
                {
                    Recurrence.Instance.CompareOutlookPattern(ev, ai, sb, ref itemModified);
                    Recurrence.Instance.UpdateOutlookExceptions(ai, ev);
                }
            }
            else if (ai.RecurrenceState == OlRecurrenceState.olApptNotRecurring)
            {
                if (!ai.IsRecurring && ev.Recurrence != null && ev.RecurringEventId == null)
                {
                    log.Debug("Converting to recurring appointment.");
                    Recurrence.Instance.CreateOutlookExceptions(ai, ev);
                    itemModified++;
                }
            }

            String summaryObfuscated = Obfuscate.ApplyRegex(ev.Summary, SyncDirection.GoogleToOutlook);

            if (MainForm.CompareAttribute("Subject", SyncDirection.GoogleToOutlook, summaryObfuscated, ai.Subject, sb, ref itemModified))
            {
                ai.Subject = summaryObfuscated;
            }
            if (!Settings.Instance.AddDescription)
            {
                ev.Description = "";
            }
            if (Settings.Instance.SyncDirection == SyncDirection.GoogleToOutlook || !Settings.Instance.AddDescription_OnlyToGoogle)
            {
                if (MainForm.CompareAttribute("Description", SyncDirection.GoogleToOutlook, ev.Description, ai.Body, sb, ref itemModified))
                {
                    ai.Body = ev.Description;
                }
            }

            if (MainForm.CompareAttribute("Location", SyncDirection.GoogleToOutlook, ev.Location, ai.Location, sb, ref itemModified))
            {
                ai.Location = ev.Location;
            }

            String oPrivacy = (ai.Sensitivity == OlSensitivity.olNormal) ? "default" : "private";
            String gPrivacy = (ev.Visibility == null ? "default" : ev.Visibility);

            if (MainForm.CompareAttribute("Private", SyncDirection.GoogleToOutlook, gPrivacy, oPrivacy, sb, ref itemModified))
            {
                ai.Sensitivity = (ev.Visibility != null && ev.Visibility == "private") ? OlSensitivity.olPrivate : OlSensitivity.olNormal;
            }
            String oFreeBusy = (ai.BusyStatus == OlBusyStatus.olFree) ? "transparent" : "opaque";
            String gFreeBusy = (ev.Transparency == null ? "opaque" : ev.Transparency);

            if (MainForm.CompareAttribute("Free/Busy", SyncDirection.GoogleToOutlook, gFreeBusy, oFreeBusy, sb, ref itemModified))
            {
                ai.BusyStatus = (ev.Transparency != null && ev.Transparency == "transparent") ? OlBusyStatus.olFree : OlBusyStatus.olBusy;
            }

            if (Settings.Instance.AddAttendees)
            {
                if (ev.Description != null && ev.Description.Contains("===--- Attendees ---==="))
                {
                    //Protect against <v1.2.4 where attendees were stored as text
                    log.Info("This event still has attendee information in the description - cannot sync them.");
                }
                else if (Settings.Instance.SyncDirection == SyncDirection.Bidirectional &&
                         ev.Attendees != null && ev.Attendees.Count == 0 && ai.Recipients.Count > 150)
                {
                    log.Info("Attendees not being synced - there are too many (" + ai.Recipients.Count + ") for Google.");
                }
                else
                {
                    //Build a list of Outlook attendees. Any remaining at the end of the diff must be deleted.
                    List <Recipient> removeRecipient = new List <Recipient>();
                    if (ai.Recipients != null)
                    {
                        foreach (Recipient recipient in ai.Recipients)
                        {
                            if (recipient.Name != ai.Organizer)
                            {
                                removeRecipient.Add(recipient);
                            }
                        }
                    }
                    if (ev.Attendees != null)
                    {
                        for (int g = ev.Attendees.Count - 1; g >= 0; g--)
                        {
                            bool          foundRecipient = false;
                            EventAttendee attendee       = ev.Attendees[g];

                            foreach (Recipient recipient in ai.Recipients)
                            {
                                if (!recipient.Resolved)
                                {
                                    recipient.Resolve();
                                }
                                String recipientSMTP = IOutlook.GetRecipientEmail(recipient);
                                if (recipientSMTP.ToLower() == attendee.Email.ToLower())
                                {
                                    foundRecipient = true;
                                    removeRecipient.Remove(recipient);

                                    //Optional attendee
                                    bool oOptional = (ai.OptionalAttendees != null && ai.OptionalAttendees.Contains(attendee.DisplayName ?? attendee.Email));
                                    bool gOptional = (attendee.Optional == null) ? false : (bool)attendee.Optional;
                                    if (MainForm.CompareAttribute("Recipient " + recipient.Name + " - Optional Check",
                                                                  SyncDirection.GoogleToOutlook, gOptional, oOptional, sb, ref itemModified))
                                    {
                                        if (gOptional)
                                        {
                                            recipient.Type = (int)OlMeetingRecipientType.olOptional;
                                        }
                                        else
                                        {
                                            recipient.Type = (int)OlMeetingRecipientType.olRequired;
                                        }
                                    }
                                    //Response is readonly in Outlook :(
                                    break;
                                }
                            }
                            if (!foundRecipient &&
                                (attendee.DisplayName != ai.Organizer)) //Attendee in Google is owner in Outlook, so can't also be added as a recipient)
                            {
                                sb.AppendLine("Recipient added: " + (attendee.DisplayName ?? attendee.Email));
                                createRecipient(attendee, ai);
                                itemModified++;
                            }
                        }
                    }

                    foreach (Recipient recipient in removeRecipient)
                    {
                        sb.AppendLine("Recipient removed: " + recipient.Name);
                        recipient.Delete();
                        itemModified++;
                    }
                }
            }
            //Reminders
            if (Settings.Instance.AddReminders)
            {
                if (ev.Reminders.Overrides != null)
                {
                    //Find the popup reminder in Google
                    for (int r = ev.Reminders.Overrides.Count - 1; r >= 0; r--)
                    {
                        EventReminder reminder = ev.Reminders.Overrides[r];
                        if (reminder.Method == "popup")
                        {
                            if (ai.ReminderSet)
                            {
                                if (MainForm.CompareAttribute("Reminder", SyncDirection.GoogleToOutlook, reminder.Minutes.ToString(), ai.ReminderMinutesBeforeStart.ToString(), sb, ref itemModified))
                                {
                                    ai.ReminderMinutesBeforeStart = (int)reminder.Minutes;
                                }
                            }
                            else
                            {
                                sb.AppendLine("Reminder: nothing => " + reminder.Minutes);
                                ai.ReminderSet = true;
                                ai.ReminderMinutesBeforeStart = (int)reminder.Minutes;
                                itemModified++;
                            } //if Outlook reminders set
                        }     //if google reminder found
                    }         //foreach reminder
                }
                else     //no google reminders set
                {
                    if (ai.ReminderSet)
                    {
                        sb.AppendLine("Reminder: " + ai.ReminderMinutesBeforeStart + " => removed");
                        ai.ReminderSet = false;
                        itemModified++;
                    }
                }
            }
            if (itemModified > 0)
            {
                MainForm.Instance.Logboxout(sb.ToString(), false, verbose: true);
                MainForm.Instance.Logboxout(itemModified + " attributes updated.", verbose: true);
                System.Windows.Forms.Application.DoEvents();
            }
            return(ai);
        }
Пример #37
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);
                }
            }
        }
Пример #38
0
        private void processOutlookExceptions(AppointmentItem ai, Event ev, Boolean forceCompare)
        {
            if (!HasExceptions(ev, checkLocalCacheOnly: true)) return;

            if (!ai.Saved) ai.Save();

            RecurrencePattern oPattern = ai.GetRecurrencePattern();
            foreach (Event gExcp in Recurrence.Instance.googleExceptions.Where(exp => exp.RecurringEventId == ev.Id)) {
                log.Fine("Found Google exception for " + (gExcp.OriginalStartTime.DateTime ?? gExcp.OriginalStartTime.Date));

                DateTime oExcpDate = DateTime.Parse(gExcp.OriginalStartTime.DateTime ?? gExcp.OriginalStartTime.Date);
                AppointmentItem newAiExcp = getOutlookInstance(oPattern, oExcpDate);
                if (newAiExcp == null) continue;

                if (gExcp.Status != "cancelled") {
                    int itemModified = 0;
                    newAiExcp = OutlookCalendar.Instance.UpdateCalendarEntry(newAiExcp, gExcp, ref itemModified, forceCompare);
                    if (itemModified > 0) {
                        try {
                            newAiExcp.Save();
                        } catch (System.Exception ex) {
                            log.Warn(ex.Message);
                            if (ex.Message == "Cannot save this item.") {
                                MainForm.Instance.Logboxout("Uh oh! Outlook wasn't able to save this recurrence exception! " +
                                    "You may have two occurences on the same day, which it doesn't allow.");
                            }
                        }
                    }
                } else {
                    MainForm.Instance.Logboxout(OutlookCalendar.GetEventSummary(ai) + "\r\nDeleted.");
                    newAiExcp.Delete();
                }
                newAiExcp = (AppointmentItem)OutlookCalendar.ReleaseObject(newAiExcp);
            }
            if (!ai.Saved) ai.Save();
            oPattern = (RecurrencePattern)OutlookCalendar.ReleaseObject(oPattern);
        }
        public static void UpdateGoogleExceptions(AppointmentItem ai, Event ev) {
            if (ai.IsRecurring) {
                RecurrencePattern recurrence = ai.GetRecurrencePattern();
                if (recurrence.Exceptions.Count > 0) {
                    log.Debug(OutlookCalendar.GetEventSummary(ai));
                    log.Debug("This is a recurring appointment with " + recurrence.Exceptions.Count + " exceptions that will now be iteratively compared.");
                    foreach (Microsoft.Office.Interop.Outlook.Exception oExcp in recurrence.Exceptions) {
                        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 = oIsDeleted ? oExcp.OriginalDate : oExcp.AppointmentItem.Start;
                        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(oExcp, ev.RecurringEventId ?? ev.Id, OutlookCalendar.Instance.IOutlook.GetGlobalApptID(ai));
                        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;
                            }
                            try {
                                GoogleCalendar.Instance.UpdateCalendarEntry(oExcp.AppointmentItem, gExcp, ref excp_itemModified);
                            } catch (System.Exception ex) {
                                if (oIsDeleted) {
                                    if (gExcp.Status != "cancelled") {
                                        gExcp.Status = "cancelled";
                                        excp_itemModified++;
                                    }
                                } else {
                                    log.Error(ex.Message);
                                    log.Error(ex.StackTrace);
                                    recurrence = (RecurrencePattern)OutlookCalendar.ReleaseObject(recurrence);
                                    throw ex;
                                }
                            }
                            if (excp_itemModified > 0) {
                                try {
                                    GoogleCalendar.Instance.UpdateCalendarEntry_save(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.");
                                    }
                                } finally {
                                    recurrence = (RecurrencePattern)OutlookCalendar.ReleaseObject(recurrence);
                                }
                            }
                        } else {
                            log.Debug("No matching Google Event recurrence found.");
                            if (oIsDeleted) log.Debug("The Outlook appointment is deleted, so not a problem.");
                        }
                    }
                }
                recurrence = (RecurrencePattern)OutlookCalendar.ReleaseObject(recurrence);
            }
        }
Пример #40
0
        /// <summary>
        /// Merges the with.
        /// </summary>
        /// <param name="googleCalendarItem">The google calendar item.</param>
        /// <param name="outlookCalendarItem">The outlook calendar item.</param>
        /// <returns>True if Changed.</returns>
        public static bool MergeWith(this EventEntry googleCalendarItem, AppointmentItem outlookCalendarItem)
        {
            var result = false;

            result |= googleCalendarItem.Title.ApplyProperty(g => g.Text, outlookCalendarItem.Subject);
            result |= googleCalendarItem.Content.ApplyProperty(g => g.Content, outlookCalendarItem.Body);

            if (googleCalendarItem.EventTransparency == null) googleCalendarItem.EventTransparency = new EventEntry.Transparency();
            result |= googleCalendarItem.EventTransparency.ApplyProperty(g => g.Value, outlookCalendarItem.BusyStatus.GetStatus());

            if (googleCalendarItem.EventVisibility == null) googleCalendarItem.EventVisibility = new EventEntry.Visibility();
            result |= googleCalendarItem.EventVisibility.ApplyProperty(g => g.Value, outlookCalendarItem.Sensitivity.GetStatus());

            result |= googleCalendarItem.Locations.Merge(outlookCalendarItem.Location);
            result |= googleCalendarItem.Participants.Merge(outlookCalendarItem);

            if (outlookCalendarItem.RecurrenceState == OlRecurrenceState.olApptNotRecurring)
            {
                When time = googleCalendarItem.Times.FirstOrInstance();
                if (!googleCalendarItem.Times.Any())
                    googleCalendarItem.Times.Add(time);

                result |= time.ApplyProperty(t => t.AllDay, outlookCalendarItem.AllDayEvent);
                result |= time.ApplyProperty(t => t.StartTime, outlookCalendarItem.Start);
                result |= time.ApplyProperty(t => t.EndTime, outlookCalendarItem.End);

                if (outlookCalendarItem.ReminderSet)
                {
                    Google.GData.Extensions.Reminder reminder = time.Reminders.FirstOrInstance(t => t.Method == Google.GData.Extensions.Reminder.ReminderMethod.alert);
                    var timespan = TimeSpan.FromMinutes(outlookCalendarItem.ReminderMinutesBeforeStart);
                    result |= reminder.ApplyProperty(r => r.Method, Google.GData.Extensions.Reminder.ReminderMethod.alert);
                    result |= reminder.ApplyProperty(r => r.Minutes, timespan.Minutes);
                    result |= reminder.ApplyProperty(r => r.Hours, timespan.Hours);
                    result |= reminder.ApplyProperty(r => r.Days, timespan.Days);
                }
            }
            else
            {
                if (googleCalendarItem.Recurrence == null) googleCalendarItem.Recurrence = new Recurrence();
                result |= googleCalendarItem.Recurrence.ApplyProperty(r => r.Value, RecurrenceSerializer.Serialize(outlookCalendarItem.GetRecurrencePattern(), outlookCalendarItem.Start, outlookCalendarItem.AllDayEvent));
            }

            return result;
        }