41 return getPathsImpl();
55 std::string
generate (
const std::string& iOutputFormatString,
60 return generateImpl (iNbOfDraws, lOutputFormatEnum);
71 const std::string& oPBStr = generateImpl (iNbOfDraws, lOutputFormatEnum);
73 const ssize_t lPBSize = oPBStr.size();
77 const bp::object& oPBObj =
78 bp::object (bp::handle<> (PyBytes_FromStringAndSize (oPBStr.c_str(),
87 std::string
search (
const std::string& iOutputFormatString,
88 const std::string& iTravelQuery) {
92 return searchImpl (iTravelQuery, lOutputFormatEnum);
98 bp::object
searchToPB (
const std::string& iTravelQuery) {
102 const std::string& oPBStr = searchImpl (iTravelQuery, lOutputFormatEnum);
103 const ssize_t lPBSize = oPBStr.size();
107 const bp::object& oPBObj =
108 bp::object (bp::handle<> (PyBytes_FromStringAndSize (oPBStr.c_str(),
118 std::string getPathsImpl() {
119 std::ostringstream oPythonLogStr;
122 if (_logOutputStream == NULL) {
123 oPythonLogStr <<
"The log filepath is not valid." << std::endl;
124 return oPythonLogStr.str();
126 assert (_logOutputStream != NULL);
131 *_logOutputStream <<
"Get the file-path details" << std::endl;
133 if (_opentrepService == NULL) {
134 oPythonLogStr <<
"The OpenTREP service has not been initialized, "
135 <<
"i.e., the init() method has not been called "
136 <<
"correctly on the OpenTrepSearcher object. Please "
137 <<
"check that all the parameters are not empty and "
138 <<
"point to actual files.";
139 *_logOutputStream << oPythonLogStr.str();
140 return oPythonLogStr.str();
142 assert (_opentrepService != NULL);
146 _opentrepService->getFilePaths();
147 const PORFilePath_T& lPORFilePath = lFilePathSet.first;
150 const TravelDBFilePath_T& lTravelDBFilePath = lDBFilePathPair.first;
151 const SQLDBConnectionString_T& lSQLDBConnStr = lDBFilePathPair.second;
154 oPythonLogStr << lPORFilePath <<
";" << lTravelDBFilePath
155 <<
";" << lSQLDBConnStr;
158 *_logOutputStream <<
"OPTD-maintained list of POR: '" << lPORFilePath
160 *_logOutputStream <<
"Xapian travel database/index: '"
161 << lTravelDBFilePath <<
"'" << std::endl;
162 *_logOutputStream <<
"SQL database connection string: '"
163 << lSQLDBConnStr <<
"'" << std::endl;
165 }
catch (
const RootException& eOpenTrepError) {
166 *_logOutputStream <<
"OpenTrep error: " << eOpenTrepError.what()
169 }
catch (
const std::exception& eStdError) {
170 *_logOutputStream <<
"Error: " << eStdError.what() << std::endl;
173 *_logOutputStream <<
"Unknown error" << std::endl;
177 return oPythonLogStr.str();
183 std::string indexImpl() {
184 std::ostringstream oPythonLogStr;
187 if (_logOutputStream == NULL) {
188 oPythonLogStr <<
"The log filepath is not valid." << std::endl;
189 return oPythonLogStr.str();
191 assert (_logOutputStream != NULL);
196 *_logOutputStream <<
"Indexation by Xapian" << std::endl;
198 if (_opentrepService == NULL) {
199 oPythonLogStr <<
"The OpenTREP service has not been initialized, "
200 <<
"i.e., the init() method has not been called "
201 <<
"correctly on the OpenTrepSearcher object. Please "
202 <<
"check that all the parameters are not empty and "
203 <<
"point to actual files.";
204 *_logOutputStream << oPythonLogStr.str();
205 return oPythonLogStr.str();
207 assert (_opentrepService != NULL);
211 _opentrepService->getFilePaths();
212 const PORFilePath_T& lPORFilePath = lFilePathSet.first;
215 const TravelDBFilePath_T& lTravelDBFilePath = lDBFilePathPair.first;
216 const SQLDBConnectionString_T& lSQLDBConnStr = lDBFilePathPair.second;
219 *_logOutputStream <<
"OPTD-maintained list of POR: '" << lPORFilePath
221 *_logOutputStream <<
"Xapian travel database/index: '"
222 << lTravelDBFilePath <<
"'" << std::endl;
223 *_logOutputStream <<
"SQL database connection string: '"
224 << lSQLDBConnStr <<
"'" << std::endl;
227 const NbOfDBEntries_T lNbOfEntries= _opentrepService->insertIntoDBAndXapian();
230 oPythonLogStr << lNbOfEntries;
233 *_logOutputStream <<
"Xapian indexation yielded " << lNbOfEntries
234 <<
" POR (points of reference) entries." << std::endl;
236 }
catch (
const RootException& eOpenTrepError) {
237 *_logOutputStream <<
"OpenTrep error: " << eOpenTrepError.what()
240 }
catch (
const std::exception& eStdError) {
241 *_logOutputStream <<
"Error: " << eStdError.what() << std::endl;
244 *_logOutputStream <<
"Unknown error" << std::endl;
248 return oPythonLogStr.str();
254 std::string searchImpl (
const std::string& iTravelQuery,
256 const std::string oEmptyStr (
"");
257 std::ostringstream oNoDetailedStr;
258 std::ostringstream oDetailedStr;
259 std::ostringstream oJSONStr;
260 std::ostringstream oProtobufStr;
263 if (_logOutputStream == NULL) {
264 oNoDetailedStr <<
"The log filepath is not valid." << std::endl;
265 return oNoDetailedStr.str();
267 assert (_logOutputStream != NULL);
272 *_logOutputStream <<
"Travel query ('" << iTravelQuery <<
"'"
273 <<
"') search" << std::endl;
275 if (_opentrepService == NULL) {
276 oNoDetailedStr <<
"The OpenTREP service has not been initialized, "
277 <<
"i.e., the init() method has not been called "
278 <<
"correctly on the OpenTrepSearcher object. Please "
279 <<
"check that all the parameters are not empty and "
280 <<
"point to actual files.";
281 *_logOutputStream << oNoDetailedStr.str();
282 return oNoDetailedStr.str();
284 assert (_opentrepService != NULL);
288 _opentrepService->getFilePaths();
289 const PORFilePath_T& lPORFilePath = lFilePathSet.first;
292 const TravelDBFilePath_T& lTravelDBFilePath = lDBFilePathPair.first;
293 const SQLDBConnectionString_T& lSQLDBConnStr = lDBFilePathPair.second;
298 _opentrepService->getDeploymentNumber();
299 const bool lExistXapianDBDir =
300 _opentrepService->checkXapianDBOnFileSystem (lTravelDBFilePath);
301 if (lExistXapianDBDir ==
false) {
302 *_logOutputStream <<
"Error - The file-path to the Xapian "
303 <<
"database/index ('" << lTravelDBFilePath
304 <<
"') does not exist or is not a directory."
306 *_logOutputStream <<
"Error - That usually means that the OpenTREP "
307 <<
"indexer (opentrep-indexer) has not been "
308 <<
"launched yet, or that it has operated on a "
309 <<
"different Xapian database/index file-path."
311 *_logOutputStream <<
"Error - For instance the Xapian database/index "
312 <<
"may have been created with a different "
313 <<
"deployment number (" << lDeploymentNumber
314 <<
" being the current deployment number)";
315 return oNoDetailedStr.str();
319 *_logOutputStream <<
"Xapian travel database/index: '"
321 <<
"' - SQL database connection string: '"
323 <<
"' - OPTD-maintained list of POR: '"
324 << lPORFilePath <<
"'" << std::endl;
330 _opentrepService->interpretTravelRequest (iTravelQuery, lLocationList,
331 lNonMatchedWordList);
334 *_logOutputStream <<
"Python search for '" << iTravelQuery <<
"' gave "
335 << nbOfMatches <<
" matches." << std::endl;
337 if (nbOfMatches != 0) {
340 for(LocationList_T::const_iterator itLocation = lLocationList.begin();
341 itLocation != lLocationList.end(); ++itLocation, ++idx) {
342 const Location& lLocation = *itLocation;
345 oNoDetailedStr <<
",";
349 oNoDetailedStr << lLocation.getIataCode();
350 oDetailedStr << idx+1 <<
". " << lLocation.toSingleLocationString()
356 lLocation.getExtraLocationList();
357 if (lExtraLocationList.empty() ==
false) {
358 oDetailedStr <<
" Extra matches: " << std::endl;
361 for (LocationList_T::const_iterator itLoc =
362 lExtraLocationList.begin();
363 itLoc != lExtraLocationList.end(); ++itLoc, ++idxExtra) {
364 oNoDetailedStr <<
":";
365 oDetailedStr <<
" " << idx+1 <<
"." << idxExtra+1 <<
". ";
367 const Location& lExtraLocation = *itLoc;
368 oNoDetailedStr << lExtraLocation.getIataCode();
369 oDetailedStr << lExtraLocation << std::endl;
375 oNoDetailedStr <<
"/" << lLocation.getPercentage();
380 lLocation.getAlternateLocationList();
381 if (lAlternateLocationList.empty() ==
false) {
382 oDetailedStr <<
" Alternate matches: " << std::endl;
385 for (LocationList_T::const_iterator itLoc =
386 lAlternateLocationList.begin();
387 itLoc != lAlternateLocationList.end(); ++itLoc, ++idxAlter) {
388 oNoDetailedStr <<
"-";
389 oDetailedStr <<
" " << idx+1 <<
"." << idxAlter+1 <<
". ";
391 const Location& lAlternateLocation = *itLoc;
392 oNoDetailedStr << lAlternateLocation.getIataCode()
393 <<
"/" << lAlternateLocation.getPercentage();
394 oDetailedStr << lAlternateLocation << std::endl;
400 if (lNonMatchedWordList.empty() ==
false) {
401 oNoDetailedStr <<
";";
402 oDetailedStr <<
"Not recognised words:" << std::endl;
404 for (WordList_T::const_iterator itWord = lNonMatchedWordList.begin();
405 itWord != lNonMatchedWordList.end(); ++itWord, ++idx) {
406 const Word_T& lWord = *itWord;
408 oNoDetailedStr <<
",";
409 oDetailedStr << idx+1 <<
"." << std::endl;
411 oNoDetailedStr << lWord;
412 oDetailedStr << lWord;
417 *_logOutputStream <<
"Python search for '" << iTravelQuery
418 <<
"' yielded:" << std::endl;
428 }
catch (
const RootException& eOpenTrepError) {
429 *_logOutputStream <<
"OpenTrep error: " << eOpenTrepError.what()
432 }
catch (
const std::exception& eStdError) {
433 *_logOutputStream <<
"Error: " << eStdError.what() << std::endl;
436 *_logOutputStream <<
"Unknown error" << std::endl;
441 switch (iOutputFormat) {
444 const std::string& oNoDetailedString = oNoDetailedStr.str();
445 *_logOutputStream <<
"Short version ("
446 << oNoDetailedString.size() <<
" char): "
447 << oNoDetailedString << std::endl;
448 return oNoDetailedString;
453 const std::string& oDetailedString = oDetailedStr.str();
454 *_logOutputStream <<
"Long version ("
455 << oDetailedString.size() <<
" char): "
456 << oDetailedString << std::endl;
457 return oDetailedString;
462 const std::string& oJSONString = oJSONStr.str();
463 *_logOutputStream <<
"JSON version ("
464 << oJSONString.size() <<
" char): "
465 << oJSONString << std::endl;
471 const std::string& oProtobufString = oProtobufStr.str();
472 *_logOutputStream <<
"Protobuf version ("
473 << oProtobufString.size() <<
" char): "
474 << oProtobufString << std::endl;
475 return oProtobufString;
494 const std::string oEmptyStr (
"");
495 std::ostringstream oNoDetailedStr;
496 std::ostringstream oDetailedStr;
497 std::ostringstream oJSONStr;
498 std::ostringstream oProtobufStr;
501 if (_logOutputStream == NULL) {
502 oNoDetailedStr <<
"The log filepath is not valid." << std::endl;
503 return oNoDetailedStr.str();
505 assert (_logOutputStream != NULL);
510 *_logOutputStream <<
"Number of random draws: " << iNbOfDraws
513 if (_opentrepService == NULL) {
514 oNoDetailedStr <<
"The OpenTREP service has not been initialized, "
515 <<
"i.e., the init() method has not been called "
516 <<
"correctly on the OpenTrepSearcher object. Please "
517 <<
"check that all the parameters are not empty and "
518 <<
"point to actual files.";
519 *_logOutputStream << oNoDetailedStr.str();
520 return oNoDetailedStr.str();
522 assert (_opentrepService != NULL);
526 _opentrepService->getFilePaths();
527 const PORFilePath_T& lPORFilePath = lFilePathSet.first;
530 const TravelDBFilePath_T& lTravelDBFilePath = lDBFilePathPair.first;
531 const SQLDBConnectionString_T& lSQLDBConnStr = lDBFilePathPair.second;
534 *_logOutputStream <<
"Xapian travel database/index: '"
536 <<
"' - SQL database connection string: '"
538 <<
"' - OPTD-maintained list of POR: '"
539 << lPORFilePath <<
"'" << std::endl;
544 _opentrepService->drawRandomLocations (iNbOfDraws, lLocationList);
547 *_logOutputStream <<
"Python generation of " << iNbOfDraws <<
" gave "
548 << nbOfMatches <<
" documents." << std::endl;
550 if (nbOfMatches != 0) {
553 for(LocationList_T::const_iterator itLocation = lLocationList.begin();
554 itLocation != lLocationList.end(); ++itLocation, ++idx) {
555 const Location& lLocation = *itLocation;
558 oNoDetailedStr <<
",";
562 oNoDetailedStr << lLocation.getIataCode();
563 oDetailedStr << idx+1 <<
". " << lLocation.toSingleLocationString()
569 lLocation.getExtraLocationList();
570 if (lExtraLocationList.empty() ==
false) {
571 oDetailedStr <<
" Extra matches: " << std::endl;
574 for (LocationList_T::const_iterator itLoc =
575 lExtraLocationList.begin();
576 itLoc != lExtraLocationList.end(); ++itLoc, ++idxExtra) {
577 oNoDetailedStr <<
":";
578 oDetailedStr <<
" " << idx+1 <<
"." << idxExtra+1 <<
". ";
580 const Location& lExtraLocation = *itLoc;
581 oNoDetailedStr << lExtraLocation.getIataCode();
582 oDetailedStr << lExtraLocation << std::endl;
588 oNoDetailedStr <<
"/" << lLocation.getPercentage();
593 lLocation.getAlternateLocationList();
594 if (lAlternateLocationList.empty() ==
false) {
595 oDetailedStr <<
" Alternate matches: " << std::endl;
598 for (LocationList_T::const_iterator itLoc =
599 lAlternateLocationList.begin();
600 itLoc != lAlternateLocationList.end(); ++itLoc, ++idxAlter) {
601 oNoDetailedStr <<
"-";
602 oDetailedStr <<
" " << idx+1 <<
"." << idxAlter+1 <<
". ";
604 const Location& lAlternateLocation = *itLoc;
605 oNoDetailedStr << lAlternateLocation.getIataCode()
606 <<
"/" << lAlternateLocation.getPercentage();
607 oDetailedStr << lAlternateLocation << std::endl;
614 *_logOutputStream <<
"Python generation of " << iNbOfDraws
615 <<
" yielded:" << std::endl;
626 }
catch (
const RootException& eOpenTrepError) {
627 *_logOutputStream <<
"OpenTrep error: " << eOpenTrepError.what()
630 }
catch (
const std::exception& eStdError) {
631 *_logOutputStream <<
"Error: " << eStdError.what() << std::endl;
634 *_logOutputStream <<
"Unknown error" << std::endl;
639 switch (iOutputFormat) {
642 const std::string& oNoDetailedString = oNoDetailedStr.str();
643 *_logOutputStream <<
"Short version ("
644 << oNoDetailedString.size() <<
" char): "
645 << oNoDetailedString << std::endl;
646 return oNoDetailedString;
651 const std::string& oDetailedString = oDetailedStr.str();
652 *_logOutputStream <<
"Long version ("
653 << oDetailedString.size() <<
" char): "
654 << oDetailedString << std::endl;
655 return oDetailedString;
660 const std::string& oJSONString = oJSONStr.str();
661 *_logOutputStream <<
"JSON version ("
662 << oJSONString.size() <<
" char): "
663 << oJSONString << std::endl;
669 const std::string& oProtobufString = oProtobufStr.str();
670 *_logOutputStream <<
"Protobuf version ("
671 << oProtobufString.size() <<
" char): "
672 << oProtobufString << std::endl;
673 return oProtobufString;
698 : _opentrepService (iOpenTrepSearcher._opentrepService),
699 _logOutputStream (iOpenTrepSearcher._logOutputStream) {
706 _opentrepService = NULL;
707 _logOutputStream = NULL;
715 bool init (
const std::string& iPORFilePath,
716 const std::string& iTravelDBFilePath,
717 const std::string& iSQLDBTypeStr,
718 const std::string& iSQLDBConnStr,
719 const unsigned short& iDeploymentNumber,
720 const bool iDontIndexIATAPOR,
721 const bool iIndexPORInXapian,
722 const bool iAddPORInDB,
723 const std::string& iLogFilePath) {
724 bool isEverythingOK =
true;
729 std::ostringstream oXFP;
730 oXFP << iTravelDBFilePath << iDeploymentNumber;
731 const std::string lXapianFP = oXFP.str();
734 _logOutputStream =
new std::ofstream;
735 assert (_logOutputStream != NULL);
738 _logOutputStream->open (iLogFilePath.c_str());
739 _logOutputStream->clear();
742 *_logOutputStream <<
"[pyopentrep][init] Python wrapper initialization"
752 lDontIndexIATAPOR (iDontIndexIATAPOR);
754 lIndexPORInXapian (iIndexPORInXapian);
760 lSQLDBType, lSQLDBConnStr,
767 *_logOutputStream <<
"[pyopentrep][init] Python wrapper initialized."
768 <<
" Parameters:" << std::endl;
769 *_logOutputStream <<
"[pyopentrep][init] POR data file: "
770 << iPORFilePath << std::endl;
771 *_logOutputStream <<
"[pyopentrep][init] Xapian DB: "
772 << iTravelDBFilePath << std::endl;
773 *_logOutputStream <<
"[pyopentrep][init][DB] Type: " << iSQLDBTypeStr
774 <<
" - Connection string: " << iSQLDBConnStr
776 *_logOutputStream <<
"[pyopentrep][init] Deployment number: "
777 << iDeploymentNumber << std::endl;
778 *_logOutputStream <<
"[pyopentrep][init] Should index non-IATA POR? "
779 << iDontIndexIATAPOR << std::endl;
780 *_logOutputStream <<
"[pyopentrep][init] Should index POR in Xapian? "
781 << iIndexPORInXapian << std::endl;
782 *_logOutputStream <<
"[pyopentrep][init] Should add POR in database? "
783 << iAddPORInDB << std::endl;
786 *_logOutputStream <<
"OpenTrep error: " << eOpenTrepError.
what()
789 }
catch (
const std::exception& eStdError) {
790 *_logOutputStream <<
"Error: " << eStdError.what() << std::endl;
793 *_logOutputStream <<
"Unknown error" << std::endl;
796 return isEverythingOK;
803 bool isEverythingOK =
true;
808 if (_opentrepService != NULL) {
809 delete _opentrepService; _opentrepService = NULL;
813 if (_logOutputStream != NULL) {
815 *_logOutputStream <<
"Python wrapper finalization" << std::endl;
816 _logOutputStream->close();
817 delete _logOutputStream; _logOutputStream = NULL;
823 return isEverythingOK;
831 std::ofstream* _logOutputStream;