forked from OpenChemistry/avogadrolibs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pythoncmdlineinterface.cpp
169 lines (153 loc) · 5.92 KB
/
pythoncmdlineinterface.cpp
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#include "pythoncmdlineinterface.h"
bool isBinaryPresent(const QString& binaryName) {
QProcess process;
process.start(binaryName, QStringList() << "--version");
process.waitForFinished();
return process.exitCode() == 0;
}
void installRequirements(const QString& folderPath, const QString& installMethod, const QString& pythonInstallation) {
if (installMethod.isEmpty()) {
return;
}
if (!isBinaryPresent(installMethod)) {
QMessageBox::critical(nullptr, "Installation Error", installMethod + " is not installed on this system.");
return;
}
// Extract the environment name from pythonInstallation, if present
QString envName;
int colonIndex = pythonInstallation.indexOf(":");
int parenIndex = pythonInstallation.indexOf(")");
if (parenIndex != -1 && colonIndex != -1) {
assert(colonIndex < parenIndex);
envName = pythonInstallation.mid(colonIndex + 1, parenIndex - colonIndex - 1).trimmed();
}
// Prepare environment activation command only if envName is not empty
QString activateCommand;
if (!envName.isEmpty()) {
if (pythonInstallation.contains("Conda")) {
if ( envName.isEmpty() ) {
activateCommand = QString("conda run ");
} else {
activateCommand = QString("conda run -n %1 ").arg(envName);
}
} else if (pythonInstallation.contains("VirtualEnv")) {
activateCommand = (QSysInfo::productType() == "windows") ?
QString("%1\\Scripts\\activate && ").arg(envName) :
QString("source %1/bin/activate && ").arg(envName);
}
}
QString requirementsTxt = folderPath + "/requirements.txt";
QString pyprojectToml = folderPath + "/pyproject.toml";
QString installCommand;
if (QFile::exists(requirementsTxt)) {
if (installMethod == "pip") {
installCommand = activateCommand + "pip install -r " + requirementsTxt;
} else if (installMethod == "conda") {
installCommand = activateCommand + "conda install --file " + requirementsTxt;
}
} else if (QFile::exists(pyprojectToml)) {
if (installMethod == "pip") {
installCommand = activateCommand + "pip install " + folderPath;
} else if (installMethod == "conda") {
QMessageBox::information(nullptr, "Installation Info", "Conda cannot install from a pyproject.toml file.");
return;
}
} else {
QMessageBox::information(nullptr, "No Requirements Found", "Neither requirements.txt nor pyproject.toml found.");
return;
}
QProcess process;
process.start(installCommand);
process.waitForFinished();
if (process.exitCode() != 0) {
QMessageBox::critical(nullptr, "Installation Error", process.readAllStandardError());
}
}
QString extractPythonPaths(const QString& pythonInterpreterString) {
int colonIndex = pythonInterpreterString.lastIndexOf(":");
if (colonIndex != -1) {
QString path = pythonInterpreterString.mid(colonIndex + 1).trimmed();
return path;
}
return "";
}
QString pythonInterpreterVersion(const QString& interpreterPath) {
QProcess process;
process.start(interpreterPath + " --version");
process.waitForFinished();
if ( process.exitCode() == 0 ) {
return process.readAllStandardOutput();
} else {
return "Python";
}
}
QStringList detectPythonInterpreters() {
QStringList interpreters;
QProcess process;
QString pythonCmd = (QSysInfo::productType() == "windows") ? "where python" : "which python";
process.start(pythonCmd);
process.waitForFinished();
QString systemPythonPath = process.readAllStandardOutput();
if (!systemPythonPath.isEmpty()) {
QString pythonPath = systemPythonPath.trimmed();
interpreters << QString("%1: %2").arg(pythonInterpreterVersion(pythonPath),pythonPath);
}
process.start("conda env list");
process.waitForFinished();
QString condaEnvsOutput = process.readAllStandardOutput();
auto lines = condaEnvsOutput.split('\n');
for (const QString& line : lines.mid(2)) {
if (!line.isEmpty()) {
auto parts = line.split(' ');
QString envName = parts[0];
QString envPath = parts.last();
QString pythonPath = envPath + QDir::separator() + "bin" + QDir::separator() + "python";
interpreters << QString("%1 (Conda: %2): %3").arg(pythonInterpreterVersion(pythonPath),envName, pythonPath);
}
}
// virtualenv cannot be detected automatically
return interpreters;
}
void activateEnvironment(const QString& envType, const QString& envName) {
QProcess process;
if (envType == "Conda") {
process.start("conda --version");
process.waitForFinished();
if (process.exitCode() != 0) {
QMessageBox::warning(nullptr, "Activation Failed", "Conda is not installed on this computer.");
return;
}
if (envName == "") {
process.start("conda deactivate");
} else {
process.start(QString("conda activate %1").arg(envName));
}
} else if (envType == "VirtualEnv") {
if (envName == "") {
process.start("deactivate");
} else {
process.start(QString("source %1/bin/activate").arg(envName));
}
}
process.waitForFinished();
if (process.exitCode() != 0) {
QMessageBox::warning(nullptr, "Activation Failed", "Failed to activate or deactivate environment");
}
}
QString extractInstallerCodeFrom(const QString& interpreter) {
bool hasConda = false;
bool hasPip = false;
if (interpreter.contains("Conda")) {
hasConda = true;
}
if (interpreter.contains("VirtualEnv")) {
hasPip = true;
}
if (hasConda) {
return "conda";
} else if (hasPip) {
return "pip";
} else {
return "";
}
}