private async Task UpdateExceptionsAsync(string id, IAppointmentSchedule schedule, bool force) { var exceptions = schedule.Recurrence.Exceptions.Where(kv => kv.Value != null); foreach (var kv in exceptions) { using (Logger.Scope($"GoogleCalendar.UpdateException({kv.Key.Date})")) { EventsResource.InstancesRequest instancesRequest = _service.Events.Instances(CalendarId, id); var originalStart = new DateTime(kv.Key.Year, kv.Key.Month, kv.Key.Day, schedule.Start.Hour, schedule.Start.Minute, schedule.Start.Second); TimeSpan utcOffset = schedule.StartTimeZone.GetUtcOffset(originalStart); string offsetFormat = (utcOffset < TimeSpan.Zero ? "\\-" : "") + "hh\\:mm"; instancesRequest.OriginalStart = $"{originalStart:yyyy-MM-ddTHH:mm:ss}{utcOffset.ToString(offsetFormat)}"; Events instances = await instancesRequest.ExecuteAsync().ConfigureAwait(false); Event instance = instances.Items.FirstOrDefault(); if (instance == null) { Logger.Warning($"Failed to find instance of \"{kv.Value}\" at {instancesRequest.OriginalStart} to create an exception"); continue; } if (force || kv.Value.LastModifiedDateTime > (instance.Updated ?? DateTime.MinValue)) { await UpdateAppointmentAsync(instance.Id, instance.Sequence, kv.Value, force).ConfigureAwait(false); } } } }
void ExportAppointment(Appointment apt) { AppointmentType aptType = apt.Type; if (aptType == AppointmentType.Pattern) { EnsurePatternId(apt); } else if (aptType != AppointmentType.Normal) { string eventPatternId = EnsurePatternId(apt.RecurrencePattern); Debug.Assert(!String.IsNullOrEmpty(eventPatternId)); if (aptType == AppointmentType.Occurrence) { return; } EventsResource.InstancesRequest instancesRequest = CalendarService.Events.Instances(CalendarEntry.Id, eventPatternId); OccurrenceCalculator calculator = OccurrenceCalculator.CreateInstance(apt.RecurrencePattern.RecurrenceInfo); instancesRequest.OriginalStart = GoogleCalendarUtils.ConvertEventDateTime(calculator.CalcOccurrenceStartTime(apt.RecurrenceIndex)).DateTimeRaw; Events occurrenceEvents = instancesRequest.Execute(); Debug.Assert(occurrenceEvents.Items.Count == 1); Event occurrence = occurrenceEvents.Items[0]; if (aptType == AppointmentType.ChangedOccurrence) { this.AssignProperties(apt, occurrence); } else if (aptType == AppointmentType.DeletedOccurrence) { occurrence.Status = "cancelled"; } Event changedOccurrence = CalendarService.Events.Update(occurrence, CalendarEntry.Id, occurrence.Id).Execute(); apt.CustomFields["eventId"] = changedOccurrence.Id; Log.WriteLine(String.Format("Exported {0} occurrance: {1}, id={2}", (aptType == AppointmentType.ChangedOccurrence) ? "changed" : "deleted", apt.Subject, changedOccurrence.Id)); return; } Event instance = this.CreateEvent(aptType); AssignProperties(apt, instance); Event result = CalendarService.Events.Insert(instance, CalendarEntry.Id).Execute(); Log.WriteLine(String.Format("Exported appointment: {0}, id={1}", apt.Subject, result.Id)); }