/// <summary>
        /// The get flight price.
        /// </summary>
        /// <param name="flight">
        /// The flight.
        /// </param>
        /// <param name="targetCurrency">
        /// The target currency.
        /// </param>
        /// <returns>
        /// The <see cref="string"/>.
        /// </returns>
        internal string GetFlightPrice(Flight flight, string targetCurrency)
        {
            double price = flight.Price;
            string flightCurrency = flight.JourneyData.Currency;
            string currencyCode = flightCurrency;

            var currencyProvider = AppContext.MonitorEnvironment.CurrencyProvider;
            if (currencyProvider != null)
            {
                if (string.IsNullOrEmpty(targetCurrency) || string.Equals(flightCurrency, targetCurrency, StringComparison.OrdinalIgnoreCase))
                {
                    price = flight.Price;
                }
                else
                {
                    if (currencyProvider.Convert(flight.Price, flightCurrency, targetCurrency, out price))
                    {
                        flightCurrency = targetCurrency;
                    }
                }

                currencyCode = currencyProvider.GetCurrencyInfo(flightCurrency).Symbol;
            }

            string result = price.ToString("#,0.0 ") + currencyCode;
            return result;
        }
        /// <summary>
        /// The get list view item.
        /// </summary>
        /// <param name="flight">
        /// The flight.
        /// </param>
        /// <param name="targetCurrency">
        /// The target currency.
        /// </param>
        /// <returns>
        /// The <see cref="ListViewItem"/>.
        /// </returns>
        internal ListViewItem GetListViewItem(Flight flight, string targetCurrency)
        {
            List<string> data = this.GetPresentationStrings(flight, targetCurrency);

            var item = new ListViewItem { UseItemStyleForSubItems = false, Tag = flight, Text = data[0] };

            var subItems = new ListViewItem.ListViewSubItem[data.Count - 1];
            for (int i = 1; i < data.Count; i++)
            {
                var sub = new ListViewItem.ListViewSubItem(item, data[i]);
                subItems[i - 1] = sub;
                if (i == 5)
                {
                    sub.Font = new Font(sub.Font, FontStyle.Bold);
                }
            }

            item.SubItems.AddRange(subItems);
            return item;
        }
Example #3
0
        /// <summary>
        /// Check if the flight detail is the same as the other flight (ignore the price and travel agency)
        /// </summary>
        /// <param name="otherFLight">
        /// The other F Light.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        public bool IsSameFlight(Flight otherFLight)
        {
            bool result = string.Equals(this.Operator, otherFLight.Operator, StringComparison.OrdinalIgnoreCase); // Operator
            if (result)
            {
                if (result = this.OutboundLeg != null && otherFLight.OutboundLeg != null)
                {
                    // Outbound leg
                    if (result = this.OutboundLeg.IsSame(otherFLight.OutboundLeg))
                    {
                        if (result = this.InboundLeg != null && otherFLight.InboundLeg != null)
                        {
                            // Inbound leg
                            result = this.InboundLeg.IsSame(otherFLight.InboundLeg);
                        }
                        else
                        {
                            result = this.InboundLeg == null && otherFLight.InboundLeg == null;
                        }
                    }
                }
                else
                {
                    result = this.OutboundLeg == null && otherFLight.OutboundLeg == null;
                }
            }

            return result;
        }
Example #4
0
        /// <summary>
        /// The filter flight.
        /// </summary>
        /// <param name="flight">
        /// The flight.
        /// </param>
        /// <param name="filter">
        /// The filter.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        private bool FilterFlight(Flight flight, ListViewFilter filter)
        {
            var data = this._lvFlightItemAdaptor.GetPresentationStrings(flight, this.ActiveCurrency);
            if (!data[filter.Column].IsMatch(filter.FilterString))
            {
                return false;
            }

            return true;
        }
Example #5
0
 /// <summary>
 /// The can buy.
 /// </summary>
 /// <param name="flight">
 /// The flight.
 /// </param>
 /// <returns>
 /// The <see cref="bool"/>.
 /// </returns>
 private bool CanBuy(Flight flight)
 {
     var result = flight != null && flight.TravelAgency != null && !string.IsNullOrEmpty(flight.TravelAgency.Url)
                   && !(flight.OutboundLeg != null && flight.OutboundLeg.Departure.Date <= DateTime.Now.Date);
     return result;
 }
Example #6
0
 /// <summary>
 /// Add flight to the journey's fare data
 /// </summary>
 /// <param name="flight">
 /// The flight.
 /// </param>
 public void AddFlight(Flight flight)
 {
     if (flight != null)
     {
         this.Flights.Add(flight);
         flight.JourneyData = this;
     }
 }
Example #7
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);
        }
        /// <summary>
        /// The get presentation strings.
        /// </summary>
        /// <param name="flight">
        /// The flight.
        /// </param>
        /// <param name="targetCurrency">
        /// The target currency.
        /// </param>
        /// <returns>
        /// The <see cref="List"/>.
        /// </returns>
        internal List<string> GetPresentationStrings(Flight flight, string targetCurrency)
        {
            string deptTime = flight.OutboundLeg.Departure.ToShortTimeString(),
                   outboundInfo = string.Format("({0}) - {1}", flight.OutboundLeg.Transit, flight.OutboundLeg.Duration.ToHourMinuteString()),
                   returnTime = flight.InboundLeg == null ? null : flight.InboundLeg.Departure.ToShortTimeString(),
                   inboundInfo = flight.InboundLeg == null
                                     ? null
                                     : string.Format("({0}) - {1}", flight.InboundLeg.Transit, flight.InboundLeg.Duration.ToHourMinuteString()),
                   flightCompany = flight.Operator,
                   price = this.GetFlightPrice(flight, targetCurrency),
                   travelPeriod = flight.OutboundLeg.Departure.ToString("ddd dd/MM/yyyy") + " - "
                                  + (flight.InboundLeg == null ? string.Empty : flight.InboundLeg.Departure.ToString("ddd dd/MM/yyyy")),
                   stayDuration =
                       ((int)(flight.InboundLeg == null ? 0 : (flight.InboundLeg.Departure.Date - flight.OutboundLeg.Departure.Date).TotalDays))
                           .ToString(CultureInfo.InvariantCulture),
                   dataDate = flight.JourneyData.DataDate.ToString("ddd, MMM dd, yyyy h:mm:ss tt"),
                   agency = flight.TravelAgency == null ? null : flight.TravelAgency.Name;

            var result = new List<string>
                             {
                                 deptTime,
                                 outboundInfo,
                                 returnTime,
                                 inboundInfo,
                                 flightCompany,
                                 price,
                                 travelPeriod,
                                 stayDuration,
                                 dataDate,
                                 agency
                             };

            return result;
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="MenuBuilderEventArgs"/> class.
 /// </summary>
 /// <param name="selectedFlight">
 /// The selected flight.
 /// </param>
 public MenuBuilderEventArgs(Flight selectedFlight)
 {
     this.SelectedFlight = selectedFlight;
 }