Esempio n. 1
0
 public async Task ActiveItemsChanged(string userId, FocusManageResult result)
 {
     foreach (var item in result.ActiveItems)
     {
         await NotifyOrInstall(userId, item);
     }
 }
Esempio n. 2
0
        public async Task RefreshGeofencesForActiveNavigations(string userId, FocusManageResult manageResult,
                                                               DateTimeOffset now)
        {
            var freshFences = await GetNewGeofencesForActiveNavigations(userId, manageResult, now);

            await _locationStore.AddGeofenceRequests(userId, freshFences);
        }
        private async Task <DateTimeOffset?> RequestLocationForItems(string userId, FocusManageResult manageResult, DateTimeOffset now, DateTimeOffset locationTimeStamp)
        {
            var candidates = manageResult.ActiveItems.Where(
                v => null != v.DirectionsMetadata &&
                null != v.Directions &&
                v.DirectionsMetadata.TravelStatus != TravelStatus.Finished);
            var requirement = UpdateTimes(candidates, now, locationTimeStamp).OrderBy(v => v.Time).FirstOrDefault();

            if (null != requirement)
            {
                await logger.LogForFocusItem(userId, requirement.FocusItem.Id, $"Location update for {requirement.Reason} {requirement.FocusItem.CalendarEvent?.Subject} at {requirement.Time:t}");

                if (requirement.Time < now + FocusConstants.ShortestLocationUpdateTime)
                {
                    return(now + FocusConstants.ShortestLocationUpdateTime);
                }
                return(requirement.Time);
            }
            return(null);
        }
Esempio n. 4
0
        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 ActiveItemsChanged(string userId, FocusManageResult res)
 {
     await hubContext.Clients.User(userId).SendAsync("focusChanged", res.ActiveItems);
 }
Esempio n. 6
0
        public async Task <GeofenceRequest[]> GetNewGeofencesForActiveNavigations(string userId, FocusManageResult manageResult,
                                                                                  DateTimeOffset now)
        {
            var geofences = manageResult.ActiveItems.Where(v => null != v.DirectionsMetadata && null == v.DirectionsMetadata.Error)
                            .Where(v => v.Directions.Routes[v.DirectionsMetadata.PeferredRoute].DepatureTime - now < FocusConstants.DeparturePending)
                            .SelectMany(item => GetGeofences(item));

            return((await Task.WhenAll(geofences.Select(async gfr => new { gfr, exists = await _locationStore.Exists(userId, gfr) })))
                   .Where(v => !v.exists).Select(v => v.gfr).ToArray());
        }
 public Task ActiveItemsChanged(string userId, FocusManageResult res)
 {
     return(Task.CompletedTask);
 }
        public async Task <LocationRequestResult> RequestLocationAsync(string userId, DateTimeOffset requestTime, FocusManageResult focusManageResult)
        {
            var storedLocation = await locationStore.GetLastLocationAsync(userId);

            bool   requestLocation = false;
            string requestReason   = null;

            if (null == storedLocation)
            {
                requestLocation = true;
                requestReason   = "No Location stored";
            }
            else if (storedLocation.Timestamp < (requestTime - FocusConstants.LastLocationCacheTime))
            {
                requestLocation = true;
                requestReason   = $"Last Location outdated {(requestTime - storedLocation.Timestamp).TotalMinutes:0}";
            }
            if (requestLocation)
            {
                var res = await pushSyncService.RequestLocationSync(userId, requestTime, requestTime.Add(FocusConstants.LocationRequestExpectedTime));

                return(new LocationRequestResult()
                {
                    LocationRequestSent = res.SyncRequested,
                    LocationRequestTime = res.SyncRequested ? requestTime : res.SyncPendingFor
                });
            }
            else
            {
                await logger.LogForUser(userId, $"Not requesting location because cached location from {storedLocation.Timestamp:s} is used");

                return(new LocationRequestResult()
                {
                    LocationRequestSent = false,
                    LocationRequestTime = null
                });
            }
        }
        public async Task <LocationResponse> LocationUpdateReceivedAsync(string userId, Location location, DateTimeOffset now, FocusManageResult focusManageResult)
        {
            await pushSyncService.SetLocationRequestDone(userId);

            await locationStore.UpdateLocationAsync(userId, location);

            //if (location.RequestSupport.HasValue && !location.RequestSupport.Value)
            //{
            //    return new LocationResponse();
            //}
            var response = new LocationResponse()
            {
                NextUpdateRequiredAt = await RequestLocationForItems(userId, focusManageResult, now, location.Timestamp),
                Geofences            = await locationStore.GetActiveGeofenceRequests(userId, now)
            };

            if (response.NextUpdateRequiredAt.HasValue)
            {
                await pushSyncService.SetLocationRequestedExternal(userId, response.NextUpdateRequiredAt.Value);
            }
            return(response);
        }