1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
#include "pythonfilepath.h"
#include <aocommon/logger.h>
#include <boost/filesystem.hpp>
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <random>
namespace wsclean::system {
std::string FindPythonFilePath(const std::string& filename) {
if (boost::filesystem::exists(filename)) return filename;
aocommon::Logger::Debug << "Searching " << filename << "... ";
aocommon::Logger::Debug.Flush();
std::random_device rndDev;
std::mt19937 gen(rndDev());
std::stringstream filenameStr;
filenameStr << "/tmp/ao-python-path-list" << gen() << ".tmp";
boost::filesystem::path tempPath =
filenameStr.str(); // boost::filesystem::unique_path();
const std::string tempFilename = tempPath.string(); // optional
std::string command =
std::string(
"echo \"from __future__ import print_function\nimport sys\nfor a in "
"sys.path:\n print(a)\"|python>") +
tempFilename;
int status = std::system(command.c_str());
if (status != 0) {
// retry with python3
command = std::string(
"echo \"from __future__ import print_function\nimport "
"sys\nfor a in "
"sys.path:\n print(a)\"|python3>") +
tempFilename;
status = std::system(command.c_str());
}
if (status != 0)
throw std::runtime_error(
"std::system() returned non-zero error code: might be out of memory, "
"or "
"python might not be working properly.\nCommand was:\n" +
command);
std::ifstream searchPathsFile(tempFilename.c_str());
if (!searchPathsFile.good())
throw std::runtime_error(("Error in findPythonFilePath: system call did "
"not create expected temporary file " +
tempFilename)
.c_str());
while (searchPathsFile.good()) {
std::string prefixPath;
std::getline(searchPathsFile, prefixPath);
boost::filesystem::path searchPath(prefixPath);
searchPath /= filename;
bool pathExists = false;
try {
pathExists = boost::filesystem::exists(searchPath);
} catch (...) {
}
if (pathExists) {
const std::string result = searchPath.string();
aocommon::Logger::Debug << result << '\n';
searchPathsFile.close();
boost::filesystem::remove(tempPath);
return result;
}
}
searchPathsFile.clear();
searchPathsFile.seekg(0, std::ios::beg);
std::string err(std::string("Could not find Python file ") + filename +
". Paths searched:\n");
while (searchPathsFile.good()) {
std::string prefixPath;
std::getline(searchPathsFile, prefixPath);
err += prefixPath + '\n';
}
searchPathsFile.close();
boost::filesystem::remove(tempPath);
throw std::runtime_error(err);
}
} // namespace wsclean::system
|