/// <summary> /// Gets a list of calendar events for a user from storage or the schedule site. /// </summary> /// <param name="user">The user to retrieve the calendar events for.</param> /// <param name="startDate">Start date to get event from.</param> /// <param name="endDate">End date to get events to.</param> public async Task <List <CalendarEvent> > GetEvents(ApplicationUser user, DateTime startDate, DateTime endDate) { string html = await _downloadLogic.GetScheduleHtml(user); List <CalendarEvent> onlineEvents = _downloadLogic.ParseScheduleHtml(html, user.ScheduleUsername); // Update storage with new and changed events // TODO: This should be done in a scheduled job in the future // TODO: Check whether we actually need to download again if it's been done recently foreach (CalendarEvent onlineEvent in onlineEvents) { CalendarEvent storageEvent = _storageLogic.GetEvent(onlineEvent.UserName, onlineEvent.StartDate); if (storageEvent == null) { // Add the new event _storageLogic.AddEvent(onlineEvent); } else if (storageEvent.IsDifferentFrom(onlineEvent)) { // Replace the existing event if it's been changed _storageLogic.RemoveEvent(storageEvent); _storageLogic.AddEvent(onlineEvent); } } List <CalendarEvent> storageEvents = _storageLogic.GetEvents(user.ScheduleUsername, startDate, endDate); if (onlineEvents.Any()) { // Determine which calendar events have been canceled and should be removed // Only look at storage events that start today because online events don't include history // TODO: This should be done in a scheduled job in the future var storageEventsToRemove = new List <CalendarEvent>(); foreach (CalendarEvent storageEvent in storageEvents.Where(se => se.StartDate > onlineEvents.Min(oe => oe.StartDate.Date))) { CalendarEvent onlineEvent = onlineEvents.FirstOrDefault(e => e.StartDate == storageEvent.StartDate); if (onlineEvent == null) { // Add the event for removal storageEventsToRemove.Add(storageEvent); } } // Remove the canceled events foreach (CalendarEvent storageEvent in storageEventsToRemove) { _storageLogic.RemoveEvent(storageEvent); storageEvents.RemoveAll(e => e.StartDate == storageEvent.StartDate); } } return(storageEvents); }