12 #include <boost/program_options.hpp>
13 #include <boost/tokenizer.hpp>
14 #include <boost/regex.hpp>
15 #include <boost/swap.hpp>
16 #include <boost/algorithm/string/case_conv.hpp>
18 #include <stdair/basic/BasLogParams.hpp>
19 #include <stdair/basic/BasDBParams.hpp>
20 #include <stdair/service/Logger.hpp>
21 #include <stdair/stdair_json.hpp>
23 #include <stdair/ui/cmdline/SReadline.hpp>
26 #include <airinv/config/airinv-paths.hpp>
32 const std::string K_AIRINV_DEFAULT_LOG_FILENAME (
"airinv.log");
57 const std::string K_AIRINV_DEFAULT_FF_DISUTILITY_INPUT_FILENAME (
STDAIR_SAMPLE_DIR
69 const bool K_AIRINV_DEFAULT_BUILT_IN_INPUT =
false;
75 const bool K_AIRINV_DEFAULT_FOR_SCHEDULE =
false;
80 const int K_AIRINV_EARLY_RETURN_STATUS = 99;
86 typedef std::vector<std::string> TokenList_T;
108 template<
class T> std::ostream&
operator<< (std::ostream& os,
109 const std::vector<T>& v) {
110 std::copy (v.begin(), v.end(), std::ostream_iterator<T> (std::cout,
" "));
117 int readConfiguration (
int argc,
char* argv[],
118 bool& ioIsBuiltin,
bool& ioIsForSchedule,
119 stdair::Filename_T& ioInventoryFilename,
120 stdair::Filename_T& ioScheduleInputFilename,
121 stdair::Filename_T& ioODInputFilename,
122 stdair::Filename_T& ioFRAT5Filename,
123 stdair::Filename_T& ioFFDisutilityFilename,
124 stdair::Filename_T& ioYieldInputFilename,
125 std::string& ioLogFilename) {
127 ioIsBuiltin = K_AIRINV_DEFAULT_BUILT_IN_INPUT;
130 ioIsForSchedule = K_AIRINV_DEFAULT_FOR_SCHEDULE;
133 boost::program_options::options_description
generic (
"Generic options");
134 generic.add_options()
135 (
"prefix",
"print installation prefix")
136 (
"version,v",
"print version string")
137 (
"help,h",
"produce help message");
142 boost::program_options::options_description config (
"Configuration");
145 "The sample BOM tree can be either built-in or parsed from an input file. That latter must then be given with the -i/--inventory or -s/--schedule option")
147 "The BOM tree should be built from a schedule file (instead of from an inventory dump)")
149 boost::program_options::value< std::string >(&ioInventoryFilename)->default_value(K_AIRINV_DEFAULT_INVENTORY_FILENAME),
150 "(CSV) input file for the inventory")
152 boost::program_options::value< std::string >(&ioScheduleInputFilename)->default_value(K_AIRINV_DEFAULT_SCHEDULE_FILENAME),
153 "(CSV) input file for the schedule")
155 boost::program_options::value< std::string >(&ioODInputFilename)->default_value(K_AIRINV_DEFAULT_OND_FILENAME),
156 "(CSV) input file for the O&D")
158 boost::program_options::value< std::string >(&ioFRAT5Filename)->default_value(K_AIRINV_DEFAULT_FRAT5_INPUT_FILENAME),
159 "(CSV) input file for the FRAT5 Curve")
161 boost::program_options::value< std::string >(&ioFFDisutilityFilename)->default_value(K_AIRINV_DEFAULT_FF_DISUTILITY_INPUT_FILENAME),
162 "(CSV) input file for the FF disutility Curve")
164 boost::program_options::value< std::string >(&ioYieldInputFilename)->default_value(K_AIRINV_DEFAULT_YIELD_FILENAME),
165 "(CSV) input file for the yield")
167 boost::program_options::value< std::string >(&ioLogFilename)->default_value(K_AIRINV_DEFAULT_LOG_FILENAME),
168 "Filename for the logs")
173 boost::program_options::options_description hidden (
"Hidden options");
176 boost::program_options::value< std::vector<std::string> >(),
177 "Show the copyright (license)");
179 boost::program_options::options_description cmdline_options;
180 cmdline_options.add(
generic).add(config).add(hidden);
182 boost::program_options::options_description config_file_options;
183 config_file_options.add(config).add(hidden);
184 boost::program_options::options_description visible (
"Allowed options");
185 visible.add(
generic).add(config);
187 boost::program_options::positional_options_description p;
188 p.add (
"copyright", -1);
190 boost::program_options::variables_map vm;
191 boost::program_options::
192 store (boost::program_options::command_line_parser (argc, argv).
193 options (cmdline_options).positional(p).run(), vm);
195 std::ifstream ifs (
"airinv.cfg");
196 boost::program_options::store (parse_config_file (ifs, config_file_options),
198 boost::program_options::notify (vm);
200 if (vm.count (
"help")) {
201 std::cout << visible << std::endl;
202 return K_AIRINV_EARLY_RETURN_STATUS;
205 if (vm.count (
"version")) {
207 return K_AIRINV_EARLY_RETURN_STATUS;
210 if (vm.count (
"prefix")) {
211 std::cout <<
"Installation prefix: " <<
PREFIXDIR << std::endl;
212 return K_AIRINV_EARLY_RETURN_STATUS;
215 if (vm.count (
"builtin")) {
218 const std::string isBuiltinStr = (ioIsBuiltin ==
true)?
"yes":
"no";
219 std::cout <<
"The BOM should be built-in? " << isBuiltinStr << std::endl;
221 if (vm.count (
"for_schedule")) {
222 ioIsForSchedule =
true;
224 const std::string isForScheduleStr = (ioIsForSchedule ==
true)?
"yes":
"no";
225 std::cout <<
"The BOM should be built from schedule? " << isForScheduleStr
228 if (ioIsBuiltin ==
false) {
230 if (ioIsForSchedule ==
false) {
232 if (vm.count (
"inventory")) {
233 ioInventoryFilename = vm[
"inventory"].as< std::string >();
234 std::cout <<
"Input inventory filename is: " << ioInventoryFilename
240 std::cerr <<
"Either one among the -b/--builtin, -i/--inventory or "
241 <<
" -f/--for_schedule and -s/--schedule options "
242 <<
"must be specified" << std::endl;
247 if (vm.count (
"schedule")) {
248 ioScheduleInputFilename = vm[
"schedule"].as< std::string >();
249 std::cout <<
"Input schedule filename is: " << ioScheduleInputFilename
255 std::cerr <<
"Either one among the -b/--builtin, -i/--inventory or "
256 <<
" -f/--for_schedule and -s/--schedule options "
257 <<
"must be specified" << std::endl;
260 if (vm.count (
"ond")) {
261 ioODInputFilename = vm[
"ond"].as< std::string >();
262 std::cout <<
"Input O&D filename is: " << ioODInputFilename << std::endl;
265 if (vm.count (
"frat5")) {
266 ioFRAT5Filename = vm[
"frat5"].as< std::string >();
267 std::cout <<
"FRAT5 input filename is: " << ioFRAT5Filename << std::endl;
271 if (vm.count (
"ff_disutility")) {
272 ioFFDisutilityFilename = vm[
"ff_disutility"].as< std::string >();
273 std::cout <<
"FF disutility input filename is: "
274 << ioFFDisutilityFilename << std::endl;
278 if (vm.count (
"yield")) {
279 ioYieldInputFilename = vm[
"yield"].as< std::string >();
280 std::cout <<
"Input yield filename is: " << ioYieldInputFilename << std::endl;
285 if (vm.count (
"log")) {
286 ioLogFilename = vm[
"log"].as< std::string >();
287 std::cout <<
"Log filename is: " << ioLogFilename << std::endl;
294 void initReadline (swift::SReadline& ioInputReader) {
297 std::vector<std::string> Completers;
302 Completers.push_back (
"help");
303 Completers.push_back (
"list %airline_code %flight_number");
304 Completers.push_back (
"select %airline_code %flight_number %flight_date");
305 Completers.push_back (
"display");
306 Completers.push_back (
"sell %booking_class %party_size %origin %destination");
307 Completers.push_back (
"quit");
308 Completers.push_back (
"json_list");
309 Completers.push_back (
"json_display");
314 ioInputReader.RegisterCompletions (Completers);
318 Command_T::Type_T extractCommand (TokenList_T& ioTokenList) {
319 Command_T::Type_T oCommandType = Command_T::LAST_VALUE;
322 if (ioTokenList.empty() ==
false) {
323 TokenList_T::iterator itTok = ioTokenList.begin();
324 std::string lCommand (*itTok);
325 boost::algorithm::to_lower (lCommand);
327 if (lCommand ==
"help") {
328 oCommandType = Command_T::HELP;
330 }
else if (lCommand ==
"list") {
331 oCommandType = Command_T::LIST;
333 }
else if (lCommand ==
"display") {
334 oCommandType = Command_T::DISPLAY;
336 }
else if (lCommand ==
"select") {
337 oCommandType = Command_T::SELECT;
339 }
else if (lCommand ==
"sell") {
340 oCommandType = Command_T::SELL;
342 }
else if (lCommand ==
"json_list") {
343 oCommandType = Command_T::JSON_LIST;
345 }
else if (lCommand ==
"json_display") {
346 oCommandType = Command_T::JSON_DISPLAY;
348 }
else if (lCommand ==
"quit") {
349 oCommandType = Command_T::QUIT;
354 ioTokenList.erase (itTok);
357 oCommandType = Command_T::NOP;
364 void parseFlightKey (
const TokenList_T& iTokenList,
365 stdair::AirlineCode_T& ioAirlineCode,
366 stdair::FlightNumber_T& ioFlightNumber) {
368 if (iTokenList.empty() ==
false) {
371 TokenList_T::const_iterator itTok = iTokenList.begin();
372 if (itTok->empty() ==
false) {
373 ioAirlineCode = *itTok;
374 boost::algorithm::to_upper (ioAirlineCode);
379 if (itTok != iTokenList.end()) {
381 if (itTok->empty() ==
false) {
384 ioFlightNumber = boost::lexical_cast<stdair::FlightNumber_T> (*itTok);
386 }
catch (boost::bad_lexical_cast& eCast) {
387 std::cerr <<
"The flight number ('" << *itTok
388 <<
"') cannot be understood. "
389 <<
"The default value (all) is kept."
402 void parseFlightDateKey (
const TokenList_T& iTokenList,
403 stdair::AirlineCode_T& ioAirlineCode,
404 stdair::FlightNumber_T& ioFlightNumber,
405 stdair::Date_T& ioDepartureDate) {
407 const std::string kMonthStr[12] = {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
408 "Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"};
410 unsigned short ioDepartureDateYear = ioDepartureDate.year();
411 unsigned short ioDepartureDateMonth = ioDepartureDate.month();
412 std::string ioDepartureDateMonthStr = kMonthStr[ioDepartureDateMonth-1];
413 unsigned short ioDepartureDateDay = ioDepartureDate.day();
416 if (iTokenList.empty() ==
false) {
419 TokenList_T::const_iterator itTok = iTokenList.begin();
420 if (itTok->empty() ==
false) {
421 ioAirlineCode = *itTok;
422 boost::algorithm::to_upper (ioAirlineCode);
427 if (itTok != iTokenList.end()) {
429 if (itTok->empty() ==
false) {
432 ioFlightNumber = boost::lexical_cast<stdair::FlightNumber_T> (*itTok);
434 }
catch (boost::bad_lexical_cast& eCast) {
435 std::cerr <<
"The flight number ('" << *itTok
436 <<
"') cannot be understood. "
437 <<
"The default value (all) is kept."
449 if (itTok != iTokenList.end()) {
451 if (itTok->empty() ==
false) {
454 ioDepartureDateYear = boost::lexical_cast<
unsigned short> (*itTok);
455 if (ioDepartureDateYear < 100) {
456 ioDepartureDateYear += 2000;
459 }
catch (boost::bad_lexical_cast& eCast) {
460 std::cerr <<
"The year of the flight departure date ('" << *itTok
461 <<
"') cannot be understood. The default value ("
462 << ioDepartureDateYear <<
") is kept. " << std::endl;
473 if (itTok != iTokenList.end()) {
475 if (itTok->empty() ==
false) {
478 const boost::regex lMonthRegex (
"^(\\d{1,2})$");
479 const bool isMonthANumber = regex_match (*itTok, lMonthRegex);
481 if (isMonthANumber ==
true) {
482 const unsigned short lMonth =
483 boost::lexical_cast<
unsigned short> (*itTok);
485 throw boost::bad_lexical_cast();
487 ioDepartureDateMonthStr = kMonthStr[lMonth-1];
490 const std::string lMonthStr (*itTok);
491 if (lMonthStr.size() < 3) {
492 throw boost::bad_lexical_cast();
494 std::string lMonthStr1 (lMonthStr.substr (0, 1));
495 boost::algorithm::to_upper (lMonthStr1);
496 std::string lMonthStr23 (lMonthStr.substr (1, 2));
497 boost::algorithm::to_lower (lMonthStr23);
498 ioDepartureDateMonthStr = lMonthStr1 + lMonthStr23;
501 }
catch (boost::bad_lexical_cast& eCast) {
502 std::cerr <<
"The month of the flight departure date ('" << *itTok
503 <<
"') cannot be understood. The default value ("
504 << ioDepartureDateMonthStr <<
") is kept. " << std::endl;
515 if (itTok != iTokenList.end()) {
517 if (itTok->empty() ==
false) {
520 ioDepartureDateDay = boost::lexical_cast<
unsigned short> (*itTok);
522 }
catch (boost::bad_lexical_cast& eCast) {
523 std::cerr <<
"The day of the flight departure date ('" << *itTok
524 <<
"') cannot be understood. The default value ("
525 << ioDepartureDateDay <<
") is kept. " << std::endl;
535 std::ostringstream lDepartureDateStr;
536 lDepartureDateStr << ioDepartureDateYear <<
"-" << ioDepartureDateMonthStr
537 <<
"-" << ioDepartureDateDay;
542 boost::gregorian::from_simple_string (lDepartureDateStr.str());
544 }
catch (boost::gregorian::bad_month& eCast) {
545 std::cerr <<
"The flight departure date ('" << lDepartureDateStr.str()
546 <<
"') cannot be understood. The default value ("
547 << ioDepartureDate <<
") is kept. " << std::endl;
555 void parseBookingClassKey (
const TokenList_T& iTokenList,
556 stdair::ClassCode_T& ioBookingClass,
557 stdair::PartySize_T& ioPartySize,
558 stdair::AirportCode_T& ioOrigin,
559 stdair::AirportCode_T& ioDestination) {
561 if (iTokenList.empty() ==
false) {
564 TokenList_T::const_iterator itTok = iTokenList.begin();
565 if (itTok->empty() ==
false) {
566 ioBookingClass = *itTok;
567 boost::algorithm::to_upper (ioBookingClass);
572 if (itTok != iTokenList.end()) {
574 if (itTok->empty() ==
false) {
577 ioPartySize = boost::lexical_cast<stdair::PartySize_T> (*itTok);
579 }
catch (boost::bad_lexical_cast& eCast) {
580 std::cerr <<
"The party size ('" << *itTok
581 <<
"') cannot be understood. The default value ("
582 << ioPartySize <<
") is kept." << std::endl;
593 if (itTok != iTokenList.end()) {
595 if (itTok->empty() ==
false) {
597 boost::algorithm::to_upper (ioOrigin);
606 if (itTok != iTokenList.end()) {
608 if (itTok->empty() ==
false) {
609 ioDestination = *itTok;
610 boost::algorithm::to_upper (ioDestination);
620 std::string toString (
const TokenList_T& iTokenList) {
621 std::ostringstream oStr;
624 unsigned short idx = 0;
625 for (TokenList_T::const_iterator itTok = iTokenList.begin();
626 itTok != iTokenList.end(); ++itTok, ++idx) {
637 TokenList_T extractTokenList (
const TokenList_T& iTokenList,
638 const std::string& iRegularExpression) {
639 TokenList_T oTokenList;
643 const std::string lFullLine = toString (iTokenList);
646 boost::regex expression (iRegularExpression);
648 std::string::const_iterator start = lFullLine.begin();
649 std::string::const_iterator end = lFullLine.end();
651 boost::match_results<std::string::const_iterator> what;
652 boost::match_flag_type flags = boost::match_default | boost::format_sed;
653 regex_search (start, end, what, expression, flags);
657 const unsigned short lMatchSetSize = what.size();
658 for (
unsigned short matchIdx = 1; matchIdx != lMatchSetSize; ++matchIdx) {
659 const std::string lMatchedString (std::string (what[matchIdx].first,
660 what[matchIdx].second));
662 oTokenList.push_back (lMatchedString);
673 TokenList_T extractTokenListForFlight (
const TokenList_T& iTokenList) {
680 const std::string lRegEx (
"^([[:alpha:]]{2,3})?"
681 "[[:space:]]*([[:digit:]]{1,4})?$");
684 const TokenList_T& oTokenList = extractTokenList (iTokenList, lRegEx);
689 TokenList_T extractTokenListForFlightDate (
const TokenList_T& iTokenList) {
700 const std::string lRegEx(
"^([[:alpha:]]{2,3})?"
701 "[[:space:]]*([[:digit:]]{1,4})?"
703 "([[:digit:]]{2,4})?[/-]?[[:space:]]*"
704 "([[:alpha:]]{3}|[[:digit:]]{1,2})?[/-]?[[:space:]]*"
705 "([[:digit:]]{1,2})?$");
708 const TokenList_T& oTokenList = extractTokenList (iTokenList, lRegEx);
713 TokenList_T extractTokenListForClass (
const TokenList_T& iTokenList) {
722 const std::string lRegEx (
"^([[:alpha:]])?"
723 "[[:space:]]*([[:digit:]]{1,3})?"
724 "[[:space:]]*([[:alpha:]]{3})?"
725 "[[:space:]]*([[:alpha:]]{3})?$");
728 const TokenList_T& oTokenList = extractTokenList (iTokenList, lRegEx);
734 int main (
int argc,
char* argv[]) {
742 stdair::Filename_T lInventoryFilename;
743 stdair::Filename_T lScheduleInputFilename;
744 stdair::Filename_T lODInputFilename;
745 stdair::Filename_T lFRAT5InputFilename;
746 stdair::Filename_T lFFDisutilityInputFilename;
747 stdair::Filename_T lYieldInputFilename;
750 const unsigned int lHistorySize (100);
751 const std::string lHistoryFilename (
"airinv.hist");
752 const std::string lHistoryBackupFilename (
"airinv.hist.bak");
755 stdair::AirlineCode_T lLastInteractiveAirlineCode;
756 stdair::FlightNumber_T lLastInteractiveFlightNumber;
757 stdair::Date_T lLastInteractiveDate;
758 stdair::AirlineCode_T lInteractiveAirlineCode;
759 stdair::FlightNumber_T lInteractiveFlightNumber;
760 stdair::Date_T lInteractiveDate;
761 stdair::AirportCode_T lInteractiveOrigin;
762 stdair::AirportCode_T lInteractiveDestination;
763 stdair::ClassCode_T lInteractiveBookingClass;
764 stdair::PartySize_T lInteractivePartySize;
767 std::string lSegmentDateKey;
770 stdair::Filename_T lLogFilename;
773 const int lOptionParserStatus =
774 readConfiguration (argc, argv, isBuiltin, isForSchedule, lInventoryFilename,
775 lScheduleInputFilename, lODInputFilename,
776 lFRAT5InputFilename, lFFDisutilityInputFilename,
777 lYieldInputFilename, lLogFilename);
779 if (lOptionParserStatus == K_AIRINV_EARLY_RETURN_STATUS) {
784 std::ofstream logOutputFile;
786 logOutputFile.open (lLogFilename.c_str());
787 logOutputFile.clear();
790 const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
794 STDAIR_LOG_DEBUG (
"Welcome to AirInv");
797 if (isBuiltin ==
true) {
800 airinvService.buildSampleBom();
803 lInteractiveAirlineCode =
"BA";
804 lInteractiveFlightNumber = 9;
805 lInteractiveDate = stdair::Date_T (2011, 06, 10);
806 lInteractiveBookingClass =
"Q";
807 lInteractivePartySize = 2;
808 lInteractiveOrigin =
"LHR";
809 lInteractiveDestination =
"SYD";
812 if (isForSchedule ==
true) {
814 stdair::ScheduleFilePath lScheduleFilePath (lScheduleInputFilename);
815 stdair::ODFilePath lODFilePath (lODInputFilename);
816 stdair::FRAT5FilePath lFRAT5FilePath (lFRAT5InputFilename);
817 stdair::FFDisutilityFilePath lFFDisutilityFilePath (lFFDisutilityInputFilename);
818 AIRRAC::YieldFilePath lYieldFilePath (lYieldInputFilename);
819 airinvService.parseAndLoad (lScheduleFilePath, lODFilePath,
820 lFRAT5FilePath, lFFDisutilityFilePath,
824 lInteractiveAirlineCode =
"SQ";
825 lInteractiveFlightNumber = 11;
826 lInteractiveDate = stdair::Date_T (2010, 01, 15);
827 lInteractiveBookingClass =
"Y";
828 lInteractivePartySize = 2;
829 lInteractiveOrigin =
"SIN";
830 lInteractiveDestination =
"BKK";
835 airinvService.parseAndLoad (lInventoryFilePath);
838 lInteractiveAirlineCode =
"SV";
839 lInteractiveFlightNumber = 5;
840 lInteractiveDate = stdair::Date_T (2010, 03, 11);
841 lInteractiveBookingClass =
"Y";
842 lInteractivePartySize = 2;
843 lInteractiveOrigin =
"KBP";
844 lInteractiveDestination =
"JFK";
849 lLastInteractiveAirlineCode = lInteractiveAirlineCode;
850 lLastInteractiveFlightNumber = lInteractiveFlightNumber;
851 lLastInteractiveDate = lInteractiveDate;
854 STDAIR_LOG_DEBUG (
"====================================================");
855 STDAIR_LOG_DEBUG (
"= Beginning of the interactive session =");
856 STDAIR_LOG_DEBUG (
"====================================================");
859 swift::SReadline lReader (lHistoryFilename, lHistorySize);
860 initReadline (lReader);
863 std::string lUserInput;
864 bool EndOfInput (
false);
865 Command_T::Type_T lCommandType (Command_T::NOP);
867 while (lCommandType != Command_T::QUIT && EndOfInput ==
false) {
869 std::ostringstream oPromptStr;
870 oPromptStr <<
"airinv "
871 << lInteractiveAirlineCode << lInteractiveFlightNumber
872 <<
" / " << lInteractiveDate
875 TokenList_T lTokenListByReadline;
876 lUserInput = lReader.GetLine (oPromptStr.str(), lTokenListByReadline,
880 lReader.SaveHistory (lHistoryBackupFilename);
884 std::cout << std::endl;
889 lCommandType = extractCommand (lTokenListByReadline);
891 switch (lCommandType) {
894 case Command_T::HELP: {
895 std::cout << std::endl;
896 std::cout <<
"Commands: " << std::endl;
897 std::cout <<
" help" <<
"\t\t" <<
"Display this help" << std::endl;
898 std::cout <<
" quit" <<
"\t\t" <<
"Quit the application" << std::endl;
899 std::cout <<
" list" <<
"\t\t"
900 <<
"List airlines, flights and departure dates" << std::endl;
901 std::cout <<
" select" <<
"\t\t"
902 <<
"Select a flight-date to become the current one"
904 std::cout <<
" display" <<
"\t"
905 <<
"Display the current flight-date" << std::endl;
906 std::cout <<
" sell" <<
"\t\t"
907 <<
"Make a booking on the current flight-date" << std::endl;
908 std::cout <<
" \nDebug Commands" << std::endl;
909 std::cout <<
" json_list" <<
"\t"
910 <<
"List airlines, flights and departure dates in a JSON format"
912 std::cout <<
" json_display" <<
"\t"
913 <<
"Display the current flight-date in a JSON format"
915 std::cout << std::endl;
920 case Command_T::QUIT: {
925 case Command_T::LIST: {
927 TokenList_T lTokenList = extractTokenListForFlight (lTokenListByReadline);
929 stdair::AirlineCode_T lAirlineCode (
"all");
930 stdair::FlightNumber_T lFlightNumber (0);
933 parseFlightKey (lTokenList, lAirlineCode, lFlightNumber);
936 const std::string lFlightNumberStr = (lFlightNumber ==0)?
" (all)":
"";
937 std::cout <<
"List of flights for "
938 << lAirlineCode <<
" " << lFlightNumber << lFlightNumberStr
942 const std::string& lFlightDateListStr =
943 airinvService.list (lAirlineCode, lFlightNumber);
945 if (lFlightDateListStr.empty() ==
false) {
946 std::cout << lFlightDateListStr << std::endl;
947 STDAIR_LOG_DEBUG (lFlightDateListStr);
950 std::cerr <<
"There is no result for "
951 << lAirlineCode <<
" " << lFlightNumber << lFlightNumberStr
952 <<
". Just type the list command without any parameter "
953 <<
"to see the flight-dates for all the airlines and for all "
954 <<
"the flight numbers."
962 case Command_T::SELECT: {
964 TokenList_T lTokenList =
965 extractTokenListForFlightDate (lTokenListByReadline);
968 if (lTokenList.empty() ==
false) {
970 TokenList_T::const_iterator itTok = lTokenList.begin();
975 boost::swap (lInteractiveAirlineCode, lLastInteractiveAirlineCode);
976 boost::swap (lInteractiveFlightNumber, lLastInteractiveFlightNumber);
977 boost::swap (lInteractiveDate, lLastInteractiveDate);
985 parseFlightDateKey (lTokenList, lInteractiveAirlineCode,
986 lInteractiveFlightNumber, lInteractiveDate);
989 const bool isFlightDateValid =
990 airinvService.check (lInteractiveAirlineCode, lInteractiveFlightNumber,
992 if (isFlightDateValid ==
false) {
993 std::ostringstream oFDKStr;
994 oFDKStr <<
"The " << lInteractiveAirlineCode
995 << lInteractiveFlightNumber <<
" / " << lInteractiveDate
996 <<
" flight-date is not valid. Make sure it exists (e.g.,"
997 <<
" with the list command). The current flight-date is kept"
999 std::cout << oFDKStr.str() << std::endl;
1000 STDAIR_LOG_ERROR (oFDKStr.str());
1003 lInteractiveAirlineCode = lLastInteractiveAirlineCode;
1004 lInteractiveFlightNumber = lLastInteractiveFlightNumber;
1005 lInteractiveDate = lLastInteractiveDate;
1011 std::ostringstream oFDKStr;
1012 oFDKStr <<
"Selected the " << lInteractiveAirlineCode
1013 << lInteractiveFlightNumber <<
" / " << lInteractiveDate
1015 std::cout << oFDKStr.str() << std::endl;
1016 STDAIR_LOG_DEBUG (oFDKStr.str());
1019 lLastInteractiveAirlineCode = lInteractiveAirlineCode;
1020 lLastInteractiveFlightNumber = lInteractiveFlightNumber;
1021 lLastInteractiveDate = lInteractiveDate;
1027 case Command_T::DISPLAY: {
1029 const std::string& lCSVFlightDateDump =
1030 airinvService.csvDisplay (lInteractiveAirlineCode,
1031 lInteractiveFlightNumber, lInteractiveDate);
1032 std::cout << lCSVFlightDateDump << std::endl;
1033 STDAIR_LOG_DEBUG (lCSVFlightDateDump);
1039 case Command_T::SELL: {
1041 TokenList_T lTokenList = extractTokenListForClass (lTokenListByReadline);
1045 parseBookingClassKey (lTokenList, lInteractiveBookingClass,
1046 lInteractivePartySize,
1047 lInteractiveOrigin, lInteractiveDestination);
1050 const std::string& lCSVFlightDateDumpBefore =
1051 airinvService.csvDisplay (lInteractiveAirlineCode,
1052 lInteractiveFlightNumber, lInteractiveDate);
1054 STDAIR_LOG_DEBUG (lCSVFlightDateDumpBefore);
1057 std::ostringstream oSDKStr;
1058 oSDKStr << lInteractiveAirlineCode <<
","
1059 << lInteractiveFlightNumber <<
","
1060 << lInteractiveDate <<
","
1061 << lInteractiveOrigin <<
"," << lInteractiveDestination;
1062 const std::string lSegmentDateKey (oSDKStr.str());
1065 const bool isSellSuccessful =
1066 airinvService.sell (lSegmentDateKey,
1067 lInteractiveBookingClass, lInteractivePartySize);
1070 const std::string isSellSuccessfulStr =
1071 (isSellSuccessful ==
true)?
"Yes":
"No";
1072 std::ostringstream oSaleStr;
1073 oSaleStr <<
"Sale ('" << lSegmentDateKey <<
"', "
1074 << lInteractiveBookingClass <<
": " << lInteractivePartySize
1075 <<
") successful? " << isSellSuccessfulStr;
1076 std::cout << oSaleStr.str() << std::endl;
1079 STDAIR_LOG_DEBUG (oSaleStr.str());
1082 const std::string& lCSVFlightDateDumpAfter =
1083 airinvService.csvDisplay (lInteractiveAirlineCode,
1084 lInteractiveFlightNumber, lInteractiveDate);
1086 STDAIR_LOG_DEBUG (lCSVFlightDateDumpAfter);
1093 case Command_T::JSON_LIST: {
1096 TokenList_T lTokenList = extractTokenListForFlight (lTokenListByReadline);
1098 stdair::AirlineCode_T lAirlineCode (
"all");
1099 stdair::FlightNumber_T lFlightNumber (0);
1102 parseFlightKey (lTokenList, lAirlineCode, lFlightNumber);
1105 const std::string lFlightNumberStr = (lFlightNumber ==0)?
" (all)":
"";
1106 std::cout <<
"JSON list of flights for "
1107 << lAirlineCode <<
" " << lFlightNumber << lFlightNumberStr
1110 std::ostringstream lMyCommandJSONstream;
1111 lMyCommandJSONstream <<
"{\"list\":"
1112 <<
"{ \"airline_code\":\"" << lAirlineCode
1113 <<
"\",\"flight_number\":\"" << lFlightNumber
1116 const stdair::JSONString lJSONCommandString (lMyCommandJSONstream.str());
1117 const std::string& lFlightDateListJSONStr =
1118 airinvService.jsonHandler (lJSONCommandString);
1121 std::cout << lFlightDateListJSONStr << std::endl;
1122 STDAIR_LOG_DEBUG (lFlightDateListJSONStr);
1129 case Command_T::JSON_DISPLAY: {
1133 std::ostringstream lMyCommandJSONstream;
1134 lMyCommandJSONstream <<
"{\"flight_date\":"
1135 <<
"{ \"departure_date\":\"" << lInteractiveDate
1136 <<
"\",\"airline_code\":\"" << lInteractiveAirlineCode
1137 <<
"\",\"flight_number\":\"" << lInteractiveFlightNumber
1141 const stdair::JSONString lJSONCommandString (lMyCommandJSONstream.str());
1142 const std::string& lCSVFlightDateDump =
1143 airinvService.jsonHandler (lJSONCommandString);
1146 std::cout << lCSVFlightDateDump << std::endl;
1147 STDAIR_LOG_DEBUG (lCSVFlightDateDump);
1153 case Command_T::NOP: {
1157 case Command_T::LAST_VALUE:
1160 std::ostringstream oStr;
1161 oStr <<
"That command is not yet understood: '" << lUserInput
1162 <<
"' => " << lTokenListByReadline;
1163 STDAIR_LOG_DEBUG (oStr.str());
1164 std::cout << oStr.str() << std::endl;
1170 STDAIR_LOG_DEBUG (
"End of the session. Exiting.");
1171 std::cout <<
"End of the session. Exiting." << std::endl;
1174 logOutputFile.close();