Пример #1
0
        /* This is a two steps process:
         *  1st: we need to visit the login form page to get two important pieces of data
         *    - the session ID cookie which will stay in our cache
         *    - the CSRF token that is generated on the fly in the form
         *  2nd: armed with those two things, we can then post to the login check page which
         *  will simply stamp our session ID as valid
         */
        async Task <bool> LoginToHubway()
        {
            var loginPage = await Client.GetStringAsync(HubwayLoginUrl).ConfigureAwait(false);

            var parser = new SimpleHtmlParser();
            var doc    = parser.ParseString(loginPage);
            var form   = doc.GetElementsByTagName("form")
                         .OfType <XmlElement> ()
                         .FirstOrDefault(n => n.GetAttribute("class") == "ed-popup-form_login__form");
            var inputs    = form.GetElementsByTagName("input").OfType <XmlElement> ().ToList();
            var csrfToken = inputs
                            .OfType <XmlElement> ()
                            .First(n => n.GetAttribute("name") == "_login_csrf_security_token")
                            .GetAttribute("value");

            var content = new FormUrlEncodedContent(new Dictionary <string, string> {
                { "_username", credentials.Username },
                { "_password", credentials.Password },
                { "_failure_path", "eightd_bike_profile__login" },
                { "ed_from_login_popup", "true" },
                { "_login_csrf_security_token", csrfToken }
            });
            var login = await Client.PostAsync(HubwayLoginCheckUrl, content).ConfigureAwait(false);

            return(login.StatusCode == HttpStatusCode.Found && login.Headers.Location == new Uri(HubwayProfileUrl));
        }
Пример #2
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);
        }