Пример #1
0
        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());
            }
        }
Пример #2
0
        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);
        }
Пример #3
0
 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;
     }
 }
Пример #4
0
        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();
            }
        }
Пример #5
0
        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);
            }
        }
Пример #6
0
        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());
                }
            }
        }
Пример #7
0
        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);
        }
Пример #8
0
        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);
        }
Пример #9
0
        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);
            }
        }