Skip to content

Commit

Permalink
G->O: Modify exceptions for existing recurring series.
Browse files Browse the repository at this point in the history
Don't filter out all-day series master occurrences that end on the sync window start date.
#2038
  • Loading branch information
phw198 committed Jan 12, 2025
1 parent ed8f509 commit 35768e2
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 139 deletions.
2 changes: 1 addition & 1 deletion src/OutlookGoogleCalendarSync/Google/GoogleCalendar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ public List<Event> GetCalendarEntriesInRange(System.DateTime from, System.DateTi
result = result.Except(cancelled).ToList();
}

List<Event> endsOnSyncStart = result.Where(ev => (ev.End != null && ev.End.SafeDateTime() == from)).ToList();
List<Event> endsOnSyncStart = result.Where(ev => (ev.End != null && ev.End.SafeDateTime() == from && ev.Recurrence == null)).ToList();
if (endsOnSyncStart.Count > 0) {
log.Debug(endsOnSyncStart.Count + " Google Events end at midnight of the sync start date window.");
result = result.Except(endsOnSyncStart).ToList();
Expand Down
39 changes: 22 additions & 17 deletions src/OutlookGoogleCalendarSync/Outlook.Graph/O365Calendar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ public Event GetCalendarEntry(String eventId) {
};
IEventInstancesCollectionRequest req = GraphClient.Me.Calendars[profile.UseOutlookCalendar.Id].Events[seriesId].Instances.Request(queryOptions);
req.Top(250);
req.Select("*");
req.Expand("extensions($filter=Id eq '" + CustomProperty.ExtensionName() + "')");
req.OrderBy("start/dateTime");
log.Fine(req.GetHttpRequestMessage().RequestUri.ToString());
Expand Down Expand Up @@ -259,15 +260,15 @@ public Event GetCalendarEntry(String eventId) {
List<Event> seriesOccurrences = result.Where(ai => ai.Type == EventType.Occurrence).ToList();
result = result.Except(seriesOccurrences).ToList();
result.Sort((x, y) => x.Start.SafeDateTime().CompareTo(y.Start.SafeDateTime()));
log.Fine(seriesOccurrences + " standard series occurrences removed.");
log.Fine(seriesOccurrences.Count + " standard series occurrences removed.");

Int32 allDayFiltered = 0;
Int32 availabilityFiltered = 0;
Int32 privacyFiltered = 0;
Int32 subjectFiltered = 0;
Int32 responseFiltered = 0;

List<Event> endsOnSyncStart = result.Where(ev => (ev.End != null && ev.End.SafeDateTime() == min)).ToList();
List<Event> endsOnSyncStart = result.Where(ai => (ai.End != null && ai.End.SafeDateTime() == min && ai.Type != EventType.SeriesMaster)).ToList();
if (endsOnSyncStart.Count > 0) {
log.Debug(endsOnSyncStart.Count + " Outlook Appointments end at midnight of the sync start date window.");
result = result.Except(endsOnSyncStart).ToList();
Expand Down Expand Up @@ -574,11 +575,12 @@ public void UpdateCalendarEntries(Dictionary<Microsoft.Graph.Event, GcalData.Eve
int itemModified = 0;
Microsoft.Graph.Event ai = compare.Key;

//Boolean aiWasRecurring = ai.IsRecurring;
Boolean aiWasRecurring = ai.Type == EventType.SeriesMaster;
Boolean needsUpdating = false;
Event aiPatch = new();
try {
needsUpdating = UpdateCalendarEntry(ref ai, compare.Value, ref itemModified, out aiPatch);
Boolean forceCompare = !aiWasRecurring && compare.Value.Recurrence != null;
needsUpdating = UpdateCalendarEntry(ref ai, compare.Value, ref itemModified, out aiPatch, forceCompare);
} catch (System.Exception ex) {
Forms.Main.Instance.Console.UpdateWithError(Ogcs.Google.Calendar.GetEventSummary("<br/>Appointment update failed.", compare.Value, out String anonSummary), ex, logEntry: anonSummary);
Ogcs.Exception.Analyse(ex, true);
Expand All @@ -601,25 +603,29 @@ public void UpdateCalendarEntries(Dictionary<Microsoft.Graph.Event, GcalData.Eve
else
throw new UserCancelledSyncException("User chose not to continue sync.");
}
/*if (ai.IsRecurring) {
if (!aiWasRecurring) log.Debug("Appointment has changed from single instance to recurring.");
log.Debug("Recurring master appointment has been updated, so now checking if exceptions need reinstating.");
Recurrence.Instance.UpdateOutlookExceptions(ref ai, compare.Value, forceCompare: true);
}*/
if (ai.Type == EventType.SeriesMaster) {
if (!aiWasRecurring) {
log.Debug("Appointment has changed from single instance to recurring.");
Recurrence.CreateOutlookExceptions(compare.Value, ai);
} else {
log.Debug("Recurring master appointment has been updated, so now checking if exceptions need reinstating.");
Recurrence.UpdateOutlookExceptions(compare.Value, ai, forceCompare: true);
}
}

} else {
/*if (ai.RecurrenceState == OlRecurrenceState.olApptMaster && compare.Value.Recurrence != null && compare.Value.RecurringEventId == null) {
if (ai.Type == EventType.SeriesMaster && compare.Value.Recurrence != null && compare.Value.RecurringEventId == null) {
log.Debug(Ogcs.Google.Calendar.GetEventSummary(compare.Value));
Recurrence.Instance.UpdateOutlookExceptions(ref ai, compare.Value, forceCompare: false);
Recurrence.UpdateOutlookExceptions(compare.Value, ai, forceCompare: false);

} else if (needsUpdating || CustomProperty.Exists(ai, CustomProperty.MetadataId.forceSave)) {
if (ai.LastModificationTime > compare.Value.Updated && !CustomProperty.Exists(ai, CustomProperty.MetadataId.forceSave))
if (ai.LastModifiedDateTime > compare.Value.Updated && !CustomProperty.Exists(ai, CustomProperty.MetadataId.forceSave))
continue;

log.Debug("Doing a dummy update in order to update the last modified date.");
CustomProperty.SetOGCSlastModified(ref ai);
updateCalendarEntry_save(ref ai);
}*/
UpdateCalendarEntry_save(ref ai);
}
}
}
}
Expand Down Expand Up @@ -721,7 +727,7 @@ public Boolean UpdateCalendarEntry(ref Microsoft.Graph.Event ai, GcalData.Event
log.Debug("Converting to non-recurring appointment.");
aiPatch.AdditionalData = new Dictionary<String, Object>();
aiPatch.AdditionalData.Add("Recurrence", null);
sb.Append("Recurrence: Removed.");
sb.Append("Recurrence: => Removed.");
itemModified++;
} else {
aiPatch.Recurrence = Recurrence.CompareOutlookPattern(ev, ai.Recurrence, Sync.Direction.GoogleToOutlook, sb, ref itemModified);
Expand All @@ -730,8 +736,7 @@ public Boolean UpdateCalendarEntry(ref Microsoft.Graph.Event ai, GcalData.Event
if (ev.Recurrence != null && ev.RecurringEventId == null) {
log.Debug("Converting to recurring appointment.");
aiPatch.Recurrence = Recurrence.BuildOutlookPattern(ev);
//***Recurrence.Instance.CreateOutlookExceptions(ref ai, ev);
sb.Append("Recurrence: Added.");
sb.Append("Recurrence: => Added");
itemModified++;
}
}
Expand Down
27 changes: 5 additions & 22 deletions src/OutlookGoogleCalendarSync/Outlook.Graph/O365CustomProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -328,27 +328,8 @@ private static System.DateTime get_datetime(Microsoft.Graph.Event ai, MetadataId
System.DateTime retVal = new System.DateTime();
String searchKey;
if (Exists(ai, key, out searchKey)) {
UserProperties ups = null;
UserProperty prop = null;
/*try {
ups = ai.UserProperties;
prop = ups.Find(searchKey);
if (prop != null) {
try {
if (prop.Type != OlUserPropertyType.olDateTime) {
log.Warn("Non-datetime property " + searchKey + " being retrieved as DateTime.");
retVal = DateTime.Parse(prop.Value.ToString());
} else
retVal = (DateTime)prop.Value;
} catch (System.Exception ex) {
log.Error("Failed to retrieve DateTime value for property " + searchKey);
Ogcs.Exception.Analyse(ex);
}
}
} finally {
prop = (UserProperty)Calendar.ReleaseObject(prop);
ups = (UserProperties)Calendar.ReleaseObject(ups);
}*/
if (!System.DateTime.TryParse(ai.OgcsExtension().AdditionalData[searchKey].ToString(), out retVal))
log.Error("Could not parse OgcsExtension value of " + ai.OgcsExtension().AdditionalData[searchKey].ToString());
}
return retVal;
}
Expand Down Expand Up @@ -407,7 +388,9 @@ public static void LogProperties(Microsoft.Graph.Event ai, log4net.Core.Level th
try {
log.Debug(Calendar.GetEventSummary(ai));
Microsoft.Graph.Extension ext = ai.OgcsExtension();
foreach (KeyValuePair<String, Object> prop in ext?.AdditionalData) {
if (ext == null) return;

foreach (KeyValuePair<String, Object> prop in ext.AdditionalData) {
if (prop.Key == metadataIdKeyName(MetadataId.gCalendarId))
log.Debug(prop.Key + "=" + EmailAddress.MaskAddress(prop.Value.ToString()));
else
Expand Down
Loading

0 comments on commit 35768e2

Please sign in to comment.