$treeview $search $mathjax
00001 // STL 00002 #include <cassert> 00003 #include <sstream> 00004 #include <fstream> 00005 #include <string> 00006 // Boost (Extended STL) 00007 #include <boost/date_time/posix_time/posix_time.hpp> 00008 #include <boost/date_time/gregorian/gregorian.hpp> 00009 #include <boost/program_options.hpp> 00010 #include <boost/tokenizer.hpp> 00011 #include <boost/lexical_cast.hpp> 00012 // StdAir 00013 #include <stdair/STDAIR_Service.hpp> 00014 #include <stdair/bom/BomDisplay.hpp> 00015 #include <stdair/bom/BookingRequestStruct.hpp> 00016 #include <stdair/bom/TravelSolutionStruct.hpp> 00017 #include <stdair/service/Logger.hpp> 00018 // AirSched 00019 #include <airsched/AIRSCHED_Service.hpp> 00020 #include <airsched/batches/BookingRequestParser.hpp> 00021 #include <airsched/config/airsched-paths.hpp> 00022 00023 // //////// Type definitions /////// 00024 typedef std::vector<std::string> WordList_T; 00025 00026 00027 // //////// Constants ////// 00031 const std::string K_AIRSCHED_DEFAULT_LOG_FILENAME ("airsched.log"); 00032 00036 const std::string K_AIRSCHED_DEFAULT_INPUT_FILENAME (STDAIR_SAMPLE_DIR 00037 "/schedule03.csv"); 00038 00044 const bool K_AIRSCHED_DEFAULT_BUILT_IN_INPUT = false; 00045 00050 const bool K_AIRSCHED_DEFAULT_BOOKING_REQUEST_MODE = false; 00051 00056 const std::string K_AIRSCHED_DEFAULT_BOOKING_REQUEST ("NCE BKK NCE 2007-04-21 2007-03-21 08:32:00 C 1 DF RO 5 NONE 10:00:00 2000.0 20.0"); 00057 00058 // ////////////////////////////////////////////////////////////////////// 00059 std::string createStringFromWordList (const WordList_T& iWordList) { 00060 std::ostringstream oStr; 00061 00062 unsigned short idx = iWordList.size(); 00063 for (WordList_T::const_iterator itWord = iWordList.begin(); 00064 itWord != iWordList.end(); ++itWord, --idx) { 00065 const std::string& lWord = *itWord; 00066 oStr << lWord; 00067 if (idx > 1) { 00068 oStr << " "; 00069 } 00070 } 00071 00072 return oStr.str(); 00073 } 00074 00075 // ///////// Parsing of Options & Configuration ///////// 00076 // A helper function to simplify the main part. 00077 template<class T> std::ostream& operator<< (std::ostream& os, 00078 const std::vector<T>& v) { 00079 std::copy (v.begin(), v.end(), std::ostream_iterator<T> (std::cout, " ")); 00080 return os; 00081 } 00082 00084 const int K_AIRSCHED_EARLY_RETURN_STATUS = 99; 00085 00087 int readConfiguration (int argc, char* argv[], 00088 bool& ioIsBuiltin, bool& ioReadBookingRequestFromCmdLine, 00089 stdair::Filename_T& ioInputFilename, 00090 std::string& ioLogFilename, 00091 std::string& ioBookingRequestString) { 00092 00093 // Default for the built-in input 00094 ioIsBuiltin = K_AIRSCHED_DEFAULT_BUILT_IN_INPUT; 00095 00096 // Default for the booking request mode (whether it is read from command-line) 00097 ioReadBookingRequestFromCmdLine = K_AIRSCHED_DEFAULT_BOOKING_REQUEST_MODE; 00098 00099 // 00100 WordList_T lWordList; 00101 00102 // Declare a group of options that will be allowed only on command line 00103 boost::program_options::options_description generic ("Generic options"); 00104 generic.add_options() 00105 ("prefix", "print installation prefix") 00106 ("version,v", "print version string") 00107 ("help,h", "produce help message"); 00108 00109 // Declare a group of options that will be allowed both on command 00110 // line and in config file 00111 boost::program_options::options_description config ("Configuration"); 00112 config.add_options() 00113 ("builtin,b", 00114 "The sample BOM tree can be either built-in or parsed from input files. In that latter case, the -i/--input option must be specified as well") 00115 ("input,i", 00116 boost::program_options::value< std::string >(&ioInputFilename)->default_value(K_AIRSCHED_DEFAULT_INPUT_FILENAME), 00117 "(CSV) input file specifying the schedule (flight-period) entries") 00118 ("log,l", 00119 boost::program_options::value< std::string >(&ioLogFilename)->default_value(K_AIRSCHED_DEFAULT_LOG_FILENAME), 00120 "Filename for the logs") 00121 ("read_booking_request,r", 00122 "Indicates that a booking request is given as a command-line option. That latter must then be given with the -b/--bkg_req option") 00123 ("bkg_req,q", 00124 boost::program_options::value< WordList_T >(&lWordList)->multitoken(), 00125 "Booking request word list (e.g. 'NCE BKK NCE 2007-04-21 2007-04-21 10:00:00 C 1 DF RO 5 NONE 10:0:0 2000.0 20.0'), which should be located at the end of the command line (otherwise, the other options would be interpreted as part of that booking request word list)") 00126 ; 00127 00128 // Hidden options, will be allowed both on command line and 00129 // in config file, but will not be shown to the user. 00130 boost::program_options::options_description hidden ("Hidden options"); 00131 hidden.add_options() 00132 ("copyright", 00133 boost::program_options::value< std::vector<std::string> >(), 00134 "Show the copyright (license)"); 00135 00136 boost::program_options::options_description cmdline_options; 00137 cmdline_options.add(generic).add(config).add(hidden); 00138 00139 boost::program_options::options_description config_file_options; 00140 config_file_options.add(config).add(hidden); 00141 00142 boost::program_options::options_description visible ("Allowed options"); 00143 visible.add(generic).add(config); 00144 00145 boost::program_options::positional_options_description p; 00146 p.add ("copyright", -1); 00147 00148 boost::program_options::variables_map vm; 00149 boost::program_options:: 00150 store (boost::program_options::command_line_parser (argc, argv). 00151 options (cmdline_options).positional(p).run(), vm); 00152 00153 std::ifstream ifs ("airsched.cfg"); 00154 boost::program_options::store (parse_config_file (ifs, config_file_options), 00155 vm); 00156 boost::program_options::notify (vm); 00157 00158 if (vm.count ("help")) { 00159 std::cout << visible << std::endl; 00160 return K_AIRSCHED_EARLY_RETURN_STATUS; 00161 } 00162 00163 if (vm.count ("version")) { 00164 std::cout << PACKAGE_NAME << ", version " << PACKAGE_VERSION << std::endl; 00165 return K_AIRSCHED_EARLY_RETURN_STATUS; 00166 } 00167 00168 if (vm.count ("prefix")) { 00169 std::cout << "Installation prefix: " << PREFIXDIR << std::endl; 00170 return K_AIRSCHED_EARLY_RETURN_STATUS; 00171 } 00172 00173 if (vm.count ("builtin")) { 00174 ioIsBuiltin = true; 00175 } 00176 const std::string isBuiltinStr = (ioIsBuiltin == true)?"yes":"no"; 00177 std::cout << "The BOM should be built-in? " << isBuiltinStr << std::endl; 00178 00179 // 00180 std::ostringstream oErrorMessageStr; 00181 oErrorMessageStr << "Either the -b/--builtin option, or the -i/--input option" 00182 << " must be specified"; 00183 00184 if (ioIsBuiltin == false) { 00185 if (vm.count ("input")) { 00186 ioInputFilename = vm["input"].as< std::string >(); 00187 std::cout << "Input filename is: " << ioInputFilename << std::endl; 00188 00189 } else { 00190 // The built-in option is not selected. However, no schedule input file 00191 // is specified 00192 std::cerr << oErrorMessageStr.str() << std::endl; 00193 } 00194 } 00195 00196 // 00197 if (vm.count ("read_booking_request")) { 00198 ioReadBookingRequestFromCmdLine = true; 00199 } 00200 const std::string readBookingRequestFromCmdLineStr = 00201 (ioReadBookingRequestFromCmdLine == true)?"yes":"no"; 00202 std::cout << "A booking request is to be given as command-line option? " 00203 << readBookingRequestFromCmdLineStr << std::endl; 00204 00205 if (ioReadBookingRequestFromCmdLine == true) { 00206 00207 if (lWordList.empty() == true) { 00208 std::cerr << "When the --read_booking_request/-r option is given, " 00209 << "a query must also be provided (with the --bkg_req/-b " 00210 << "option at the end of the command-line)" << std::endl; 00211 return K_AIRSCHED_EARLY_RETURN_STATUS; 00212 } 00213 00214 // Rebuild the booking request query string 00215 ioBookingRequestString = createStringFromWordList (lWordList); 00216 std::cout << "The booking request string is: " << ioBookingRequestString 00217 << std::endl; 00218 } 00219 00220 if (vm.count ("log")) { 00221 ioLogFilename = vm["log"].as< std::string >(); 00222 std::cout << "Log filename is: " << ioLogFilename << std::endl; 00223 } 00224 00225 return 0; 00226 } 00227 00228 // ////////////////////////////////////////////////////////////// 00229 stdair::BookingRequestStruct 00230 parseBookingRequest (const std::string& iRequestOption) { 00231 typedef boost::tokenizer<boost::char_separator<char> > tokenizer; 00232 boost::char_separator<char> sep(" -:"); 00233 00234 tokenizer tokens (iRequestOption, sep); 00235 00236 // Origin (e.g., "NCE") 00237 tokenizer::iterator tok_iter = tokens.begin(); 00238 assert (tok_iter != tokens.end()); 00239 const stdair::AirportCode_T iOrigin (*tok_iter); 00240 00241 // Destination (e.g., "BKK") 00242 ++tok_iter; assert (tok_iter != tokens.end()); 00243 const stdair::AirportCode_T iDestination (*tok_iter); 00244 00245 // POS (e.g., "NCE") 00246 ++tok_iter; assert (tok_iter != tokens.end()); 00247 const stdair::AirportCode_T iPOS (*tok_iter); 00248 00249 // Preferred departure date (e.g., "2007-04-21") 00250 ++tok_iter; assert (tok_iter != tokens.end()); 00251 const short lDepDateYear = boost::lexical_cast<short> (*tok_iter); 00252 ++tok_iter; assert (tok_iter != tokens.end()); 00253 const short lDepDateMonth = boost::lexical_cast<short> (*tok_iter); 00254 ++tok_iter; assert (tok_iter != tokens.end()); 00255 const short lDepDateDay = boost::lexical_cast<short> (*tok_iter); 00256 const stdair::Date_T iDepartureDate(lDepDateYear, lDepDateMonth, lDepDateDay); 00257 00258 // Request date (e.g., "2007-03-21") 00259 ++tok_iter; assert (tok_iter != tokens.end()); 00260 const short lReqDateYear = boost::lexical_cast<short> (*tok_iter); 00261 ++tok_iter; assert (tok_iter != tokens.end()); 00262 const short lReqDateMonth = boost::lexical_cast<short> (*tok_iter); 00263 ++tok_iter; assert (tok_iter != tokens.end()); 00264 const short lReqDateDay = boost::lexical_cast<short> (*tok_iter); 00265 const stdair::Date_T iRequestDate (lReqDateYear, lReqDateMonth, lReqDateDay); 00266 00267 // Request time (e.g., "08:34:23") 00268 ++tok_iter; assert (tok_iter != tokens.end()); 00269 const short lReqTimeHours = boost::lexical_cast<short> (*tok_iter); 00270 ++tok_iter; assert (tok_iter != tokens.end()); 00271 const short lReqTimeMinutes = boost::lexical_cast<short> (*tok_iter); 00272 ++tok_iter; assert (tok_iter != tokens.end()); 00273 const short lReqTimeSeconds = boost::lexical_cast<short> (*tok_iter); 00274 const stdair::Duration_T iRequestTime (lReqTimeHours, lReqTimeMinutes, 00275 lReqTimeSeconds); 00276 00277 // Request date-time (aggregation of the two items above) 00278 const stdair::DateTime_T iRequestDateTime (iRequestDate, iRequestTime); 00279 00280 // Preferred cabin (e.g., "C") 00281 ++tok_iter; assert (tok_iter != tokens.end()); 00282 const stdair::CabinCode_T iPreferredCabin (*tok_iter); 00283 00284 // Party size (e.g., 1) 00285 ++tok_iter; assert (tok_iter != tokens.end()); 00286 const stdair::NbOfSeats_T iPartySize = 1; 00287 00288 // Channel (e.g., "DF") 00289 ++tok_iter; assert (tok_iter != tokens.end()); 00290 const stdair::ChannelLabel_T iChannel (*tok_iter); 00291 00292 // Trip type (e.g., "RO") 00293 ++tok_iter; assert (tok_iter != tokens.end()); 00294 const stdair::TripType_T iTripType (*tok_iter); 00295 00296 // Stay duration (e.g., 5) 00297 ++tok_iter; assert (tok_iter != tokens.end()); 00298 const stdair::DayDuration_T iStayDuration = 5; 00299 00300 // Frequent flyer (e.g., "NONE") 00301 ++tok_iter; assert (tok_iter != tokens.end()); 00302 const stdair::FrequentFlyer_T iFrequentFlyerType ("NONE"); 00303 00304 // Preferred departure time (e.g., "10:00:00") 00305 ++tok_iter; assert (tok_iter != tokens.end()); 00306 const short lPrefTimeHours = boost::lexical_cast<short> (*tok_iter); 00307 ++tok_iter; assert (tok_iter != tokens.end()); 00308 const short lPrefTimeMinutes = boost::lexical_cast<short> (*tok_iter); 00309 ++tok_iter; assert (tok_iter != tokens.end()); 00310 const short lPrefTimeSeconds = boost::lexical_cast<short> (*tok_iter); 00311 const stdair::Duration_T iPreferredDepartureTime (lPrefTimeHours, 00312 lPrefTimeMinutes, 00313 lPrefTimeSeconds); 00314 00315 // Willingness-to-pay (e.g., 2000.0) 00316 ++tok_iter; assert (tok_iter != tokens.end()); 00317 const stdair::WTP_T iWTP = 2000.0; 00318 00319 // Value of time (e.g., 20.0) 00320 ++tok_iter; assert (tok_iter != tokens.end()); 00321 const stdair::PriceValue_T iValueOfTime = 20.0; 00322 00323 // Change fee acceptation (e.g., true) 00324 //++tok_iter; assert (tok_iter != tokens.end()); 00325 const stdair::ChangeFees_T iChangeFees = true; 00326 const stdair::Disutility_T iChangeFeeDisutility = 50; 00327 00328 // Non refundable acceptation (e.g., true) 00329 //++tok_iter; assert (tok_iter != tokens.end()); 00330 const stdair::NonRefundable_T iNonRefundable = true; 00331 const stdair::Disutility_T iNonRefundableDisutility = 50; 00332 00333 // Build and return the booking request structure 00334 return stdair::BookingRequestStruct (iOrigin, 00335 iDestination, iPOS, 00336 iDepartureDate, iRequestDateTime, 00337 iPreferredCabin, iPartySize, 00338 iChannel, iTripType, iStayDuration, 00339 iFrequentFlyerType, 00340 iPreferredDepartureTime, iWTP, 00341 iValueOfTime, iChangeFees, 00342 iChangeFeeDisutility, iNonRefundable, 00343 iNonRefundableDisutility); 00344 } 00345 00346 // ///////// M A I N //////////// 00347 int main (int argc, char* argv[]) { 00348 00349 // State whether the BOM tree should be built-in or parsed from an 00350 // input file 00351 bool isBuiltin; 00352 00353 // A booking request should be given as command-line option 00354 bool readBookingRequestFromCmdLine; 00355 00356 // Input file name 00357 stdair::Filename_T lInputFilename; 00358 00359 // Output log File 00360 stdair::Filename_T lLogFilename; 00361 00362 // Booking request string 00363 std::string lBookingRequestString; 00364 00365 // Call the command-line option parser 00366 const int lOptionParserStatus = 00367 readConfiguration (argc, argv, isBuiltin, readBookingRequestFromCmdLine, 00368 lInputFilename, lLogFilename, lBookingRequestString); 00369 00370 if (lOptionParserStatus == K_AIRSCHED_EARLY_RETURN_STATUS) { 00371 return 0; 00372 } 00373 00374 // Set the log parameters 00375 std::ofstream logOutputFile; 00376 // Open and clean the log outputfile 00377 logOutputFile.open (lLogFilename.c_str()); 00378 logOutputFile.clear(); 00379 00380 // Initialise the AirSched service object 00381 const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile); 00382 AIRSCHED::AIRSCHED_Service airschedService (lLogParams); 00383 00384 // Check wether or not (CSV) input files should be read 00385 if (isBuiltin == true) { 00386 00387 // Build the sample BOM tree 00388 airschedService.buildSampleBom(); 00389 00390 } else { 00391 // Build the BOM tree from parsing input files 00392 const stdair::ScheduleFilePath lScheduleFilePath (lInputFilename); 00393 airschedService.parseAndLoad (lScheduleFilePath); 00394 } 00395 00396 // Check wether or not a booking request is given as a command-line option 00397 if (readBookingRequestFromCmdLine == false) { 00398 lBookingRequestString = K_AIRSCHED_DEFAULT_BOOKING_REQUEST; 00399 } 00400 00401 // DEBUG 00402 STDAIR_LOG_DEBUG("Booking request string: '" << lBookingRequestString << "'"); 00403 00404 // Create a booking request object 00405 const stdair::BookingRequestStruct& lBookingRequest = 00406 parseBookingRequest (lBookingRequestString); 00407 00408 // 00409 stdair::TravelSolutionList_T lTravelSolutionList; 00410 airschedService.buildSegmentPathList (lTravelSolutionList, lBookingRequest); 00411 00412 // DEBUG 00413 STDAIR_LOG_DEBUG ("Parsed booking request: " << lBookingRequest); 00414 00415 // DEBUG 00416 std::ostringstream oStream; 00417 stdair::BomDisplay::csvDisplay (oStream, lTravelSolutionList); 00418 STDAIR_LOG_DEBUG (oStream.str()); 00419 00420 // Close the Log outputFile 00421 logOutputFile.close(); 00422 00423 return 0; 00424 }