public void StoreRentals(Rental[] rentals) { var savedRentals = string.Empty; if (rentals != null) { try { var root = new XElement("rentals"); root.Add(rentals.Select(r => { return(new XElement("rental", new XAttribute("Id", r.Id), new XAttribute("FromStationName", r.FromStationName), new XAttribute("ToStationName", r.ToStationName), new XAttribute("Price", r.Price), new XAttribute("DepartureTime", r.DepartureTime), new XAttribute("ArrivalTime", r.ArrivalTime), new XAttribute("Duration", r.Duration))); })); savedRentals = root.ToString(); } catch (Exception e) { AnalyticsHelper.LogException("PreferencesRentalStorage", e); Log.Error("PreferencesRentalStorage", "Couldn't serialize existing rental: {0}", e.ToString()); } } using (var editor = prefs.Edit()) { editor.PutString(Key, savedRentals); editor.Commit(); } }
public async void FillUpMap(bool forceRefresh) { if (loading) { return; } loading = true; if (pane != null && pane.Opened) { pane.SetState(InfoPane.State.Closed, animated: false); } flashBar.ShowLoading(); try { var stations = await hubway.GetStations(forceRefresh); await SetMapStationPins(stations); lastUpdateText.Text = "Last refreshed: " + DateTime.Now.ToShortTimeString(); } catch (Exception e) { AnalyticsHelper.LogException("DataFetcher", e); Android.Util.Log.Debug("DataFetcher", e.ToString()); } flashBar.ShowLoaded(); showedStale = false; if (pendingSearchTerm != null) { OpenStationWithTerm(pendingSearchTerm); pendingSearchTerm = null; } loading = false; }
async Task <Asset> CreateWearAssetFrom(Station station) { var cacheDir = CacheDir.AbsolutePath; var file = Path.Combine(cacheDir, "StationBackgrounds", station.Id.ToString()); byte[] content = null; var url = GoogleApis.MakeStreetViewUrl(station.Location, 640, 400); try { if (!File.Exists(file)) { if (client == null) { client = new HttpClient(); } content = await client.GetByteArrayAsync(url); Directory.CreateDirectory(Path.GetDirectoryName(file)); File.WriteAllBytes(file, content); } else { content = File.ReadAllBytes(file); } } catch (Exception e) { e.Data ["URL"] = url; Android.Util.Log.Error("StreetViewBackground", e.ToString()); AnalyticsHelper.LogException("StreetViewBackground", e); } return(content == null ? null : Asset.CreateFromBytes(content)); }
public Rental[] GetStoredRentals() { var savedRentals = prefs.GetString(Key, null); if (string.IsNullOrEmpty(savedRentals)) { return(new Rental[0]); } try { var root = XElement.Parse(savedRentals); return(root.Elements("rental").Select(e => new Rental { Id = (long)e.Attribute("Id"), FromStationName = (string)e.Attribute("FromStationName"), ToStationName = (string)e.Attribute("ToStationName"), Price = (double)e.Attribute("Price"), DepartureTime = (DateTime)e.Attribute("DepartureTime"), ArrivalTime = (DateTime)e.Attribute("ArrivalTime"), Duration = (TimeSpan)e.Attribute("Duration") }).ToArray()); } catch (Exception e) { AnalyticsHelper.LogException("PreferencesRentalStorage", e); Log.Error("PreferencesRentalStorage", "Couldn't deserialize existing rental: {0}", e.ToString()); } return(null); }
public override ICursor Query(Android.Net.Uri uri, string[] projection, string selection, string[] selectionArgs, string sortOrder) { var query = uri.LastPathSegment.ToLowerInvariant(); IList <Address> addresses = null; try { addresses = geocoder.GetFromLocationName(query, SuggestionCount, LowerLeftLat, LowerLeftLon, UpperRightLat, UpperRightLon); } catch (Exception e) { AnalyticsHelper.LogException("SuggestionsFetcher", e); Android.Util.Log.Warn("SuggestionsFetcher", e.ToString()); addresses = new Address[0]; } var cursor = new MatrixCursor(new string[] { BaseColumns.Id, SearchManager.SuggestColumnText1, SearchManager.SuggestColumnText2, SearchManager.SuggestColumnIntentExtraData }, addresses.Count); long id = 0; foreach (var address in addresses) { int dummy; if (int.TryParse(address.Thoroughfare, out dummy)) { continue; } var options1 = new string[] { address.FeatureName, address.Thoroughfare }; var options2 = new string[] { address.Locality, address.AdminArea }; var line1 = string.Join(", ", options1.Where(s => !string.IsNullOrEmpty(s)).Distinct()); var line2 = string.Join(", ", options2.Where(s => !string.IsNullOrEmpty(s))); if (string.IsNullOrEmpty(line1) || string.IsNullOrEmpty(line2)) { continue; } cursor.AddRow(new Java.Lang.Object[] { id++, line1, line2, address.Latitude.ToSafeString() + "|" + address.Longitude.ToSafeString() }); } return(cursor); }
async void LoadStationHistory(int stationID) { try { using (var scope = ActivityScope.Of(Activity)) await DoLoadStationHistory(scope, stationID); } catch (Exception e) { AnalyticsHelper.LogException("HistoryFetcher", e); Android.Util.Log.Debug("HistoryFetcher", e.ToString()); } }
async ActivityTask DoFillUpMap(ActivityScope scope, bool forceRefresh) { try { var stations = await hubway.GetStations(forceRefresh); await SetMapStationPins(stations); lastUpdateText.Text = "Last refreshed: " + DateTime.Now.ToShortTimeString(); } catch (Exception e) { AnalyticsHelper.LogException("DataFetcher", e); Android.Util.Log.Debug("DataFetcher", e.ToString()); } }
void LaunchPlaceSearch() { const double LowerLeftLat = 42.343828; const double LowerLeftLon = -71.169777; const double UpperRightLat = 42.401150; const double UpperRightLon = -71.017685; try { var intent = new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.ModeFullscreen) .SetBoundsBias(new LatLngBounds(new LatLng(LowerLeftLat, LowerLeftLon), new LatLng(UpperRightLat, UpperRightLon))) .Build(Activity); StartActivityForResult(intent, SearchRequestID); } catch (Exception e) { AnalyticsHelper.LogException("PlaceSearch", e); Android.Util.Log.Debug("PlaceSearch", e.ToString()); } }
public async Task <Station[]> GetStations(bool forceRefresh = false, Action <string> dataCacher = null) { string data = null; if (HasCachedData && !forceRefresh) { return(LastStations); } if (stationDescriptions == null) { stationDescriptions = await GetStationDescriptions().ConfigureAwait(false); } while (data == null) { try { data = await client.GetStringAsync(HubwayStationStatusUrl).ConfigureAwait(false); } catch (Exception e) { AnalyticsHelper.LogException("HubwayDownloader", e); Android.Util.Log.Error("HubwayDownloader", e.ToString()); } if (data == null) { await Task.Delay(500); } } if (dataCacher != null) { dataCacher(data); } var stations = ParseStationsFromContent(data); if (subscribers.Any()) { foreach (var sub in subscribers) { sub.Observer.OnNext(stations); } } return(stations); }
public async void SetStationIds(HashSet <int> ids) { while (true) { try { var hubway = Hubway.Instance; var stationList = hubway.HasCachedData ? hubway.LastStations : (await hubway.GetStations()); stations = stationList .Where(s => ids.Contains(s.Id)) .OrderBy(s => s.Name) .ToList(); } catch (Exception e) { AnalyticsHelper.LogException("Favorite", e); Android.Util.Log.Error("Favorites", e.ToString()); } NotifyDataSetChanged(); break; } }
async void OpenStationWithTerm(string term) { try { var stations = await hubway.GetStations(); var bestResult = stations .Select(s => new { Station = s, Score = FuzzyStringMatch(term, s.Name) }) .Where(s => s.Score > 0.5f) .OrderByDescending(s => s.Score) .FirstOrDefault(); if (bestResult == null) { Toast.MakeText(Activity, "No station found for '" + term + "'", ToastLength.Short).Show(); return; } CenterAndOpenStationOnMap(bestResult.Station.Id); } catch (Exception e) { e.Data ["Term"] = term; AnalyticsHelper.LogException("TermStationSearch", e); } }
async Task FetchData() { historyCache = new Dictionary <int, IEnumerable <KeyValuePair <DateTime, int> > > (); for (int i = 0; i < 3; i++) { try { var data = await client.GetStringAsync(HistoryApiEndpoint); // If another update was done in the meantime, no need to process it if (!NeedFetching) { return; } var reader = new StringReader(data); string line = reader.ReadLine(); var times = line.Split('|').Select(t => DateTime.FromBinary(long.Parse(t))).ToArray(); while ((line = reader.ReadLine()) != null) { var split = line.Split('|'); var id = int.Parse(split[0]); var datapoints = split.Skip(1).Select((v, index) => { var time = times[index]; var num = int.Parse(v); return(new KeyValuePair <DateTime, int> (time, num)); }).ToArray(); historyCache[id] = datapoints; } lastFetch = DateTime.UtcNow; } catch (Exception e) { AnalyticsHelper.LogException("HistoryDownloader", e); Android.Util.Log.Error("HistoryDownloader", e.ToString()); } } }
public async Task <Rental[]> GetRentals(int page) { bool needsAuth = false; for (int i = 0; i < 4; i++) { try { if (needsAuth) { if (await LoginToHubway().ConfigureAwait(false)) { needsAuth = false; } else { continue; } } if (string.IsNullOrEmpty(credentials.UserId)) { credentials.UserId = await GetHubwayUserId().ConfigureAwait(false); if (string.IsNullOrEmpty(credentials.UserId)) { needsAuth = true; continue; } } var rentalsUrl = HubwayRentalsUrl + credentials.UserId; if (page > 0) { rentalsUrl += "?pageNumber=" + page; } var answer = await Client.GetStringAsync(rentalsUrl).ConfigureAwait(false); var parser = new SimpleHtmlParser(); var doc = parser.ParseString(answer); var div = doc.GetElementsByTagName("section") .OfType <XmlElement> () .First(s => s.GetAttribute("class") == "ed-profile-page__content"); var rows = div.GetElementsByTagName("div") .OfType <XmlElement> () .Where(n => n.ContainsClass("ed-table__item_trip")); return(rows.Select(row => { var cells = row.GetElementsByTagName("div").OfType <XmlElement> ().ToList(); /* 0 <div> * 1 <div>time start * 2 <div>station start * </div> * 3 <div> * 4 <div>time end * 5 <div>station end * </div> * 6 <div>duration * 7 <div>billed */ var rental = new Rental { FromStationName = cells[2].InnerText.Trim(), ToStationName = cells[5].InnerText.Trim(), Duration = ParseRentalDuration(cells[6].InnerText.Trim()), Price = ParseRentalPrice(cells[7].InnerText.Trim()), DepartureTime = DateTime.Parse(cells[1].InnerText, System.Globalization.CultureInfo.InvariantCulture), ArrivalTime = DateTime.Parse(cells[4].InnerText, System.Globalization.CultureInfo.InvariantCulture) }; rental.Id = ((long)rental.DepartureTime.GetHashCode()) << 32; rental.Id |= (uint)rental.ArrivalTime.GetHashCode(); return rental; }).ToArray()); } catch (HttpRequestException htmlException) { // Super hacky but oh well if (!needsAuth) { needsAuth = htmlException.Message.Contains("302"); } continue; } catch (Exception e) { AnalyticsHelper.LogException("RentalsGenericError", e); Log.Error("RentalsGenericError", e.ToString()); break; } } return(null); }
public async Task <Rental[]> GetRentals(int page) { bool needsAuth = false; var rentalsUrl = HubwayRentalsUrl; if (page > 0) { rentalsUrl += "/" + (page * 20); } for (int i = 0; i < 4; i++) { try { if (needsAuth) { var content = new FormUrlEncodedContent(new Dictionary <string, string> { { "username", credentials.Username }, { "password", credentials.Password } }); var login = await Client.PostAsync(HubwayLoginUrl, content).ConfigureAwait(false); if (login.StatusCode == HttpStatusCode.Found) { needsAuth = false; } else { continue; } } var answer = await Client.GetStringAsync(rentalsUrl).ConfigureAwait(false); var doc = new HtmlDocument(); doc.LoadHtml(answer); var div = doc.GetElementById("content"); var table = div.Element("table"); return(table.Element("tbody").Elements("tr").Select(row => { var items = row.Elements("td").ToArray(); return new Rental { Id = long.Parse(items[0].InnerText.Trim()), FromStationName = items [1].InnerText.Trim(), ToStationName = items [3].InnerText.Trim(), Duration = ParseRentalDuration(items [5].InnerText.Trim()), Price = ParseRentalPrice(items [6].InnerText.Trim()), DepartureTime = DateTime.Parse(items[2].InnerText, System.Globalization.CultureInfo.InvariantCulture), ArrivalTime = DateTime.Parse(items[4].InnerText, System.Globalization.CultureInfo.InvariantCulture) }; }).ToArray()); } catch (HttpRequestException htmlException) { // Super hacky but oh well if (!needsAuth) { needsAuth = htmlException.Message.Contains("302"); } continue; } catch (Exception e) { AnalyticsHelper.LogException("RentalsGenericError", e); Log.Error("RentalsGenericError", e.ToString()); break; } } return(null); }
async void HandleMessage(IMessageEvent message) { try { Android.Util.Log.Info("WearIntegration", "Received Message"); var client = new GoogleApiClientBuilder(this) .AddApi(LocationServices.API) .AddApi(WearableClass.API) .Build(); var result = client.BlockingConnect(30, Java.Util.Concurrent.TimeUnit.Seconds); if (!result.IsSuccess) { return; } var path = message.Path; try { var stations = Hubway.Instance.LastStations; if (stations == null) { stations = await Hubway.Instance.GetStations(); } if (path.StartsWith(SearchStationPath)) { var lastLocation = LocationServices.FusedLocationApi.GetLastLocation(client); if (lastLocation == null) { return; } var currentPoint = new GeoPoint { Lat = lastLocation.Latitude, Lon = lastLocation.Longitude }; var nearestStations = Hubway.GetStationsAround(stations, currentPoint, maxItems: 6, minDistance: double.MaxValue); var favManager = FavoriteManager.Obtain(this); var favorites = await favManager.GetFavoriteStationIdsAsync(); var request = PutDataMapRequest.Create(SearchStationPath + "/Answer"); var map = request.DataMap; var stationMap = new List <DataMap> (); foreach (var station in nearestStations) { var itemMap = new DataMap(); itemMap.PutInt("Id", station.Id); var asset = await CreateWearAssetFrom(station); itemMap.PutAsset("Background", asset); string secondary; string primary = StationUtils.CutStationName(station.Name, out secondary); itemMap.PutString("Primary", primary); itemMap.PutString("Secondary", secondary); var distance = GeoUtils.Distance(currentPoint, station.Location); itemMap.PutDouble("Distance", distance); itemMap.PutDouble("Lat", station.Location.Lat); itemMap.PutDouble("Lon", station.Location.Lon); itemMap.PutInt("Bikes", station.BikeCount); itemMap.PutInt("Racks", station.EmptySlotCount); itemMap.PutBoolean("IsFavorite", favorites.Contains(station.Id)); stationMap.Add(itemMap); } map.PutDataMapArrayList("Stations", stationMap); map.PutLong("UpdatedAt", DateTime.UtcNow.Ticks); await WearableClass.DataApi.PutDataItem(client, request.AsPutDataRequest()); } else { var uri = new Uri("wear://watch" + path); var query = uri.GetComponents(UriComponents.Query, UriFormat.Unescaped); var parts = uri.GetComponents(UriComponents.Path, UriFormat.Unescaped).Split('/'); var action = parts[parts.Length - 2]; var id = int.Parse(parts.Last()); if (action == FavoriteAction) { var favorites = FavoriteManager.Obtain(this); handler.Post(() => { if (query == "add") { favorites.AddToFavorite(id); } else { favorites.RemoveFromFavorite(id); } }); } } } finally { client.Disconnect(); } } catch (Exception e) { Android.Util.Log.Error("WearIntegration", e.ToString()); AnalyticsHelper.LogException("WearIntegration", e); } }