public async Task <FocusManageResult> Update(string userId, FocusUpdateRequest focusUpdateRequest) { if (null != focusUpdateRequest.Location) { await _focusGeofenceService.UpdateFocusItems(userId, focusUpdateRequest.Location); } var res = new FocusManageResult(); var activeItems = await focusStore.GetActiveAsync(userId); var updatedItemIds = new HashSet <string>(focusUpdateRequest.ItemSyncResult != null ? focusUpdateRequest.ItemSyncResult.ChangedItems.Select(v => v.Id) : new string[0]); foreach (var item in activeItems) { var evt = await calendarServiceClient.Users[userId].Feeds[item.CalendarEventFeedId].Events.Get(item.CalendarEventId); TransitDirections directions; if (null != focusUpdateRequest.ItemSyncResult && ( focusUpdateRequest.ItemSyncResult.AddedItems.Any(v => v.Id == item.Id) || focusUpdateRequest.ItemSyncResult.ChangedItems.Any(v => v.Id == item.Id)) || null == item.DirectionsMetadata?.Key) { directions = await GetFreshDirections(userId, evt, item, focusUpdateRequest.Location); } else { var directionsRes = await GetCachedDirectionsOrNew(userId, evt, item, focusUpdateRequest.Location); directions = directionsRes.Directions; if (directionsRes.IsNew) { updatedItemIds.Add(item.Id); } if (null != directions && null != focusUpdateRequest.ChangedDirections && focusUpdateRequest.ChangedDirections.Contains( item.DirectionsMetadata.Key)) { await logger.LogForFocusItem(userId, item.Id, $"Received direction updates for {evt.Subject}", DigitTraceAction.DirectionsUpdate); updatedItemIds.Add(item.Id); } } DateTimeOffset indicateTime; if (null == directions) { await logger.LogForFocusItem(userId, item.Id, $"No departure time found, using {FocusConstants.DefaultTravelTime.TotalMinutes:0} minutes for {evt.Subject}"); indicateTime = evt.Start - FocusConstants.DefaultTravelTime; } else { indicateTime = directions.Routes[item.DirectionsMetadata.PeferredRoute].DepatureTime; } item.IndicateTime = indicateTime; await focusStore.UpdateIndicateTime(item.Id, indicateTime); res.ActiveItems.Add(new FocusItemWithExternalData() { Start = item.Start, IndicateTime = item.IndicateTime, CalendarEvent = evt, Directions = directions, DirectionsMetadata = item.DirectionsMetadata, End = item.End, Id = item.Id }); } await _focusGeofenceService.RefreshGeofencesForActiveNavigations(userId, res, DateTimeOffset.Now); var active = await focusStore.GetActiveItem(userId); var activeItemChanged = await focusStore.UpdateActiveItem(userId, active?.Id); if (activeItemChanged || (null != active && updatedItemIds.Contains(active.Id))) { if (null != active) { await Task.WhenAll(focusSubscribers.Select(v => v.ActiveItemChanged(userId, res.ActiveItems.Where(d => d.Id == active.Id).Single()))); } else { await Task.WhenAll(focusSubscribers.Select(v => v.ActiveItemChanged(userId, null))); } } if (updatedItemIds.Count > 0) { await Task.WhenAll(focusSubscribers.Select(v => v.ActiveItemsChanged(userId, res))); } return(res); }
public async Task<Plan> GetPlan(string userId, DateTimeOffset from, DateTimeOffset to) { string start = "#home"; var syncResult = await _focusCalendarSyncService.SyncAsync(userId, from, to); var items = (await _focusStore.GetTimeRangeAsync(userId, from, to)).OrderBy(d => d.Start); var directionsList = new List<DirectionsResult>(); var focusItemsList = new List<FocusItem>(); DateTimeOffset? getup = null; bool first = true; foreach (var e in items) { var calendarItem = syncResult.Events.Where(c => c.Id == e.CalendarEventId && c.FeedId == e.CalendarEventFeedId).SingleOrDefault(); if (null != calendarItem) { if (first) { } focusItemsList.Add(e); var address = calendarItem.GetFormattedAddress(); if (!string.IsNullOrEmpty(address)) { var directions = await _travelServiceClient.Users[userId] .Directions.Transit.Get(start, address, calendarItem.Start); var route = DirectionUtils.SelectRoute(directions); if (null == directions.NotFound) { if (first) { getup = route.DepatureTime - TimeSpan.FromHours(1); } directionsList.Add(directions); await _focusStore.UpdateDirections(e.Id, directions, 0); await _focusStore.UpdateIndicateTime(e.Id, route.DepatureTime); e.IndicateTime = route.DepatureTime; e.DirectionsMetadata = new DirectionsMetadata() { Error = directions.NotFound?.Reason, Key = directions.CacheKey, PeferredRoute = 0, TravelStatus = TravelStatus.UnStarted }; } else { await _focusStore.UpdateDirections(e.Id, directions, null); e.DirectionsMetadata = new DirectionsMetadata() { Error = directions.NotFound?.Reason, Key = directions.CacheKey, PeferredRoute = 0, TravelStatus = TravelStatus.UnStarted }; } start = address; } first = false; } } var plan = new Plan() { Events = syncResult.Events, Directions = directionsList.ToArray(), FocusItems = items.ToArray(), GetUp = getup }; return plan; }