public ConflictResolution Resolve(string message, Microsoft.Office.Interop.Outlook.AppointmentItem outlookAppointment, Event googleAppointment, Synchronizer sync, bool keepOutlook, bool keepGoogle) { string name = string.Empty; _form.OutlookItemTextBox.Text = string.Empty; _form.GoogleItemTextBox.Text = string.Empty; if (outlookAppointment != null) { name = outlookAppointment.Subject + " - " + outlookAppointment.Start; _form.OutlookItemTextBox.Text += outlookAppointment.Body; } if (googleAppointment != null) { name = googleAppointment.Summary + " - " + Synchronizer.GetTime(googleAppointment); _form.GoogleItemTextBox.Text += googleAppointment.Description; } //ToDo: Make it more flexible _form.keepGoogle.Enabled = keepGoogle; _form.keepOutlook.Enabled = keepOutlook; _form.AllCheckBox.Visible = true; _form.messageLabel.Text = message; return(Resolve()); }
public DeleteResolution ResolveDelete(Event googleAppointment) { _form.Text = "Outlook appointment deleted"; _form.messageLabel.Text = "Outlook appointment \"" + googleAppointment.Summary + " - " + Synchronizer.GetTime(googleAppointment) + "\" doesn't exist aynmore. Do you want to delete it also on Google side?"; _form.OutlookItemTextBox.Text = String.Empty; _form.GoogleItemTextBox.Text += googleAppointment.Description; _form.keepOutlook.Text = "Keep Google"; _form.keepGoogle.Text = "Delete Google"; _form.skip.Enabled = false; return(ResolveDeletedOutlook()); }
public static void SyncAppointments(Synchronizer sync) { for (int i = 0; i < sync.Appointments.Count; i++) { AppointmentMatch match = sync.Appointments[i]; if (NotificationReceived != null) { string name = string.Empty; if (match.OutlookAppointment != null) { name = match.OutlookAppointment.Subject + " - " + match.OutlookAppointment.Start; } else if (match.GoogleAppointment != null) { name = match.GoogleAppointment.Summary + " - " + Synchronizer.GetTime(match.GoogleAppointment); } NotificationReceived(String.Format("Syncing appointment {0} of {1}: {2} ...", i + 1, sync.Appointments.Count, name)); } SyncAppointment(match, sync); } }
public ConflictResolution Resolve(Microsoft.Office.Interop.Outlook.AppointmentItem outlookAppointment, Event googleAppointment, Synchronizer sync, bool isNewMatch) { string name = string.Empty; _form.OutlookItemTextBox.Text = string.Empty; _form.GoogleItemTextBox.Text = string.Empty; if (outlookAppointment != null) { name = outlookAppointment.Subject + " - " + outlookAppointment.Start; _form.OutlookItemTextBox.Text += outlookAppointment.Body; } if (googleAppointment != null) { name = googleAppointment.Summary + " - " + Synchronizer.GetTime(googleAppointment); _form.GoogleItemTextBox.Text += googleAppointment.Description; } if (isNewMatch) { _form.messageLabel.Text = "This is the first time these appointments \"" + name + "\" are synced. Choose which you would like to keep."; _form.skip.Text = "Keep both"; } else { _form.messageLabel.Text = "Both the Outlook and Google Appointment \"" + name + "\" have been changed. Choose which you would like to keep."; } return(Resolve()); }
/// <summary> /// Matches outlook and Google appointment by a) id b) properties. /// </summary> /// <param name="sync">Syncronizer instance</param> /// <returns>Returns a list of match pairs (outlook appointment + Google appointment) for all appointment. Those that weren't matche will have it's peer set to null</returns> public static List <AppointmentMatch> MatchAppointments(Synchronizer sync) { Logger.Log("Matching Outlook and Google appointments...", EventType.Information); var result = new List <AppointmentMatch>(); var googleAppointmentExceptions = new List <Event>(); //for each outlook appointment try to get Google appointment id from user properties //if no match - try to match by properties //if no match - create a new match pair without Google appointment. //foreach (Outlook._AppointmentItem olc in outlookAppointments) var OutlookAppointmentsWithoutSyncId = new Collection <Outlook.AppointmentItem>(); #region Match first all outlookAppointments by sync id for (int i = 1; i <= sync.OutlookAppointments.Count; i++) { Outlook.AppointmentItem ola; try { ola = sync.OutlookAppointments[i] as Outlook.AppointmentItem; //For debugging: //if (ola.Subject == "Flex Pilot - Latest Status") // - 14.07.2014 11:30:00 // throw new Exception("Debugging: Flex Pilot - Latest Status"); if (ola == null || string.IsNullOrEmpty(ola.Subject) && ola.Start == AppointmentSync.outlookDateMin) { Logger.Log("Empty Outlook appointment found. Skipping", EventType.Warning); sync.SkippedCount++; sync.SkippedCountNotMatches++; continue; } else if (ola.MeetingStatus == Outlook.OlMeetingStatus.olMeetingCanceled || ola.MeetingStatus == Outlook.OlMeetingStatus.olMeetingReceivedAndCanceled) { Logger.Log("Skipping Outlook appointment found because it is cancelled: " + ola.Subject + " - " + ola.Start, EventType.Debug); //sync.SkippedCount++; //sync.SkippedCountNotMatches++; continue; } else if (Synchronizer.MonthsInPast > 0 && (ola.IsRecurring && ola.GetRecurrencePattern().PatternEndDate < DateTime.Now.AddMonths(-Synchronizer.MonthsInPast) || !ola.IsRecurring && ola.End < DateTime.Now.AddMonths(-Synchronizer.MonthsInPast)) || Synchronizer.MonthsInFuture > 0 && (ola.IsRecurring && ola.GetRecurrencePattern().PatternStartDate > DateTime.Now.AddMonths(Synchronizer.MonthsInFuture) || !ola.IsRecurring && ola.Start > DateTime.Now.AddMonths(Synchronizer.MonthsInFuture))) { Logger.Log("Skipping Outlook appointment because it is out of months range to sync:" + ola.Subject + " - " + ola.Start, EventType.Debug); continue; } //else if (ola.Subject != "Business Trip") //{//Only for debugging purposes, please comment if not needed // Logger.Log("Skipping Outlook appointment because of DEBUGGING:" + ola.Subject + " - " + ola.Start, EventType.Error); // continue; //} } catch (Exception ex) { //this is needed because some appointments throw exceptions Logger.Log("Accessing Outlook appointment threw and exception. Skipping: " + ex.Message, EventType.Warning); sync.SkippedCount++; sync.SkippedCountNotMatches++; continue; } //try //{ if (NotificationReceived != null) { NotificationReceived(String.Format("Matching appointment {0} of {1} by id: {2} ...", i, sync.OutlookAppointments.Count, ola.Subject)); } // Create our own info object to go into collections/lists, so we can free the Outlook objects and not run out of resources / exceed policy limits. //OutlookAppointmentInfo olci = new OutlookAppointmentInfo(ola, sync); //try to match this appointment to one of Google appointments Outlook.ItemProperties userProperties = ola.ItemProperties; Outlook.ItemProperty idProp = userProperties[sync.OutlookPropertyNameId]; try { if (idProp != null) { string googleAppointmentId = string.Copy((string)idProp.Value); Event foundAppointment = sync.GetGoogleAppointmentById(googleAppointmentId); var match = new AppointmentMatch(ola, null); if (foundAppointment != null && !foundAppointment.Status.Equals("cancelled")) { //we found a match by google id, that is not deleted or cancelled yet //ToDo: For an unknown reason, some appointments are duplicate in GoogleAppointments, therefore remove all duplicates before continuing while (foundAppointment != null) { match.AddGoogleAppointment(foundAppointment); result.Add(match); //Remove the appointment from the list to not sync it twice if (sync.GoogleAppointments.Contains(foundAppointment)) { sync.GoogleAppointments.Remove(foundAppointment); foundAppointment = sync.GetGoogleAppointmentById(googleAppointmentId); } else { foundAppointment = null; } } } else { OutlookAppointmentsWithoutSyncId.Add(ola); } } else { OutlookAppointmentsWithoutSyncId.Add(ola); } } finally { if (idProp != null) { Marshal.ReleaseComObject(idProp); } Marshal.ReleaseComObject(userProperties); } } #endregion #region Match the remaining appointments by properties for (int i = 0; i < OutlookAppointmentsWithoutSyncId.Count; i++) { Outlook.AppointmentItem ola = OutlookAppointmentsWithoutSyncId[i]; if (NotificationReceived != null) { NotificationReceived(String.Format("Matching appointment {0} of {1} by unique properties: {2} ...", i + 1, OutlookAppointmentsWithoutSyncId.Count, ola.Subject)); } //no match found by id => match by subject/title //create a default match pair with just outlook appointment. var match = new AppointmentMatch(ola, null); //foreach Google appointment try to match and create a match pair if found some match(es) for (int j = sync.GoogleAppointments.Count - 1; j >= 0; j--) { var googleAppointment = sync.GoogleAppointments[j]; // only match if there is a appointment targetBody, else // a matching Google appointment will be created at each sync if (!googleAppointment.Status.Equals("cancelled") && ola.Subject == googleAppointment.Summary && googleAppointment.Start.DateTime != null && ola.Start == googleAppointment.Start.DateTime) { match.AddGoogleAppointment(googleAppointment); sync.GoogleAppointments.Remove(googleAppointment); //ToDo: For an unknown reason, some appointments are duplicate in GoogleAppointments, therefore remove all duplicates before continuing Event foundAppointment = sync.GetGoogleAppointmentById(AppointmentPropertiesUtils.GetGoogleId(googleAppointment)); while (foundAppointment != null) { //we found a match by google id, that is not deleted yet match.AddGoogleAppointment(foundAppointment); //Remove the appointment from the list to not sync it twice if (sync.GoogleAppointments.Contains(foundAppointment)) { sync.GoogleAppointments.Remove(foundAppointment); foundAppointment = sync.GetGoogleAppointmentById(AppointmentPropertiesUtils.GetGoogleId(googleAppointment)); } else { foundAppointment = null; } } } } if (match.GoogleAppointment == null) { Logger.Log(string.Format("No match found for outlook appointment ({0}) => {1}", match.OutlookAppointment.Subject + " - " + match.OutlookAppointment.Start, (AppointmentPropertiesUtils.GetOutlookGoogleAppointmentId(sync, match.OutlookAppointment) != null ? "Delete from Outlook" : "Add to Google")), EventType.Information); } result.Add(match); } #endregion //for each Google appointment that's left (they will be nonmatched) create a new match pair without outlook appointment. for (int i = 0; i < sync.GoogleAppointments.Count; i++) { var googleAppointment = sync.GoogleAppointments[i]; //For debugging: //if (googleAppointment.Summary == "Flex Pilot - Latest Status") // throw new Exception("Debugging: Flex Pilot - Latest Status"); if (NotificationReceived != null) { NotificationReceived(String.Format("Adding new Google appointment {0} of {1} by unique properties: {2} ...", i + 1, sync.GoogleAppointments.Count, googleAppointment.Summary)); } if (googleAppointment.RecurringEventId != null) { sync.SkippedCountNotMatches++; googleAppointmentExceptions.Add(googleAppointment); } else if (googleAppointment.Status.Equals("cancelled")) { Logger.Log("Skipping Google appointment found because it is cancelled: " + googleAppointment.Summary + " - " + Synchronizer.GetTime(googleAppointment), EventType.Debug); //sync.SkippedCount++; //sync.SkippedCountNotMatches++; } else if (string.IsNullOrEmpty(googleAppointment.Summary) && (googleAppointment.Start == null || googleAppointment.Start.DateTime == null && googleAppointment.Start.Date == null)) { // no title or time sync.SkippedCount++; sync.SkippedCountNotMatches++; Logger.Log("Skipped GoogleAppointment because no unique property found (Subject or StartDate):" + googleAppointment.Summary + " - " + Synchronizer.GetTime(googleAppointment), EventType.Warning); } //else if (googleAppointment.Summary != "Business Trip") //{//Only for debugging purposes, please comment if not needed // Logger.Log("Skipping Google appointment because of DEBUGGING:" + googleAppointment.Summary + " - " + googleAppointment.Times[0].StartTime, EventType.Error); // continue; //} else { Logger.Log(string.Format("No match found for Google appointment ({0}) => {1}", googleAppointment.Summary + " - " + Synchronizer.GetTime(googleAppointment), (!string.IsNullOrEmpty(AppointmentPropertiesUtils.GetGoogleOutlookAppointmentId(sync.SyncProfile, googleAppointment)) ? "Delete from Google" : "Add to Outlook")), EventType.Information); var match = new AppointmentMatch(null, googleAppointment); result.Add(match); } } //for each Google appointment exception, assign to proper match for (int i = 0; i < googleAppointmentExceptions.Count; i++) { var googleAppointment = googleAppointmentExceptions[i]; if (NotificationReceived != null) { NotificationReceived(String.Format("Adding Google appointment exception {0} of {1} ...", i + 1, googleAppointmentExceptions.Count, googleAppointment.Summary + " - " + Synchronizer.GetTime(googleAppointment))); } //Search for original recurrent event in matches //AtomId atomId = new AtomId(googleAppointment.Id.AbsoluteUri.Substring(0, googleAppointment.Id.AbsoluteUri.LastIndexOf("/") + 1) + googleAppointment.RecurringEventId); bool found = false; foreach (AppointmentMatch match in result) { if (match.GoogleAppointment != null && googleAppointment.RecurringEventId.Equals(match.GoogleAppointment.Id)) { match.GoogleAppointmentExceptions.Add(googleAppointment); found = true; break; } } if (!found) { Logger.Log(string.Format("No match found for Google appointment exception: {0}", googleAppointment.Summary + " - " + Synchronizer.GetTime(googleAppointment)), EventType.Debug); } } return(result); }