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; } }
protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); AndroidExtensions.Initialize(this); AnalyticsHelper.Initialize(ApplicationContext); SetContentView(Resource.Layout.Main); var toolbar = FindViewById <Android.Support.V7.Widget.Toolbar> (Resource.Id.toolbar); ViewCompat.SetElevation(toolbar, TypedValue.ApplyDimension(ComplexUnitType.Dip, 2, Resources.DisplayMetrics)); SetSupportActionBar(toolbar); this.drawer = FindViewById <DrawerLayout> (Resource.Id.drawer_layout); drawer.SetDrawerShadow(Resource.Drawable.drawer_shadow, (int)GravityFlags.Start); drawerToggle = new Android.Support.V7.App.ActionBarDrawerToggle(this, drawer, Resource.String.open_drawer, Resource.String.close_drawer); drawer.AddDrawerListener(drawerToggle); SupportActionBar.SetDisplayHomeAsUpEnabled(true); SupportActionBar.SetHomeButtonEnabled(true); Hubway.Instance.Subscribe(this); FavoriteManager.FavoritesChanged += (sender, e) => aroundAdapter.Refresh(); drawerAround = FindViewById <ListView> (Resource.Id.left_drawer_around); drawerAround.ItemClick += HandleAroundItemClick; drawerAround.Adapter = aroundAdapter = new DrawerAroundAdapter(this); drawerMenu = FindViewById <NavigationView> (Resource.Id.left_drawer); drawerMenu.NavigationItemSelected += HandlerNavigationItemSelected; if (CheckGooglePlayServices()) { PostCheckGooglePlayServices(); } }
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); } }