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 load data.
        /// </summary>
        /// <param name="journeys">
        /// The journeys.
        /// </param>
        /// <param name="loadHistory">
        /// The load history.
        /// </param>
        /// <param name="callback">
        /// The callback.
        /// </param>
        public void LoadData(IList<Journey> journeys, bool loadHistory, IProgressCallback callback)
        {
            this.Logger.DebugFormat("Load data for {0} journeys [{1}]", journeys.Count, loadHistory ? "H" : null);
            foreach (var j in journeys)
            {
                j.Data.Clear();
            }

            string condition = GenerateCondition(journeys);
            using (var connection = new SQLiteConnection(this._connectionString))
            {
                string selectSql = "SELECT LID, LJOURNEYID, SCURRENCY, BFLIGHT, " + (loadHistory ? "TUPDATE" : "MAX(TUPDATE) TUPDATE")
                                   + " FROM JOURNEY_DATA " + " WHERE " + condition + (loadHistory ? string.Empty : " GROUP BY (LJOURNEYID)");

                using (var getFlightsCmd = new SQLiteCommand(selectSql, connection))
                {
                    connection.Open();

                    using (var reader = getFlightsCmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            if (reader.HasRows)
                            {
                                int iId = reader.GetOrdinal("LID");
                                int iJourneyId = reader.GetOrdinal("LJOURNEYID");
                                int iCurrency = reader.GetOrdinal("SCURRENCY");
                                int iUpdate = reader.GetOrdinal("TUPDATE");
                                int iFlight = reader.GetOrdinal("BFLIGHT");

                                while (reader.Read())
                                {
                                    var flights = this._formatter.FromRaw<List<Flight>>((byte[])reader[iFlight]);
                                    if (flights != null && flights.Count > 0)
                                    {
                                        long dataId = reader.GetInt64(iId);
                                        long journeyId = reader.GetInt64(iJourneyId);
                                        string currency = reader.GetString(iCurrency);
                                        string dataDateStr = reader.GetString(iUpdate);
                                        DateTime dataDate = DateTime.ParseExact(
                                            dataDateStr,
                                            DATETIME_FORMAT,
                                            CultureInfo.InvariantCulture,
                                            DateTimeStyles.AssumeUniversal);

                                        var newData = new JourneyData(dataId, currency, dataDate);
                                        newData.AddFlights(flights);

                                        foreach (var j in journeys)
                                        {
                                            if (j.Id == journeyId)
                                            {
                                                j.AddData(newData);
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// The load data.
        /// </summary>
        /// <param name="route">
        /// The route.
        /// </param>
        /// <param name="loadJourneyData">
        /// The load journey data.
        /// </param>
        /// <param name="loadHistory">
        /// The load history.
        /// </param>
        /// <param name="loadFlights">
        /// The load flights.
        /// </param>
        /// <param name="callback">
        /// The callback.
        /// </param>
        /// <exception cref="ArgumentException">
        /// </exception>
        public void LoadData(TravelRoute route, bool loadJourneyData, bool loadHistory, bool loadFlights, IProgressCallback callback)
        {
            this.Logger.DebugFormat(
                "Load data for route [{0}-{1}] [{2}{3}{4}]",
                route.Departure.IATA,
                route.Destination.IATA,
                loadJourneyData ? "D" : null,
                loadHistory ? "H" : null,
                loadFlights ? "F" : null);
            using (var connection = new SQLiteConnection(this._connectionString))
            {
                if (route.Id < 1)
                {
                    throw new ArgumentException("Invalid Route Id");
                }

                route.Journeys.Clear();
                string selectSql = "SELECT J.LID, J.TDEPARTURE, J.TRETURN"
                                   + (loadJourneyData
                                          ? (", D.LID DATAID, D.SCURRENCY, " + (loadHistory ? "D.TUPDATE" : "MAX(D.TUPDATE) TUPDATE")
                                             + (loadFlights ? ", D.BFLIGHT" : string.Empty))
                                          : string.Empty) + " FROM JOURNEY J" + (loadJourneyData ? ", JOURNEY_DATA D " : string.Empty) + " WHERE J.LROUTEID = @lRouteId "
                                   + (loadJourneyData ? " AND D.LJOURNEYID = J.LID " + (loadHistory ? string.Empty : " GROUP BY (D.LJOURNEYID) ") : string.Empty);

                using (var getJourneyCmd = new SQLiteCommand(selectSql, connection))
                {
                    getJourneyCmd.Parameters.AddWithValue("@lRouteId", route.Id);

                    connection.Open();
                    using (var reader = getJourneyCmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            int iId = reader.GetOrdinal("LID");
                            int iDeparture = reader.GetOrdinal("TDEPARTURE");
                            int iReturn = reader.GetOrdinal("TRETURN");
                            int iUpdate = reader.GetOrdinal("TUPDATE");
                            int iCurrency = loadJourneyData ? reader.GetOrdinal("SCURRENCY") : -1;
                            int iDataId = loadJourneyData ? reader.GetOrdinal("DATAID") : -1;
                            int iFlight = loadJourneyData ? reader.GetOrdinal("BFLIGHT") : -1;

                            while (reader.Read())
                            {
                                long journeyId = reader.GetInt64(iId);
                                Journey journey = null;
                                var allJourneys = route.Journeys;
                                foreach (var j in allJourneys)
                                {
                                    if (j.Id == journeyId)
                                    {
                                        journey = j;
                                        break;
                                    }
                                }

                                if (journey == null)
                                {
                                    var deptDate = DateTime.ParseExact(reader.GetString(iDeparture), DATE_FORMAT, CultureInfo.InvariantCulture);
                                    var retDate = DateTime.ParseExact(reader.GetString(iReturn), DATE_FORMAT, CultureInfo.InvariantCulture);
                                    journey = new Journey(journeyId, route, deptDate, retDate);
                                    route.AddJourney(journey);
                                }

                                if (loadJourneyData)
                                {
                                    var dataDate = DateTime.ParseExact(
                                        reader.GetString(iUpdate),
                                        DATETIME_FORMAT,
                                        CultureInfo.InvariantCulture,
                                        DateTimeStyles.AssumeUniversal);
                                    var newData = new JourneyData(reader.GetInt64(iDataId), reader.GetString(iCurrency), dataDate);

                                    if (loadFlights)
                                    {
                                        var dbFlights = this._formatter.FromRaw<List<Flight>>((byte[])reader[iFlight]);
                                        if (dbFlights != null && dbFlights.Count > 0)
                                        {
                                            newData.AddFlights(dbFlights);
                                        }
                                    }

                                    journey.AddData(newData);
                                }
                            }
                        }
                    }
                }
            }
        }
Esempio n. 4
0
        public void FlightDataListViewTest()
        {
            // To generate code for this test, select "Generate Code for Coded UI Test" from the shortcut menu and select one of the menu items.
            // For more information on generated code, see http://go.microsoft.com/fwlink/?LinkId=179463
            using (var frm = new Form())
            {
                using (var lv = new FlightDataListView { Dock = DockStyle.Fill })
                {
                    var route = new TravelRoute(1, AirportDataProvider.FromIATA("HEL"), AirportDataProvider.FromIATA("SGN"));
                    var j = new Journey(1, route, DateTime.Now, DateTime.Now.AddDays(7));
                    var d = new JourneyData(1, "EUR", DateTime.Now);

                    var ds = new List<Flight>(100);

                    /* TODO FIX Unit test
                    for (int i = 0; i < 100; i++)
                    {
                        var f = new Flight(
                            d,
                            Guid.NewGuid().ToString(),
                            i + 10,
                            new TravelAgency(Guid.NewGuid().ToString(), "http://google.com"),
                            new FlightLeg(DateTime.Now, DateTime.Now.AddDays(1), TimeSpan.FromHours(i + 12), 2),
                            new FlightLeg(DateTime.Now.AddDays(7), DateTime.Now.AddDays(8), TimeSpan.FromHours(i + 13), 2));
                        ds.Add(f);
                    }
                     */

                    j.AddData(d);
                    d.SetFlightLinks();
                    lv.SetDataSourceAsync(ds, true);
                    frm.Controls.Add(lv);
                    frm.ShowDialog();
                }
            }
        }
Esempio n. 5
0
 /// <summary>
 /// Add fare data for the journey
 /// </summary>
 /// <param name="data">
 /// The data.
 /// </param>
 public void AddData(JourneyData data)
 {
     if (data != null)
     {
         this.Data.Add(data);
         data.JourneyInfo = this;
     }
 }
Esempio n. 6
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);
        }