Beispiel #1
0
        public void CreateCalendarEntries(List <Event> events)
        {
            foreach (Event ev in events)
            {
                AppointmentItem newAi = IOutlook.UseOutlookCalendar().Items.Add() as AppointmentItem;
                try {
                    newAi = createCalendarEntry(ev);
                } catch (System.Exception ex) {
                    if (!Settings.Instance.VerboseOutput)
                    {
                        MainForm.Instance.Logboxout(GoogleCalendar.GetEventSummary(ev));
                    }
                    MainForm.Instance.Logboxout("WARNING: Appointment creation failed.\r\n" + ex.Message);
                    log.Error(ex.StackTrace);
                    if (MessageBox.Show("Outlook appointment creation failed. Continue with synchronisation?", "Sync item failed", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        continue;
                    }
                    else
                    {
                        newAi = (AppointmentItem)ReleaseObject(newAi);
                        throw new UserCancelledSyncException("User chose not to continue sync.");
                    }
                }

                try {
                    createCalendarEntry_save(newAi, ev);
                } catch (System.Exception ex) {
                    MainForm.Instance.Logboxout("WARNING: New appointment failed to save.\r\n" + ex.Message);
                    log.Error(ex.StackTrace);
                    if (MessageBox.Show("New Outlook appointment failed to save. Continue with synchronisation?", "Sync item failed", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        continue;
                    }
                    else
                    {
                        newAi = (AppointmentItem)ReleaseObject(newAi);
                        throw new UserCancelledSyncException("User chose not to continue sync.");
                    }
                }

                if (ev.Recurrence != null && ev.RecurringEventId == null && Recurrence.Instance.HasExceptions(ev))
                {
                    MainForm.Instance.Logboxout("This is a recurring item with some exceptions:-");
                    Recurrence.Instance.CreateOutlookExceptions(newAi, ev);
                    MainForm.Instance.Logboxout("Recurring exceptions completed.");
                }
                newAi = (AppointmentItem)ReleaseObject(newAi);
            }
        }
Beispiel #2
0
        private AppointmentItem createCalendarEntry(Event ev)
        {
            string itemSummary = GoogleCalendar.GetEventSummary(ev);

            log.Debug("Processing >> " + itemSummary);
            MainForm.Instance.Logboxout(itemSummary, verbose: true);

            AppointmentItem ai = IOutlook.UseOutlookCalendar().Items.Add() as AppointmentItem;

            //Add the Google event ID into Outlook appointment.
            AddOGCSproperty(ref ai, gEventID, ev.Id);

            ai.Start       = new DateTime();
            ai.End         = new DateTime();
            ai.AllDayEvent = (ev.Start.Date != null);
            ai             = OutlookCalendar.Instance.IOutlook.WindowsTimeZone_set(ai, ev);
            Recurrence.Instance.BuildOutlookPattern(ev, ai);

            ai.Subject = Obfuscate.ApplyRegex(ev.Summary, SyncDirection.GoogleToOutlook);
            if (Settings.Instance.AddDescription && ev.Description != null)
            {
                ai.Body = ev.Description;
            }
            ai.Location    = ev.Location;
            ai.Sensitivity = (ev.Visibility == "private") ? OlSensitivity.olPrivate : OlSensitivity.olNormal;
            ai.BusyStatus  = (ev.Transparency == "transparent") ? OlBusyStatus.olFree : OlBusyStatus.olBusy;

            if (Settings.Instance.AddAttendees && ev.Attendees != null)
            {
                foreach (EventAttendee ea in ev.Attendees)
                {
                    createRecipient(ea, ai);
                }
            }

            //Reminder alert
            if (Settings.Instance.AddReminders && ev.Reminders != null && ev.Reminders.Overrides != null)
            {
                foreach (EventReminder reminder in ev.Reminders.Overrides)
                {
                    if (reminder.Method == "popup")
                    {
                        ai.ReminderSet = true;
                        ai.ReminderMinutesBeforeStart = (int)reminder.Minutes;
                    }
                }
            }
            return(ai);
        }
Beispiel #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;
                        }
                    }
                }
            }
        }
Beispiel #4
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);
        }
Beispiel #5
0
        public void UpdateCalendarEntries(Dictionary <AppointmentItem, Event> entriesToBeCompared, ref int entriesUpdated)
        {
            entriesUpdated = 0;
            foreach (KeyValuePair <AppointmentItem, Event> compare in entriesToBeCompared)
            {
                int             itemModified   = 0;
                AppointmentItem ai             = IOutlook.UseOutlookCalendar().Items.Add() as AppointmentItem;
                Boolean         aiWasRecurring = compare.Key.IsRecurring;
                try {
                    ai = UpdateCalendarEntry(compare.Key, compare.Value, ref itemModified);
                } catch (System.Exception ex) {
                    if (!Settings.Instance.VerboseOutput)
                    {
                        MainForm.Instance.Logboxout(GoogleCalendar.GetEventSummary(compare.Value));
                    }
                    MainForm.Instance.Logboxout("WARNING: Appointment update failed.\r\n" + ex.Message);
                    log.Error(ex.StackTrace);
                    if (MessageBox.Show("Outlook appointment update failed. Continue with synchronisation?", "Sync item failed", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        continue;
                    }
                    else
                    {
                        ai = (AppointmentItem)ReleaseObject(ai);
                        throw new UserCancelledSyncException("User chose not to continue sync.");
                    }
                }

                if (itemModified > 0)
                {
                    try {
                        updateCalendarEntry_save(ai);
                        entriesUpdated++;
                    } catch (System.Exception ex) {
                        MainForm.Instance.Logboxout("WARNING: Updated appointment failed to save.\r\n" + ex.Message);
                        log.Error(ex.StackTrace);
                        if (MessageBox.Show("Updated Outlook appointment failed to save. Continue with synchronisation?", "Sync item failed", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                        {
                            continue;
                        }
                        else
                        {
                            ai = (AppointmentItem)ReleaseObject(ai);
                            throw new UserCancelledSyncException("User chose not to continue sync.");
                        }
                    }
                    if (!aiWasRecurring && ai.IsRecurring)
                    {
                        log.Debug("Appointment has changed from single instance to recurring, so exceptions may need processing.");
                        Recurrence.Instance.UpdateOutlookExceptions(ai, compare.Value);
                    }
                }
                else if (ai != null && ai.RecurrenceState != OlRecurrenceState.olApptMaster)     //Master events are always compared anyway
                {
                    log.Debug("Doing a dummy update in order to update the last modified date.");
                    AddOGCSproperty(ref ai, Program.OGCSmodified, DateTime.Now);
                    updateCalendarEntry_save(ai);
                }
                ai = (AppointmentItem)ReleaseObject(ai);
            }
        }