// Adds the trips that will be part of the flight request // that will be sent to the QPX Express API private static IList <SliceInput> AddTrips(FlightDetails fd) { List <SliceInput> trips = new List <SliceInput>(); string goDate = ToQpxDateFormat(fd.OutboundDate); // Outbound trip request details SliceInput goTrip = new SliceInput() { Origin = fd.OriginIata, Destination = fd.DestinationIata, Date = goDate }; trips.Add(goTrip); // Inbound trip request details // (if the flight request is not 'one way' if (fd.InboundDate.ToLower() != GatherQuestions.cStrGatherProcessOneWay.ToLower()) { string returnDate = ToQpxDateFormat(fd.InboundDate); SliceInput returnTrip = new SliceInput() { Origin = fd.DestinationIata, Destination = fd.OriginIata, Date = returnDate }; trips.Add(returnTrip); } return(trips); }
// Main submethod that executes the flight request to the QPX Express API private static string CreateExecuteRequest(FlightDetails fd, QPXExpressService service, out TripsSearchRequest x, out TripsSearchResponse result) { string failed = string.Empty; x = new TripsSearchRequest(); result = null; try { x.Request = new TripOptionsRequest(); int nump = Convert.ToInt32(fd.NumPassengers); x.Request.Passengers = new PassengerCounts { AdultCount = nump }; x.Request.Slice = AddTrips(fd); x.Request.Solutions = DetermineSolutions(fd); result = service.Trips.Search(x).Execute(); } catch { failed = GatherQuestions.cStrGatherProcessTryAgain; } return(failed); }
// Main submethod for processing the results obtained from the QPX Express API // It basically loops through the results, determines the best one (price-wise) // and creates the output that will be sent to the user private static List <string> ProcessResult(bool save, Dictionary <string, Airport> airports, TripOptionsRequest req, TripsSearchResponse result, FlightDetails fd, int?totalResults, string inb, out string guid) { int legs = 1; int numResult = 0; List <string> p = new List <string>(); string price = string.Empty; string details = string.Empty; guid = string.Empty; if (result.Trips.TripOption != null) { for (int i = 0; i <= totalResults - 1; i++) { price = "Price: " + result.Trips.TripOption[i].SaleTotal; details = GetDetails(airports, result.Trips.Data, result.Trips.TripOption[i], inb, out legs); if (IsResultOk(fd, legs - 1)) { numResult++; if (fd.Follow.ToLower() == GatherQuestions.cStrYes) { fd.Posi = i; using (TableStorage ts = new TableStorage(req, result, fd)) { if (save) { guid = ts.Save(); } } } if (numResult == Convert.ToInt32(fd.NumResults)) { break; } } else { price = string.Empty; details = string.Empty; } } if (price != string.Empty && details != string.Empty) { SetFooter(ref p, guid, price, details); } } return(p); }
// Create a unique key that identifies the flight details a user is // interested in following protected string GetKey(FlightDetails fd) { return((fd.OriginIata + "_" + fd.DestinationIata + "_" + fd.OutboundDate + "_" + fd.InboundDate + "_" + fd.Direct + "_" + fd.NumPassengers + "_" + fd.UserId).Replace(" ", "_")); }
// Main sub-method that is responsible for chedking and returning a flight price change result public string ShowUpdatedResults(Dictionary <string, Airport> airports, FlightDetails fd, out TripsSearchResponse result) { string guid = string.Empty; result = null; // Checks the current flight price for a stored flight (being followed by the user) string[] res = QpxExpressApiHelper.GetFlightPrices(false, airports, fd, out guid, out result).ToArray(); // The result is formatted and returned to the interested user return(ProcessFlight.OutputResult(res, guid)); }
// Refreshed the flight data details object protected FlightDetails GetUpdatedFlightData(FlightDetails fd) { FlightDetails ffd = new FlightDetails() { OriginIata = fd.OriginIata, DestinationIata = fd.DestinationIata, OutboundDate = fd.OutboundDate, InboundDate = fd.InboundDate, NumPassengers = fd.NumPassengers, NumResults = fd.NumResults }; return(ffd); }
public ProcessFlight() { FlightDetails = new FlightDetails() { OriginIata = string.Empty, DestinationIata = string.Empty, OutboundDate = string.Empty, InboundDate = string.Empty, NumPassengers = string.Empty, NumResults = string.Empty }; Airports = GetAirports(); }
public virtual void Dispose(bool disposing) { if (!disposed) { if (disposing) { // Dispose any managed, IDisposable resources FlightDetails = null; } // Dispose of undisposed unmanaged resources } disposed = true; }
// Method that simply compares if the price of the stored flight // is different than the current price for that same flight protected bool PriceHasChanged(TravelEntity entity, TripsSearchResponse result, CloudStorageAccount storageAccount) { bool res = false; FlightDetails fd = JsonConvert.DeserializeObject <FlightDetails>(GetFromBlob(entity.FlightDetails, storageAccount)); TripsSearchResponse travelRes = JsonConvert. DeserializeObject <TripsSearchResponse>(GetFromBlob(entity.TravelRes, storageAccount)); if (travelRes.Trips.TripOption[fd.Posi].SaleTotal != result.Trips.TripOption[fd.Posi].SaleTotal) { res = true; } return(res); }
// Determines if a result from the QPX Express API is suitable to be displayed // based on the criteria selected by the user - if direct flights have been chosen // or with multiple stops private static bool IsResultOk(FlightDetails fd, int legs) { bool res = false; if (fd.Direct.ToLower() == "yes") { if (fd.InboundDate.ToLower() == GatherQuestions.cStrGatherProcessOneWay.ToLower() && legs == 1) { res = true; } if (fd.InboundDate.ToLower() != GatherQuestions.cStrGatherProcessOneWay.ToLower() && legs == 2) { res = true; } } else { res = true; } return(res); }
public TableStorage(TripOptionsRequest req, TripsSearchResponse res, FlightDetails fd) { travelReq = req; travelRes = res; flightDetails = fd; }
public TableStorage() { travelReq = null; travelRes = null; flightDetails = null; }
// This is the main method responsible for getting flight data // It calls the QPX Express API and establishes authentication // It is called by FlightData.cs and also by the Timer that checks // if a price has changed public static List <string> GetFlightPrices(bool save, Dictionary <string, Airport> airports, FlightDetails fd, out string guid, out TripsSearchResponse result) { List <string> p = new List <string>(); guid = string.Empty; // Authentication with the QPX Express API using (QPXExpressService service = new QPXExpressService(new BaseClientService.Initializer() { ApiKey = CloudConfigurationManager.GetSetting(StrConsts.cStrQpxApiKey), ApplicationName = CloudConfigurationManager.GetSetting(StrConsts.cStrBotId) })) { TripsSearchRequest x = null; result = null; // Executes the flight / trip request using the QPX Express API string failed = CreateExecuteRequest(fd, service, out x, out result); if (result != null) { // Process the results obtained from the QPX Express API p = ProcessResult(save, airports, x.Request, result, fd, x.Request.Solutions, fd.InboundDate, out guid); } else { p.Add(failed + StrConsts._NewLine + StrConsts._NewLine + GatherErrors.cStrCouldFetchData); } } return(p); }
// Checks what number of results to fetch from the QPX Express API private static int?DetermineSolutions(FlightDetails fd) { return((DirectSelected(fd)) ? StrConsts.cNumSolutions : Convert.ToInt32(fd.NumResults)); }
// Checks if the request will be for direct flights or not private static bool DirectSelected(FlightDetails fd) { return((fd.Direct.ToLower() == GatherQuestions.cStrYes) ? true : false); }
// Main method for checking if any of the stored flights (being followed by users) have changed their prices public async Task <bool> CheckForPriceUpdates(Dictionary <string, Airport> airports, FlightDetails fd, Activity activity, ConnectorClient connector, string guid) { bool changed = false; try { // Connects to Azure Table Storage in order to retrieve th details of // flights being watched by users CloudStorageAccount storageAccount = CloudStorageAccount.Parse( CloudConfigurationManager.GetSetting(StrConsts.cStrStorageConnectionStr)); CloudTableClient tableClient = storageAccount.CreateCloudTableClient(); CloudTable table = tableClient.GetTableReference( CloudConfigurationManager.GetSetting(StrConsts.cStrBotId)); TableQuery <TravelEntity> query = new TableQuery <TravelEntity>(). Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.NotEqual, string.Empty)); // Gets all the flights being watched IEnumerable <TravelEntity> results = table.ExecuteQuery(query); // Let's check if any of the flights stored have a change in price foreach (TravelEntity entity in results) { TripsSearchResponse result = null; TripOptionsRequest req = null; // Get the details of a stored flight (being followed) fd = GetStoredFlightData(entity, storageAccount, out req); // If the stored flight was submitted by the user currently // interacting with our bot - very important :) if (fd.UserId.ToLower() == activity.From.Id.ToLower()) { // Query the QPX Express API to see if the current price // of the flight stored differs string res = ShowUpdatedResults(airports, fd, out result); // If the flight is still relevant (has not expired) if (res != string.Empty) { // If indeed the current price differs from when it was // originally requested by the user if (PriceHasChanged(entity, result, storageAccount)) { changed = true; // Save the new flight price on Azure Storage Table using (TableStorage ts = new TableStorage(req, result, fd)) guid = ts.Save(); changed = true; // Create the response with the current flight price that will be // sent back to the user Activity reply = activity.CreateReply(GatherQuestions.cStrPriceChange + StrConsts._NewLine + StrConsts._NewLine + res + StrConsts._NewLine + StrConsts._NewLine + GatherQuestions.cStrGatherRequestProcessed + StrConsts._NewLine + StrConsts._NewLine + GatherQuestions.cStrUnFollow + guid); await connector.Conversations.ReplyToActivityAsync(reply); } } else { // The flight is no longer relevant // so it should be removed from Azure Storage RemoveEntity(GetKey(fd)); } } } } catch { } // If there has been a price change // return true return(changed); }