00001
00002 #include <cassert>
00003 #include <sstream>
00004 #include <fstream>
00005 #include <string>
00006
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
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
00019 #include <airsched/AIRSCHED_Service.hpp>
00020 #include <airsched/batches/BookingRequestParser.hpp>
00021 #include <airsched/config/airsched-paths.hpp>
00022
00023
00024 typedef std::vector<std::string> WordList_T;
00025
00026
00027
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
00076
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
00094 ioIsBuiltin = K_AIRSCHED_DEFAULT_BUILT_IN_INPUT;
00095
00096
00097 ioReadBookingRequestFromCmdLine = K_AIRSCHED_DEFAULT_BOOKING_REQUEST_MODE;
00098
00099
00100 WordList_T lWordList;
00101
00102
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
00110
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
00129
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
00191
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
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
00237 tokenizer::iterator tok_iter = tokens.begin();
00238 assert (tok_iter != tokens.end());
00239 const stdair::AirportCode_T iOrigin (*tok_iter);
00240
00241
00242 ++tok_iter; assert (tok_iter != tokens.end());
00243 const stdair::AirportCode_T iDestination (*tok_iter);
00244
00245
00246 ++tok_iter; assert (tok_iter != tokens.end());
00247 const stdair::AirportCode_T iPOS (*tok_iter);
00248
00249
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
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
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
00278 const stdair::DateTime_T iRequestDateTime (iRequestDate, iRequestTime);
00279
00280
00281 ++tok_iter; assert (tok_iter != tokens.end());
00282 const stdair::CabinCode_T iPreferredCabin (*tok_iter);
00283
00284
00285 ++tok_iter; assert (tok_iter != tokens.end());
00286 const stdair::NbOfSeats_T iPartySize = 1;
00287
00288
00289 ++tok_iter; assert (tok_iter != tokens.end());
00290 const stdair::ChannelLabel_T iChannel (*tok_iter);
00291
00292
00293 ++tok_iter; assert (tok_iter != tokens.end());
00294 const stdair::TripType_T iTripType (*tok_iter);
00295
00296
00297 ++tok_iter; assert (tok_iter != tokens.end());
00298 const stdair::DayDuration_T iStayDuration = 5;
00299
00300
00301 ++tok_iter; assert (tok_iter != tokens.end());
00302 const stdair::FrequentFlyer_T iFrequentFlyerType ("NONE");
00303
00304
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
00316 ++tok_iter; assert (tok_iter != tokens.end());
00317 const stdair::WTP_T iWTP = 2000.0;
00318
00319
00320 ++tok_iter; assert (tok_iter != tokens.end());
00321 const stdair::PriceValue_T iValueOfTime = 20.0;
00322
00323
00324 return stdair::BookingRequestStruct (iOrigin,
00325 iDestination, iPOS,
00326 iDepartureDate, iRequestDateTime,
00327 iPreferredCabin, iPartySize,
00328 iChannel, iTripType, iStayDuration,
00329 iFrequentFlyerType,
00330 iPreferredDepartureTime, iWTP,
00331 iValueOfTime);
00332 }
00333
00334
00335 int main (int argc, char* argv[]) {
00336
00337
00338
00339 bool isBuiltin;
00340
00341
00342 bool readBookingRequestFromCmdLine;
00343
00344
00345 stdair::Filename_T lInputFilename;
00346
00347
00348 stdair::Filename_T lLogFilename;
00349
00350
00351 std::string lBookingRequestString;
00352
00353
00354 const int lOptionParserStatus =
00355 readConfiguration (argc, argv, isBuiltin, readBookingRequestFromCmdLine,
00356 lInputFilename, lLogFilename, lBookingRequestString);
00357
00358 if (lOptionParserStatus == K_AIRSCHED_EARLY_RETURN_STATUS) {
00359 return 0;
00360 }
00361
00362
00363 std::ofstream logOutputFile;
00364
00365 logOutputFile.open (lLogFilename.c_str());
00366 logOutputFile.clear();
00367
00368
00369 const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
00370 AIRSCHED::AIRSCHED_Service airschedService (lLogParams);
00371
00372
00373 if (isBuiltin == true) {
00374
00375
00376 airschedService.buildSampleBom();
00377
00378 } else {
00379
00380 airschedService.parseAndLoad (lInputFilename);
00381 }
00382
00383
00384 if (readBookingRequestFromCmdLine == false) {
00385 lBookingRequestString = K_AIRSCHED_DEFAULT_BOOKING_REQUEST;
00386 }
00387
00388
00389 STDAIR_LOG_DEBUG("Booking request string: '" << lBookingRequestString << "'");
00390
00391
00392 const stdair::BookingRequestStruct& lBookingRequest =
00393 parseBookingRequest (lBookingRequestString);
00394
00395
00396 stdair::TravelSolutionList_T lTravelSolutionList;
00397 airschedService.buildSegmentPathList (lTravelSolutionList, lBookingRequest);
00398
00399
00400 STDAIR_LOG_DEBUG ("Parsed booking request: " << lBookingRequest);
00401
00402
00403 std::ostringstream oStream;
00404 stdair::BomDisplay::csvDisplay (oStream, lTravelSolutionList);
00405 STDAIR_LOG_DEBUG (oStream.str());
00406
00407
00408 logOutputFile.close();
00409
00410 return 0;
00411 }