public static async Task <TimeZoneInfo> DetermineTimeZoneAsync(GeoTagsEntry geoTags) { var requestUri = string.Format(RequestTimeZoneUri, geoTags.LatitudeValue, geoTags.LongitudeValue, DateTime.Now.ToUnixTimestamp()); Logging.Debug(requestUri); using (var order = KillerOrder.Create(new WebClient(), 5000)) { var data = await order.Victim.DownloadStringTaskAsync(requestUri); var doc = XDocument.Parse(data); var zoneId = doc.Descendants(@"time_zone_id").FirstOrDefault()?.Value; if (zoneId == null) { throw new Exception("Invalid response"); } try { return(TimeZoneInfo.FindSystemTimeZoneById(zoneId)); } catch (TimeZoneNotFoundException) { var rawOffset = doc.Descendants(@"raw_offset").FirstOrDefault()?.Value; var zoneName = doc.Descendants(@"time_zone_name").FirstOrDefault()?.Value; if (rawOffset == null || zoneName == null) { throw new Exception("Invalid response"); } return(TimeZoneInfo.CreateCustomTimeZone(zoneId, TimeSpan.FromSeconds(FlexibleParser.ParseDouble(rawOffset)), zoneName, zoneName)); } } }
public async Task <WeatherDescription> GetWeatherAsync(GeoTagsEntry geoTags) { var requestUri = string.Format(RequestWeatherUri, geoTags.LatitudeValue, geoTags.LongitudeValue, InternalUtils.GetOpenWeatherApiCode()); #if DEBUG Logging.Write(requestUri); #endif using (var order = KillerOrder.Create(new WebClient(), 5000)) { var data = await order.Victim.DownloadStringTaskAsync(requestUri); XDocument doc; try { doc = XDocument.Parse(data); } catch (XmlException) { Logging.Warning("response: " + data); throw; } var temperatureValue = doc.Descendants(@"temperature").FirstOrDefault()?.Attribute(@"value")?.Value; var weatherNode = doc.Descendants(@"weather").FirstOrDefault(); if (temperatureValue == null || weatherNode == null) { throw new Exception("Invalid response"); } var temperature = FlexibleParser.ParseDouble(temperatureValue); var type = OpenWeatherTypeToCommonType((OpenWeatherType)int.Parse(weatherNode.Attribute(@"number")?.Value, NumberStyles.Any, CultureInfo.InvariantCulture)); var description = weatherNode.Attribute(@"value")?.Value; var icon = weatherNode.Attribute(@"icon")?.Value; var iconUri = icon == null ? null : string.Format(IconUri, icon); return(new WeatherDescription(type, temperature, description, iconUri)); } }
public void Update(double lat, double lng) { Sync(() => { _skipNext = true; _model.Latitude = GeoTagsEntry.ToLat(lat); _model.Longitude = GeoTagsEntry.ToLng(lng); _skipNext = false; }); }
public void Update(double lat, double lng) { Sync(() => { _skipNext = true; if (_bridge.Model != null) { _bridge.Model.Latitude = GeoTagsEntry.ToLat(lat); _bridge.Model.Longitude = GeoTagsEntry.ToLng(lng); } _skipNext = false; }); }
public static async Task <TimeZoneInfo> DetermineTimeZoneAsync(GeoTagsEntry geoTags) { var requestUri = string.Format(RequestTimeZoneUri, geoTags.LatitudeValue, geoTags.LongitudeValue, InternalUtils.GetTimeZoneDbApiCode()); #if DEBUG Logging.Debug(requestUri); #endif using (var order = KillerOrder.Create(new CookieAwareWebClient(), 15000)) { var data = await order.Victim.DownloadStringTaskAsync(requestUri); var doc = JObject.Parse(data); var zoneId = doc.GetStringValueOnly("zoneName"); if (zoneId == null) { throw new Exception("Invalid response"); } Logging.Write("Returned zone ID: " + zoneId); try { Logging.Write("Parsed as: " + TZConvert.GetTimeZoneInfo(zoneId).ToSerializedString()); return(TZConvert.GetTimeZoneInfo(zoneId)); } catch (TimeZoneNotFoundException) { var rawOffset = doc.GetStringValueOnly(@"gmtOffset"); return(TimeZoneInfo.CreateCustomTimeZone(zoneId, TimeSpan.FromSeconds(FlexibleParser.ParseDouble(rawOffset)), zoneId, zoneId)); } } /*var requestUri = string.Format(RequestTimeZoneUri, geoTags.LatitudeValue, geoTags.LongitudeValue, * DateTime.Now.ToUnixTimestamp(), InternalUtils.GetGoogleMapsApiCode()); * * using (var order = KillerOrder.Create(new WebClient(), 5000)) { * var data = await order.Victim.DownloadStringTaskAsync(requestUri); * var doc = XDocument.Parse(data); * var zoneId = doc.Descendants(@"time_zone_id").FirstOrDefault()?.Value; * if (zoneId == null) throw new Exception("Invalid response"); * * try { * return TZConvert.GetTimeZoneInfo(zoneId); * } catch (TimeZoneNotFoundException) { * var rawOffset = doc.Descendants(@"raw_offset").FirstOrDefault()?.Value; * var zoneName = doc.Descendants(@"time_zone_name").FirstOrDefault()?.Value; * if (rawOffset == null || zoneName == null) throw new Exception("Invalid response"); * return TimeZoneInfo.CreateCustomTimeZone(zoneId, TimeSpan.FromSeconds(FlexibleParser.ParseDouble(rawOffset)), zoneName, zoneName); * } * }*/ }
private void Model_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { if (_skipNext) { return; } switch (e.PropertyName) { case nameof(Model.Latitude): case nameof(Model.Longitude): var pair = new GeoTagsEntry(Model.Latitude, Model.Longitude); if (!pair.IsEmptyOrInvalid) { MapWebBrowser.Execute(@"moveTo", $@"{pair.LatitudeValue};{pair.LongitudeValue}"); } break; } }
public static async Task <WeatherDescription> TryToGetWeatherAsync(GeoTagsEntry geoTags) { CleanUpCache(); if (LocalCache.TryGetValue(geoTags, out var cached)) { return(cached.Item2); } try { var result = await new OpenWeatherApiProvider().GetWeatherAsync(geoTags); LocalCache[geoTags] = new CachedEntry(DateTime.Now, result); return(result); } catch (WebException e) { Logging.Warning(e.Message); return(null); } catch (Exception e) { Logging.Warning(e); return(null); } }
public static async Task <TimeZoneInfo> TryToDetermineAsync(GeoTagsEntry geoTags) { var key = Key + geoTags; if (CacheStorage.Contains(key)) { return(CacheStorage.Get <string>(key).As <TimeZoneInfo>()); } try { var result = await GoogleApiProvider.DetermineTimeZoneAsync(geoTags); CacheStorage.Set(key, result); return(result); } catch (WebException e) { Logging.Warning(e.Message); return(null); } catch (Exception e) { Logging.Warning(e); CacheStorage.Set(key, ""); return(null); } }
/// <summary> /// Complex method, but it’s the best I can think of for now. Due to async nature, /// all results will be returned in callbacks. There is no guarantee in which order callbacks /// will be called (and even if they will be called at all or not)! /// </summary> /// <param name="track">Track for which conditions will be loaded.</param> /// <param name="localWeather">Use local weather instead.</param> /// <param name="considerTimezones">Consider timezones while setting time. Be careful: you’ll get an unclamped time!</param> /// <param name="timeCallback">Set to null if you don’t need an automatic time.</param> /// <param name="weatherCallback">Set to null if you don’t need weather.</param> /// <param name="cancellation">Cancellation token.</param> /// <returns>Task.</returns> public static async Task UpdateConditions(TrackObjectBase track, bool localWeather, bool considerTimezones, [CanBeNull] Action <int> timeCallback, [CanBeNull] Action <WeatherDescription> weatherCallback, CancellationToken cancellation) { GeoTagsEntry trackGeoTags = null, localGeoTags = null; if (!localWeather || considerTimezones && timeCallback != null) { trackGeoTags = track.GeoTags; if (trackGeoTags == null || trackGeoTags.IsEmptyOrInvalid) { trackGeoTags = await TracksLocator.TryToLocateAsync(track); if (cancellation.IsCancellationRequested) { return; } } } if ((trackGeoTags == null || localWeather) && !string.IsNullOrWhiteSpace(SettingsHolder.Drive.LocalAddress)) { localGeoTags = await TracksLocator.TryToLocateAsync(SettingsHolder.Drive.LocalAddress); if (cancellation.IsCancellationRequested) { return; } } // Time var time = DateTime.Now.TimeOfDay.TotalSeconds.RoundToInt(); if (timeCallback != null) { if (trackGeoTags == null || !considerTimezones) { timeCallback.Invoke(time); } else { var timeZone = await TimeZoneDeterminer.TryToDetermineAsync(trackGeoTags); if (cancellation.IsCancellationRequested) { return; } timeCallback.Invoke((time + (int)(timeZone == null ? 0 : timeZone.BaseUtcOffset.TotalSeconds - TimeZoneInfo.Local.BaseUtcOffset.TotalSeconds) + SecondsPerDay) % SecondsPerDay); } } // Weather var tags = localWeather ? localGeoTags : trackGeoTags ?? localGeoTags; if (tags == null) { return; } var weather = await WeatherProvider.TryToGetWeatherAsync(tags); if (cancellation.IsCancellationRequested) { return; } if (weather != null) { weatherCallback?.Invoke(weather); } }
/// <summary> /// Complex method, but it’s the best I can think of for now. Due to async nature, /// all results will be returned in callbacks. There is no guarantee in which order callbacks /// will be called (and even if they will be called at all or not)! /// </summary> /// <param name="track">Track for which conditions will be loaded.</param> /// <param name="localWeather">Use local weather instead.</param> /// <param name="considerTimezones">Consider timezones while setting time. Be careful: you’ll get an unclamped time!</param> /// <param name="dateTimeCallback">Set to null if you don’t need an automatic time.</param> /// <param name="weatherCallback">Set to null if you don’t need weather.</param> /// <param name="cancellation">Cancellation token.</param> /// <returns>Task.</returns> public static async Task UpdateConditions(TrackObjectBase track, bool localWeather, bool considerTimezones, [CanBeNull] Action <DateTime> dateTimeCallback, [CanBeNull] Action <WeatherDescription> weatherCallback, CancellationToken cancellation) { GeoTagsEntry trackGeoTags = null, localGeoTags = null; if (!localWeather || considerTimezones && dateTimeCallback != null) { trackGeoTags = track.GeoTags; if (trackGeoTags == null || trackGeoTags.IsEmptyOrInvalid) { trackGeoTags = await TracksLocator.TryToLocateAsync(track); if (cancellation.IsCancellationRequested) { return; } } } if ((trackGeoTags == null || localWeather) && !string.IsNullOrWhiteSpace(SettingsHolder.Drive.LocalAddress)) { localGeoTags = await TracksLocator.TryToLocateAsync(SettingsHolder.Drive.LocalAddress); if (cancellation.IsCancellationRequested) { return; } } // Time var now = DateTime.Now; if (dateTimeCallback != null) { if (trackGeoTags == null || !considerTimezones) { dateTimeCallback.Invoke(now); } else { var data = DataProvider.Instance.TrackParams[track.MainTrackObject.Id]; var timeZone = data.ContainsKey(@"TIMEZONE") ? TZConvert.GetTimeZoneInfo(data.GetNonEmpty("TIMEZONE")) : await TimeZoneDeterminer.TryToDetermineAsync(trackGeoTags); if (cancellation.IsCancellationRequested) { return; } var offsetInSeconds = (int)(timeZone == null ? 0 : timeZone.BaseUtcOffset.TotalSeconds - TimeZoneInfo.Local.BaseUtcOffset.TotalSeconds); dateTimeCallback.Invoke(now + TimeSpan.FromSeconds(offsetInSeconds)); } } // Weather var tags = localWeather ? localGeoTags : trackGeoTags ?? localGeoTags; if (tags == null) { return; } var weather = await WeatherProvider.TryToGetWeatherAsync(tags); if (cancellation.IsCancellationRequested) { return; } if (weather != null) { weatherCallback?.Invoke(weather); } }