Esempio n. 1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Flight"/> class.
 /// </summary>
 /// <param name="baseData">
 /// The base data.
 /// </param>
 /// <param name="flightOperator">
 /// The flight operator.
 /// </param>
 /// <param name="price">
 /// The price.
 /// </param>
 /// <param name="travelAgency">
 /// The travel agency.
 /// </param>
 /// <param name="outboundLeg">
 /// The outbound leg.
 /// </param>
 /// <param name="inboundLeg">
 /// The inbound leg.
 /// </param>
 public Flight(
     JourneyData baseData,
     string flightOperator,
     FlightLeg outboundLeg,
     FlightLeg inboundLeg)
 {
     this.JourneyData = baseData;
     this.Operator = flightOperator;
     this.OutboundLeg = outboundLeg;
     this.InboundLeg = inboundLeg;
     this.Fares = new List<Fare>();
 }
Esempio n. 2
0
        /// <summary>
        /// The parse web archive.
        /// </summary>
        /// <param name="webDocument">
        /// The web document.
        /// </param>
        /// <returns>
        /// The <see cref="RouteDataResult"/>.
        /// </returns>
        internal RouteDataResult ParseWebArchive(HtmlDocument webDocument)
        {
            HtmlNode originInput = webDocument.GetElementbyId("flight_places");
            if (originInput == null)
            {
                // Data is not ready yet
                return new RouteDataResult(DataResult.NotReady, null);
            }

            var resultDivs = webDocument.DocumentNode.SelectNodes("//div[@id='results_list']//div[@class='flights_a']");
            if (resultDivs == null || resultDivs.Count < 1)
            {
                // Data is not ready yet
                return new RouteDataResult(DataResult.NotReady, null);
            }

            var route = new TravelRoute(0, this.Departure, this.Destination);

            foreach (var resultSection in resultDivs)
            {
                // Each result set
                DateTime dataDate = DateTime.Now;
                var operatorData = new Dictionary<string, List<Flight>>();
                var newData = new JourneyData(0, "EUR", dataDate);

                FlightLeg outboundLeg = null, inboundLeg = null;
                string flightOperator = null;
                TravelAgency travelAgency = null;
                double price = 0.0;
                List<Fare> fares = new List<Fare>();

                var priceContainers = resultSection.SelectNodes(".//div[@class='f_price_container']//div[@class='row']");
                if (priceContainers == null || priceContainers.Count < 1)
                {
                    continue;
                }

                foreach (var priceContainer in priceContainers)
                {
                    string onClickStr = priceContainer.GetAttributeValue("onclick", string.Empty);
                    travelAgency = this.TryGetTravelAgency(onClickStr, false);

                    var priceNode = priceContainer.SelectSingleNode(".//div[@class='f_price']");
                    if (priceNode == null)
                    {
                        continue;
                    }

                    string priceStr = Regex.Match(priceNode.InnerText.Replace(",", "."), @"\d+(.\d+)?").Value;
                    double.TryParse(priceStr, NumberStyles.Any, NamingRule.NumberCulture, out price);
                    fares.Add(new Fare { TravelAgency = travelAgency, Price = price });
                }

                // Loop through each column in table
                var flightNode = resultSection.SelectSingleNode(".//div[@class='f_normal_info']");
                if (flightNode == null)
                {
                    continue;
                }

                foreach (HtmlNode flightDetailNode in flightNode.ChildNodes)
                {
                    // Fetch the flight detail from the row
                    if (flightDetailNode.Name != "div")
                    {
                        continue;
                    }

                    string className = flightDetailNode.GetAttributeValue("class", string.Empty);
                    switch (className)
                    {
                        case "f_outbound":
                        case "f_outbound_only":
                        case "f_return":
                            var divNodes = flightDetailNode.Descendants("div");
                            if (divNodes != null)
                            {
                                string depDatePartStr = null, depTimePartStr = null, stopStr = null, arrDatePartStr = null, arrTimePartStr = null;
                                TimeSpan duration = TimeSpan.Zero;
                                foreach (var dataNode in divNodes)
                                {
                                    // Each flight
                                    string dataClass = dataNode.GetAttributeValue("class", string.Empty);
                                    switch (dataClass)
                                    {
                                        case "f_dep_date":
                                            depDatePartStr = dataNode.InnerText;
                                            break;
                                        case "f_departure":
                                            depTimePartStr = dataNode.InnerText;
                                            break;
                                        case "f_arr_date":
                                            arrDatePartStr = dataNode.InnerText;
                                            break;
                                        case "f_arrival":
                                            arrTimePartStr = dataNode.InnerText;
                                            break;
                                        case "f_duration":
                                            duration = this.TryGetDuration(dataNode.InnerText);
                                            break;
                                        case "f_stops":
                                            stopStr = TryGetNumberString(dataNode.InnerText);
                                            break;
                                    }
                                }

                                // Validate that we got all required data
                                string depDateStr = string.Format(CultureInfo.InvariantCulture, "{0} {1}", depDatePartStr, depTimePartStr),
                                       arrDateStr = string.Format(CultureInfo.InvariantCulture, "{0} {1}", arrDatePartStr, arrTimePartStr);
                                DateTime deptDate, arrDate;
                                if (DateTime.TryParseExact(
                                    depDateStr,
                                    "dd.MM.yy HH:mm",
                                    CultureInfo.InvariantCulture,
                                    DateTimeStyles.None,
                                    out deptDate) && deptDate.IsDefined()
                                    && DateTime.TryParseExact(
                                        arrDateStr,
                                        "dd.MM.yy HH:mm",
                                        CultureInfo.InvariantCulture,
                                        DateTimeStyles.None,
                                        out arrDate) && arrDate.IsDefined())
                                {
                                    if (duration > TimeSpan.Zero)
                                    {
                                        int transit;
                                        int.TryParse(stopStr, out transit); // This might fail for straight flight: Just ignore it
                                        var flightLeg = new FlightLeg(deptDate, arrDate, duration, transit);
                                        if (className == "f_return")
                                        {
                                            inboundLeg = flightLeg;
                                        }
                                        else
                                        {
                                            outboundLeg = flightLeg;
                                        }
                                    }
                                }
                            }

                            break;

                        case "f_company":
                            flightOperator = flightDetailNode.InnerText.Replace("mm. ", string.Empty);
                            break;
                    }
                }

                if (outboundLeg != null)
                {
                    bool shouldAdd;
                    if (shouldAdd = !operatorData.ContainsKey(flightOperator))
                    {
                        // Flight will always be added if it is the first from this operator
                        if (operatorData.Keys.Count == this.MaxAirlines)
                        {
                            // If we reached the limit for number of flight operators
                            continue;
                        }

                        operatorData.Add(flightOperator, new List<Flight>(this.MaxFlightsPerAirline));
                    }

                    var opearatorFlights = operatorData[flightOperator];
                    if (!shouldAdd)
                    {
                        // This is not the first fly from this operator
                        TimeSpan totalDuration = (outboundLeg == null ? TimeSpan.Zero : outboundLeg.Duration)
                                                 + (inboundLeg == null ? TimeSpan.Zero : inboundLeg.Duration);
                        var lastFlight = opearatorFlights[opearatorFlights.Count - 1];

                        if ((price - lastFlight.Price) > this.MinPriceMargin)
                        {
                            // If the price differs enough, add new flight if we still have space
                            if (opearatorFlights.Count < this.MaxFlightsPerAirline)
                            {
                                shouldAdd = true;
                            }
                        }
                        else
                        {
                            // The new price does not differ enough from last flight: Add or replace existing flight if the duration is shorter
                            for (int i = opearatorFlights.Count - 1; i >= 0; i--)
                            {
                                var f = opearatorFlights[i];
                                if ((price - f.Price) <= this.MinPriceMargin && totalDuration < f.Duration)
                                {
                                    opearatorFlights.RemoveAt(i);
                                    shouldAdd = true;
                                    break;
                                }
                            }
                        }
                    }

                    if (shouldAdd && fares.Count > 0)
                    {
                        var newFlight = new Flight(newData, flightOperator, outboundLeg, inboundLeg) { Fares = fares };
                        newData.AddFlight(newFlight);
                        opearatorFlights.Add(newFlight);
                    }
                }

                if (newData.Flights.Count > 0)
                {
                    Journey existJourney = null;
                    DateTime deptDate = newData.Flights[0].OutboundLeg.Departure.Date;
                    DateTime retDate = DateTime.MinValue;
                    if (newData.Flights[0].InboundLeg != null)
                    {
                        retDate = newData.Flights[0].InboundLeg.Departure.Date;
                    }

                    foreach (var j in route.Journeys)
                    {
                        if (j.DepartureDate == deptDate && j.ReturnDate == retDate)
                        {
                            existJourney = j;
                            break;
                        }
                    }

                    if (existJourney == null)
                    {
                        existJourney = new Journey();
                        route.AddJourney(existJourney);
                    }

                    existJourney.AddData(newData);
                    existJourney.DepartureDate = deptDate;
                    existJourney.ReturnDate = retDate;
                }
            }

            return new RouteDataResult(DataResult.Ready, route);
        }
Esempio n. 3
0
        /// <summary>
        /// Returns true if the flight leg has the same departure time, arrival time, total duration and number of transits
        /// </summary>
        /// <param name="otherLeg">
        /// The other Leg.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        public bool IsSame(FlightLeg otherLeg)
        {
            bool result;
            if (result = otherLeg != null)
            {
                if (result = this.Departure == otherLeg.Departure)
                {
                    if (result = this.Arrival == otherLeg.Arrival)
                    {
                        if (result = this.Duration == otherLeg.Duration)
                        {
                            result = this.Transit == otherLeg.Transit;
                        }
                    }
                }
            }

            return result;
        }