[arch-commits] Commit in pgadmin4/repos (20 files)
Jerome Leclanche
jleclanche at archlinux.org
Sun Jun 18 11:00:00 UTC 2017
Date: Sunday, June 18, 2017 @ 10:59:59
Author: jleclanche
Revision: 238033
archrelease: copy trunk to community-i686, community-x86_64
Added:
pgadmin4/repos/community-i686/0001-Simplify-Server-s-python-setup.patch
(from rev 238032, pgadmin4/trunk/0001-Simplify-Server-s-python-setup.patch)
pgadmin4/repos/community-i686/PKGBUILD
(from rev 238032, pgadmin4/trunk/PKGBUILD)
pgadmin4/repos/community-i686/config_distro.py
(from rev 238032, pgadmin4/trunk/config_distro.py)
pgadmin4/repos/community-i686/config_local.py
(from rev 238032, pgadmin4/trunk/config_local.py)
pgadmin4/repos/community-i686/pgAdmin4.desktop
(from rev 238032, pgadmin4/trunk/pgAdmin4.desktop)
pgadmin4/repos/community-x86_64/0001-Simplify-Server-s-python-setup.patch
(from rev 238032, pgadmin4/trunk/0001-Simplify-Server-s-python-setup.patch)
pgadmin4/repos/community-x86_64/PKGBUILD
(from rev 238032, pgadmin4/trunk/PKGBUILD)
pgadmin4/repos/community-x86_64/config_distro.py
(from rev 238032, pgadmin4/trunk/config_distro.py)
pgadmin4/repos/community-x86_64/config_local.py
(from rev 238032, pgadmin4/trunk/config_local.py)
pgadmin4/repos/community-x86_64/pgAdmin4.desktop
(from rev 238032, pgadmin4/trunk/pgAdmin4.desktop)
Deleted:
pgadmin4/repos/community-i686/0001-Simplify-Server-s-python-setup.patch
pgadmin4/repos/community-i686/PKGBUILD
pgadmin4/repos/community-i686/config_distro.py
pgadmin4/repos/community-i686/config_local.py
pgadmin4/repos/community-i686/pgAdmin4.desktop
pgadmin4/repos/community-x86_64/0001-Simplify-Server-s-python-setup.patch
pgadmin4/repos/community-x86_64/PKGBUILD
pgadmin4/repos/community-x86_64/config_distro.py
pgadmin4/repos/community-x86_64/config_local.py
pgadmin4/repos/community-x86_64/pgAdmin4.desktop
------------------------------------------------------------+
/0001-Simplify-Server-s-python-setup.patch | 1266 +++++++++++
/PKGBUILD | 172 +
/config_distro.py | 4
/pgAdmin4.desktop | 22
community-i686/0001-Simplify-Server-s-python-setup.patch | 633 -----
community-i686/PKGBUILD | 84
community-i686/config_distro.py | 2
community-i686/pgAdmin4.desktop | 11
community-x86_64/0001-Simplify-Server-s-python-setup.patch | 633 -----
community-x86_64/PKGBUILD | 84
community-x86_64/config_distro.py | 2
community-x86_64/pgAdmin4.desktop | 11
12 files changed, 1464 insertions(+), 1460 deletions(-)
Deleted: community-i686/0001-Simplify-Server-s-python-setup.patch
===================================================================
--- community-i686/0001-Simplify-Server-s-python-setup.patch 2017-06-18 10:59:49 UTC (rev 238032)
+++ community-i686/0001-Simplify-Server-s-python-setup.patch 2017-06-18 10:59:59 UTC (rev 238033)
@@ -1,633 +0,0 @@
-From a5a1c332e23a094e0c2a1c9513fb9f6b05cbbf05 Mon Sep 17 00:00:00 2001
-From: "Jan Alexander Steffens (heftig)" <jan.steffens at gmail.com>
-Date: Sat, 28 Jan 2017 01:19:06 +0100
-Subject: [PATCH] Simplify Server's python setup
----
- runtime/BrowserWindow.cpp | 6 +-
- runtime/ConfigWindow.cpp | 16 ++-
- runtime/ConfigWindow.h | 6 +-
- runtime/ConfigWindow.ui | 22 +++-
- runtime/Server.cpp | 253 +++++++++++-----------------------------------
- runtime/Server.h | 11 +-
- runtime/pgAdmin4.cpp | 106 ++++++++++---------
- 7 files changed, 149 insertions(+), 271 deletions(-)
-
-diff --git a/runtime/BrowserWindow.cpp b/runtime/BrowserWindow.cpp
-index 516b8689818bddc9..a2ee4895f5351565 100644
---- a/runtime/BrowserWindow.cpp
-+++ b/runtime/BrowserWindow.cpp
-@@ -1286,17 +1286,17 @@ void BrowserWindow::preferences()
-
- ConfigWindow *dlg = new ConfigWindow();
- dlg->setWindowTitle(QWidget::tr("Configuration"));
-- dlg->setPythonPath(settings.value("PythonPath").toString());
-+ dlg->setPythonExecutable(settings.value("PythonExecutable").toString());
- dlg->setApplicationPath(settings.value("ApplicationPath").toString());
- dlg->setModal(true);
- ok = dlg->exec();
-
-- QString pythonpath = dlg->getPythonPath();
-+ QString pythonexecutable = dlg->getPythonExecutable();
- QString applicationpath = dlg->getApplicationPath();
-
- if (ok)
- {
-- settings.setValue("PythonPath", pythonpath);
-+ settings.setValue("PythonExecutable", pythonexecutable);
- settings.setValue("ApplicationPath", applicationpath);
- }
- }
-diff --git a/runtime/ConfigWindow.cpp b/runtime/ConfigWindow.cpp
-index 3fb1a2738eb89ec0..c31345bf08d06d88 100644
---- a/runtime/ConfigWindow.cpp
-+++ b/runtime/ConfigWindow.cpp
-@@ -17,37 +17,45 @@ ConfigWindow::ConfigWindow(QWidget *parent) :
- ui(new Ui::ConfigWindow)
- {
- ui->setupUi(this);
-+
-+#ifdef PYTHON2
-+ ui->pythonExecutableLineEdit->setPlaceholderText(
-+ QString(QWidget::tr("The Python 2 executable to use (may be within a virtual environment)")));
-+#else
-+ ui->pythonExecutableLineEdit->setPlaceholderText(
-+ QString(QWidget::tr("The Python 3 executable to use (may be within a virtual environment)")));
-+#endif
- }
-
- ConfigWindow::~ConfigWindow()
- {
- delete ui;
- }
-
- void ConfigWindow::on_buttonBox_accepted()
- {
- this->close();
- }
-
- void ConfigWindow::on_buttonBox_rejected()
- {
- this->close();
- }
-
--QString ConfigWindow::getPythonPath()
-+QString ConfigWindow::getPythonExecutable()
- {
-- return ui->pythonPathLineEdit->text();
-+ return ui->pythonExecutableLineEdit->text();
- }
-
- QString ConfigWindow::getApplicationPath()
- {
- return ui->applicationPathLineEdit->text();
- }
-
-
--void ConfigWindow::setPythonPath(QString path)
-+void ConfigWindow::setPythonExecutable(QString path)
- {
-- ui->pythonPathLineEdit->setText(path);
-+ ui->pythonExecutableLineEdit->setText(path);
- }
-
- void ConfigWindow::setApplicationPath(QString path)
-diff --git a/runtime/ConfigWindow.h b/runtime/ConfigWindow.h
-index 0027a742aca7b762..c4487fcc6e97f354 100644
---- a/runtime/ConfigWindow.h
-+++ b/runtime/ConfigWindow.h
-@@ -26,19 +26,19 @@ public:
- explicit ConfigWindow(QWidget *parent = 0);
- ~ConfigWindow();
-
-- QString getPythonPath();
-+ QString getPythonExecutable();
- QString getApplicationPath();
-
-- void setPythonPath(QString path);
-+ void setPythonExecutable(QString path);
- void setApplicationPath(QString path);
-
- private slots:
- void on_buttonBox_accepted();
- void on_buttonBox_rejected();
-
- private:
- Ui::ConfigWindow *ui;
-- QString m_pythonpath, m_applicationpath;
-+ QString m_pythonexecutable, m_applicationpath;
- };
-
- #endif // CONFIGWINDOW_H
-diff --git a/runtime/ConfigWindow.ui b/runtime/ConfigWindow.ui
-index 40d87be43803204a..8b379052a1da8cd0 100644
---- a/runtime/ConfigWindow.ui
-+++ b/runtime/ConfigWindow.ui
-@@ -29,24 +29,38 @@
- <enum>QFormLayout::ExpandingFieldsGrow</enum>
- </property>
- <item row="0" column="0">
-- <widget class="QLabel" name="pythonPathLabel">
-+ <widget class="QLabel" name="pythonExecutableLabel">
-+ <property name="sizeIncrement">
-+ <size>
-+ <width>0</width>
-+ <height>1</height>
-+ </size>
-+ </property>
- <property name="text">
-- <string>Python Path</string>
-+ <string>Python Executable</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
-- <widget class="QLineEdit" name="pythonPathLineEdit"/>
-+ <widget class="QLineEdit" name="pythonExecutableLineEdit">
-+ <property name="placeholderText">
-+ <string>The python executable to use (may be within a virtual environment)</string>
-+ </property>
-+ </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="applicationPathLabel">
- <property name="text">
- <string>Application Path</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
-- <widget class="QLineEdit" name="applicationPathLineEdit"/>
-+ <widget class="QLineEdit" name="applicationPathLineEdit">
-+ <property name="placeholderText">
-+ <string>The directory containing pgAdmin4.py (do not include the file name)</string>
-+ </property>
-+ </widget>
- </item>
- </layout>
- </item>
-diff --git a/runtime/Server.cpp b/runtime/Server.cpp
-index 33b43583480440b7..83bcdeedb09197c8 100644
---- a/runtime/Server.cpp
-+++ b/runtime/Server.cpp
-@@ -22,201 +22,85 @@
- // App headers
- #include "Server.h"
-
--static void add_to_path(QString &python_path, QString path, bool prepend=false)
--{
-- if (!python_path.contains(path))
-- {
-- if (!prepend)
-- {
--#if defined(Q_OS_WIN)
-- if (!python_path.isEmpty() && !python_path.endsWith(";"))
-- python_path.append(";");
--#else
-- if (!python_path.isEmpty() && !python_path.endsWith(":"))
-- python_path.append(":");
--#endif
--
-- python_path.append(path);
-- }
-- else
-- {
--#if defined(Q_OS_WIN)
-- if (!python_path.isEmpty() && !python_path.startsWith(";"))
-- python_path.prepend(";");
--#else
-- if (!python_path.isEmpty() && !python_path.startsWith(":"))
-- python_path.prepend(":");
--#endif
--
-- python_path.prepend(path);
-- }
-- }
--}
--
- Server::Server(quint16 port, QString key)
- {
- // Appserver port etc
- m_port = port;
- m_key = key;
-- m_wcAppName = NULL;
-- m_wcPythonHome = NULL;
-
- // Initialise Python
-- Py_NoSiteFlag=1;
-- Py_DontWriteBytecodeFlag=1;
-+ Py_DontWriteBytecodeFlag = 1;
-
-- PGA_APP_NAME_UTF8 = PGA_APP_NAME.toUtf8();
-+ // Get the application directory
-+ QString appDir = qApp->applicationDirPath();
-+
-+ // Build (and canonicalise) the virtual environment path
-+#ifdef Q_OS_MAC
-+ QFileInfo venvBinPath(appDir + "/../Resources/venv/bin");
-+#elif defined(Q_OS_WIN)
-+ QFileInfo venvBinPath(appDir + "/../venv");
-+#else
-+ QFileInfo venvBinPath(appDir + "/../venv/bin");
-+#endif
-+ QString binPath = venvBinPath.canonicalFilePath();
-+
-+ if (binPath.isEmpty())
-+ {
-+ // Use default Python environment from the config, or lastly, PATH
-+ QSettings settings;
-+ binPath.append(settings.value("PythonExecutable").toString());
-+ if (binPath.isEmpty())
-+ binPath.append("python");
-+ }
-+ else
-+ {
-+ binPath.append("/python");
-+ }
-
- // Python3 requires conversion of char * to wchar_t *, so...
- #ifdef PYTHON2
-- Py_SetProgramName(PGA_APP_NAME_UTF8.data());
-+ QByteArray appName = binPath.toLocal8Bit();
-+ m_pyAppName = new char[strlen(appName.data()) + 1];
-+ strcpy(m_pyAppName, appName.data());
-+ qDebug() << "Python interpreter: " << QString::fromLocal8Bit(m_pyAppName);
- #else
-- char *appName = PGA_APP_NAME_UTF8.data();
-- const size_t cSize = strlen(appName)+1;
-- m_wcAppName = new wchar_t[cSize];
-- mbstowcs (m_wcAppName, appName, cSize);
-- Py_SetProgramName(m_wcAppName);
-+ std::wstring appName = binPath.toStdWString();
-+ m_pyAppName = new wchar_t[wcslen(appName.c_str()) + 1];
-+ wcscpy(m_pyAppName, appName.c_str());
-+ qDebug() << "Python interpreter: " << QString::fromWCharArray(m_pyAppName);
- #endif
--
-- // Setup the search path
-- QSettings settings;
-- QString python_path = settings.value("PythonPath").toString();
--
-- // Get the application directory
-- QString app_dir = qApp->applicationDirPath(),
-- path_env = qgetenv("PATH"),
-- pythonHome;
-- QStringList path_list;
-- int i;
--
--#ifdef Q_OS_MAC
-- // In the case we're running in a release appbundle, we need to ensure the
-- // bundled virtual env is included in the Python path. We include it at the
-- // end, so expert users can override the path, but we do not save it, because
-- // if users move the app bundle, we'll end up with dead entries
--
-- // Build (and canonicalise) the virtual environment path
-- QFileInfo venvBinPath(app_dir + "/../Resources/venv/bin");
-- QFileInfo venvLibPath(app_dir + "/../Resources/venv/lib/python");
-- QFileInfo venvDynLibPath(app_dir + "/../Resources/venv/lib/python/lib-dynload");
-- QFileInfo venvSitePackagesPath(app_dir + "/../Resources/venv/lib/python/site-packages");
-- QFileInfo venvPath(app_dir + "/../Resources/venv");
--
-- // Prepend the bin directory to the path
-- add_to_path(path_env, venvBinPath.canonicalFilePath(), true);
-- // Append the path, if it's not already there
-- add_to_path(python_path, venvLibPath.canonicalFilePath());
-- add_to_path(python_path, venvDynLibPath.canonicalFilePath());
-- add_to_path(python_path, venvSitePackagesPath.canonicalFilePath());
-- add_to_path(pythonHome, venvPath.canonicalFilePath());
--#elif defined(Q_OS_WIN)
--
-- // In the case we're running in a release application, we need to ensure the
-- // bundled virtual env is included in the Python path. We include it at the
-- // end, so expert users can override the path, but we do not save it.
--
-- // Build (and canonicalise) the virtual environment path
-- QFileInfo venvBinPath(app_dir + "/../venv");
-- QFileInfo venvLibPath(app_dir + "/../venv/Lib");
-- QFileInfo venvDLLsPath(app_dir + "/../venv/DLLs");
-- QFileInfo venvSitePackagesPath(app_dir + "/../venv/Lib/site-packages");
-- QFileInfo venvPath(app_dir + "/../venv");
--
-- // Prepend the bin directory to the path
-- add_to_path(path_env, venvBinPath.canonicalFilePath(), true);
-- // Append paths, if they're not already there
-- add_to_path(python_path, venvLibPath.canonicalFilePath());
-- add_to_path(python_path, venvDLLsPath.canonicalFilePath());
-- add_to_path(python_path, venvSitePackagesPath.canonicalFilePath());
-- add_to_path(pythonHome, venvPath.canonicalFilePath());
--#else
-- // Build (and canonicalise) the virtual environment path
-- QFileInfo venvBinPath(app_dir + "/../venv/bin");
-- QFileInfo venvLibPath(app_dir + "/../venv/lib/python");
-- QFileInfo venvDynLibPath(app_dir + "/../venv/lib/python/lib-dynload");
-- QFileInfo venvSitePackagesPath(app_dir + "/../venv/lib/python/site-packages");
-- QFileInfo venvPath(app_dir + "/../venv");
--
-- // Prepend the bin directory to the path
-- add_to_path(path_env, venvBinPath.canonicalFilePath(), true);
-- // Append the path, if it's not already there
-- add_to_path(python_path, venvLibPath.canonicalFilePath());
-- add_to_path(python_path, venvDynLibPath.canonicalFilePath());
-- add_to_path(python_path, venvSitePackagesPath.canonicalFilePath());
-- add_to_path(pythonHome, venvPath.canonicalFilePath());
--#endif
--
-- qputenv("PATH", path_env.toUtf8().data());
--
-- if (python_path.length() > 0)
-- {
-- // Split the path setting into individual entries
-- path_list = python_path.split(";", QString::SkipEmptyParts);
-- python_path = QString();
--
-- // Add new additional path elements
-- for (i = path_list.size() - 1; i >= 0 ; --i)
-- {
-- python_path.append(path_list.at(i));
-- if (i > 0)
-- {
--#if defined(Q_OS_WIN)
-- python_path.append(";");
--#else
-- python_path.append(":");
--#endif
-- }
-- }
-- qputenv("PYTHONPATH", python_path.toUtf8().data());
-- }
--
-- qDebug() << "Python path: " << python_path
-- << "\nPython Home: " << pythonHome;
-- if (!pythonHome.isEmpty())
-- {
-- pythonHome_utf8 = pythonHome.toUtf8();
--#ifdef PYTHON2
-- Py_SetPythonHome(pythonHome_utf8.data());
--#else
-- char *python_home = pythonHome_utf8.data();
-- const size_t cSize = strlen(python_home) + 1;
-- m_wcPythonHome = new wchar_t[cSize];
-- mbstowcs (m_wcPythonHome, python_home, cSize);
--
-- Py_SetPythonHome(m_wcPythonHome);
--#endif
-- }
-+ Py_SetProgramName(m_pyAppName);
-
- Py_Initialize();
-
-+ /*
-+ * Untrusted search path vulnerability in the PySys_SetArgv API function in Python 2.6 and earlier, and possibly later
-+ * versions, prepends an empty string to sys.path when the argv[0] argument does not contain a path separator,
-+ * which might allow local users to execute arbitrary code via a Trojan horse Python file in the current working directory.
-+ * Here we have to set arguments explicitly to python interpreter. Check more details in 'PySys_SetArgv' documentation.
-+ */
-+ PySys_SetArgvEx(1, &m_pyAppName, 0);
-+
- // Get the current path
- PyObject* sysPath = PySys_GetObject((char*)"path");
--
-- // Add new additional path elements
-- for (i = path_list.size() - 1; i >= 0 ; --i)
-- {
-+ PyObject* sysPathRepr = PyObject_Repr(sysPath);
- #ifdef PYTHON2
-- PyList_Append(sysPath, PyString_FromString(path_list.at(i).toUtf8().data()));
-+ qDebug() << "Python path: " << QString::fromLocal8Bit(PyString_AsString(sysPathRepr));
- #else
--#if PY_MINOR_VERSION > 2
-- PyList_Append(sysPath, PyUnicode_DecodeFSDefault(path_list.at(i).toUtf8().data()));
--#else
-- PyList_Append(sysPath, PyBytes_FromString(path_list.at(i).toUtf8().data()));
-+ PyObject* sysPathBytes = PyUnicode_AsEncodedString(sysPathRepr, "utf8", "replace");
-+ qDebug() << "Python path: " << QString::fromUtf8(PyBytes_AsString(sysPathBytes));
-+ Py_DECREF(sysPathBytes);
- #endif
--#endif
-- }
-+ Py_DECREF(sysPathRepr);
- }
-
- Server::~Server()
- {
-- if (m_wcAppName)
-- delete m_wcAppName;
--
-- if (m_wcPythonHome)
-- delete m_wcPythonHome;
--
- // Shutdown Python
- Py_Finalize();
-+
-+ if (m_pyAppName)
-+ delete [] m_pyAppName;
- }
-
- bool Server::Init()
-@@ -264,52 +148,29 @@ bool Server::Init()
- void Server::run()
- {
- // Open the application code and run it.
-- FILE *cp = fopen(m_appfile.toUtf8().data(), "r");
-+ QByteArray m_appfile_utf8 = m_appfile.toUtf8();
-+ FILE *cp = fopen(m_appfile_utf8.data(), "r");
- if (!cp)
- {
- setError(QString(tr("Failed to open the application file: %1, server thread exiting.")).arg(m_appfile));
- return;
- }
-
- // Set the port number
- PyRun_SimpleString(QString("PGADMIN_PORT = %1").arg(m_port).toLatin1());
- PyRun_SimpleString(QString("PGADMIN_KEY = '%1'").arg(m_key).toLatin1());
-
- // Run the app!
-- QByteArray m_appfile_utf8 = m_appfile.toUtf8();
- #ifdef PYTHON2
-- /*
-- * Untrusted search path vulnerability in the PySys_SetArgv API function in Python 2.6 and earlier, and possibly later
-- * versions, prepends an empty string to sys.path when the argv[0] argument does not contain a path separator,
-- * which might allow local users to execute arbitrary code via a Trojan horse Python file in the current working directory.
-- * Here we have to set arguments explicitly to python interpreter. Check more details in 'PySys_SetArgv' documentation.
-- */
-- char* n_argv[] = { m_appfile_utf8.data() };
-- PySys_SetArgv(1, n_argv);
--
- PyObject* PyFileObject = PyFile_FromString(m_appfile_utf8.data(), (char *)"r");
- int ret = PyRun_SimpleFile(PyFile_AsFile(PyFileObject), m_appfile_utf8.data());
-- if (ret != 0)
-- setError(tr("Failed to launch the application server, server thread exiting."));
- #else
-- /*
-- * Untrusted search path vulnerability in the PySys_SetArgv API function in Python 2.6 and earlier, and possibly later
-- * versions, prepends an empty string to sys.path when the argv[0] argument does not contain a path separator,
-- * which might allow local users to execute arbitrary code via a Trojan horse Python file in the current working directory.
-- * Here we have to set arguments explicitly to python interpreter. Check more details in 'PySys_SetArgv' documentation.
-- */
-- char *appName = m_appfile_utf8.data();
-- const size_t cSize = strlen(appName)+1;
-- wchar_t* wcAppName = new wchar_t[cSize];
-- mbstowcs (wcAppName, appName, cSize);
-- wchar_t* n_argv[] = { wcAppName };
-- PySys_SetArgv(1, n_argv);
--
- int fd = fileno(cp);
- PyObject* PyFileObject = PyFile_FromFd(fd, m_appfile_utf8.data(), (char *)"r", -1, NULL, NULL,NULL,1);
-- if (PyRun_SimpleFile(fdopen(PyObject_AsFileDescriptor(PyFileObject),"r"), m_appfile_utf8.data()) != 0)
-- setError(tr("Failed to launch the application server, server thread exiting."));
-+ int ret = PyRun_SimpleFile(fdopen(PyObject_AsFileDescriptor(PyFileObject),"r"), m_appfile_utf8.data());
- #endif
-+ if (ret != 0)
-+ setError(tr("Failed to launch the application server, server thread exiting."));
-
- fclose(cp);
- }
-diff --git a/runtime/Server.h b/runtime/Server.h
-index 488f9fcedc6d7dc7..207e2f157db7d7a5 100644
---- a/runtime/Server.h
-+++ b/runtime/Server.h
-@@ -40,12 +40,11 @@ private:
-
- quint16 m_port;
- QString m_key;
-- // Application name in UTF-8 for Python
-- wchar_t *m_wcAppName;
-- QByteArray PGA_APP_NAME_UTF8;
-- // PythonHome for Python
-- wchar_t *m_wcPythonHome;
-- QByteArray pythonHome_utf8;
-+#ifdef PYTHON2
-+ char *m_pyAppName;
-+#else
-+ wchar_t *m_pyAppName;
-+#endif
- };
-
- #endif // SERVER_H
-diff --git a/runtime/pgAdmin4.cpp b/runtime/pgAdmin4.cpp
-index a2dbe7451557befc..ebcb4ff4d4899aaf 100644
---- a/runtime/pgAdmin4.cpp
-+++ b/runtime/pgAdmin4.cpp
-@@ -228,69 +228,65 @@ int main(int argc, char * argv[])
- // Fire up the webserver
- Server *server;
-
-- bool done = false;
-+ server = new Server(port, key);
-
-- while (done != true)
-+ if (!server->Init())
- {
-- server = new Server(port, key);
-+ splash->finish(NULL);
-
-- if (!server->Init())
-+ qDebug() << server->getError();
-+
-+ QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError());
-+ QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
-+
-+ exit(1);
-+ }
-+
-+ server->start();
-+
-+ // This is a hack. Wait a second and then check to see if the server thread
-+ // is still running. If it's not, we probably had a startup error
-+ delay(1000);
-+
-+ // Any errors?
-+ if (server->isFinished() || server->getError().length() > 0)
-+ {
-+ splash->finish(NULL);
-+
-+ qDebug() << server->getError();
-+
-+ QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError());
-+ QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
-+
-+ // Allow the user to tweak the Python Path if needed
-+ QSettings settings;
-+ bool ok;
-+
-+ ConfigWindow *dlg = new ConfigWindow();
-+ dlg->setWindowTitle(QWidget::tr("Configuration"));
-+ dlg->setPythonExecutable(settings.value("PythonExecutable").toString());
-+ dlg->setApplicationPath(settings.value("ApplicationPath").toString());
-+ dlg->setModal(true);
-+ ok = dlg->exec();
-+
-+ QString pythonexecutable = dlg->getPythonExecutable();
-+ QString applicationpath = dlg->getApplicationPath();
-+
-+ if (ok)
- {
-- splash->finish(NULL);
-+ settings.setValue("PythonExecutable", pythonexecutable);
-+ settings.setValue("ApplicationPath", applicationpath);
-+ settings.sync();
-
-- qDebug() << server->getError();
-+ QString msg = QString(QWidget::tr("Please restart the application to allow the changes to take effect."));
-+ QMessageBox::information(NULL, QString(QWidget::tr("Restart")), msg);
-
-- QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError());
-- QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
--
-- exit(1);
-- }
--
-- server->start();
--
-- // This is a hack. Wait a second and then check to see if the server thread
-- // is still running. If it's not, we probably had a startup error
-- delay(1000);
--
-- // Any errors?
-- if (server->isFinished() || server->getError().length() > 0)
-- {
-- splash->finish(NULL);
--
-- qDebug() << server->getError();
--
-- QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError());
-- QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
--
-- // Allow the user to tweak the Python Path if needed
-- QSettings settings;
-- bool ok;
--
-- ConfigWindow *dlg = new ConfigWindow();
-- dlg->setWindowTitle(QWidget::tr("Configuration"));
-- dlg->setPythonPath(settings.value("PythonPath").toString());
-- dlg->setApplicationPath(settings.value("ApplicationPath").toString());
-- dlg->setModal(true);
-- ok = dlg->exec();
--
-- QString pythonpath = dlg->getPythonPath();
-- QString applicationpath = dlg->getApplicationPath();
--
-- if (ok)
-- {
-- settings.setValue("PythonPath", pythonpath);
-- settings.setValue("ApplicationPath", applicationpath);
-- settings.sync();
-- }
-- else
-- {
-- exit(1);
-- }
--
-- delete server;
-+ exit(0);
- }
- else
-- done = true;
-+ {
-+ exit(1);
-+ }
- }
-
-
---
-2.13.0
-
Copied: pgadmin4/repos/community-i686/0001-Simplify-Server-s-python-setup.patch (from rev 238032, pgadmin4/trunk/0001-Simplify-Server-s-python-setup.patch)
===================================================================
--- community-i686/0001-Simplify-Server-s-python-setup.patch (rev 0)
+++ community-i686/0001-Simplify-Server-s-python-setup.patch 2017-06-18 10:59:59 UTC (rev 238033)
@@ -0,0 +1,633 @@
+From a5a1c332e23a094e0c2a1c9513fb9f6b05cbbf05 Mon Sep 17 00:00:00 2001
+From: "Jan Alexander Steffens (heftig)" <jan.steffens at gmail.com>
+Date: Sat, 28 Jan 2017 01:19:06 +0100
+Subject: [PATCH] Simplify Server's python setup
+---
+ runtime/BrowserWindow.cpp | 6 +-
+ runtime/ConfigWindow.cpp | 16 ++-
+ runtime/ConfigWindow.h | 6 +-
+ runtime/ConfigWindow.ui | 22 +++-
+ runtime/Server.cpp | 253 +++++++++++-----------------------------------
+ runtime/Server.h | 11 +-
+ runtime/pgAdmin4.cpp | 106 ++++++++++---------
+ 7 files changed, 149 insertions(+), 271 deletions(-)
+
+diff --git a/runtime/BrowserWindow.cpp b/runtime/BrowserWindow.cpp
+index 516b8689818bddc9..a2ee4895f5351565 100644
+--- a/runtime/BrowserWindow.cpp
++++ b/runtime/BrowserWindow.cpp
+@@ -1286,17 +1286,17 @@ void BrowserWindow::preferences()
+
+ ConfigWindow *dlg = new ConfigWindow();
+ dlg->setWindowTitle(QWidget::tr("Configuration"));
+- dlg->setPythonPath(settings.value("PythonPath").toString());
++ dlg->setPythonExecutable(settings.value("PythonExecutable").toString());
+ dlg->setApplicationPath(settings.value("ApplicationPath").toString());
+ dlg->setModal(true);
+ ok = dlg->exec();
+
+- QString pythonpath = dlg->getPythonPath();
++ QString pythonexecutable = dlg->getPythonExecutable();
+ QString applicationpath = dlg->getApplicationPath();
+
+ if (ok)
+ {
+- settings.setValue("PythonPath", pythonpath);
++ settings.setValue("PythonExecutable", pythonexecutable);
+ settings.setValue("ApplicationPath", applicationpath);
+ }
+ }
+diff --git a/runtime/ConfigWindow.cpp b/runtime/ConfigWindow.cpp
+index 3fb1a2738eb89ec0..c31345bf08d06d88 100644
+--- a/runtime/ConfigWindow.cpp
++++ b/runtime/ConfigWindow.cpp
+@@ -17,37 +17,45 @@ ConfigWindow::ConfigWindow(QWidget *parent) :
+ ui(new Ui::ConfigWindow)
+ {
+ ui->setupUi(this);
++
++#ifdef PYTHON2
++ ui->pythonExecutableLineEdit->setPlaceholderText(
++ QString(QWidget::tr("The Python 2 executable to use (may be within a virtual environment)")));
++#else
++ ui->pythonExecutableLineEdit->setPlaceholderText(
++ QString(QWidget::tr("The Python 3 executable to use (may be within a virtual environment)")));
++#endif
+ }
+
+ ConfigWindow::~ConfigWindow()
+ {
+ delete ui;
+ }
+
+ void ConfigWindow::on_buttonBox_accepted()
+ {
+ this->close();
+ }
+
+ void ConfigWindow::on_buttonBox_rejected()
+ {
+ this->close();
+ }
+
+-QString ConfigWindow::getPythonPath()
++QString ConfigWindow::getPythonExecutable()
+ {
+- return ui->pythonPathLineEdit->text();
++ return ui->pythonExecutableLineEdit->text();
+ }
+
+ QString ConfigWindow::getApplicationPath()
+ {
+ return ui->applicationPathLineEdit->text();
+ }
+
+
+-void ConfigWindow::setPythonPath(QString path)
++void ConfigWindow::setPythonExecutable(QString path)
+ {
+- ui->pythonPathLineEdit->setText(path);
++ ui->pythonExecutableLineEdit->setText(path);
+ }
+
+ void ConfigWindow::setApplicationPath(QString path)
+diff --git a/runtime/ConfigWindow.h b/runtime/ConfigWindow.h
+index 0027a742aca7b762..c4487fcc6e97f354 100644
+--- a/runtime/ConfigWindow.h
++++ b/runtime/ConfigWindow.h
+@@ -26,19 +26,19 @@ public:
+ explicit ConfigWindow(QWidget *parent = 0);
+ ~ConfigWindow();
+
+- QString getPythonPath();
++ QString getPythonExecutable();
+ QString getApplicationPath();
+
+- void setPythonPath(QString path);
++ void setPythonExecutable(QString path);
+ void setApplicationPath(QString path);
+
+ private slots:
+ void on_buttonBox_accepted();
+ void on_buttonBox_rejected();
+
+ private:
+ Ui::ConfigWindow *ui;
+- QString m_pythonpath, m_applicationpath;
++ QString m_pythonexecutable, m_applicationpath;
+ };
+
+ #endif // CONFIGWINDOW_H
+diff --git a/runtime/ConfigWindow.ui b/runtime/ConfigWindow.ui
+index 40d87be43803204a..8b379052a1da8cd0 100644
+--- a/runtime/ConfigWindow.ui
++++ b/runtime/ConfigWindow.ui
+@@ -29,24 +29,38 @@
+ <enum>QFormLayout::ExpandingFieldsGrow</enum>
+ </property>
+ <item row="0" column="0">
+- <widget class="QLabel" name="pythonPathLabel">
++ <widget class="QLabel" name="pythonExecutableLabel">
++ <property name="sizeIncrement">
++ <size>
++ <width>0</width>
++ <height>1</height>
++ </size>
++ </property>
+ <property name="text">
+- <string>Python Path</string>
++ <string>Python Executable</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+- <widget class="QLineEdit" name="pythonPathLineEdit"/>
++ <widget class="QLineEdit" name="pythonExecutableLineEdit">
++ <property name="placeholderText">
++ <string>The python executable to use (may be within a virtual environment)</string>
++ </property>
++ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="applicationPathLabel">
+ <property name="text">
+ <string>Application Path</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+- <widget class="QLineEdit" name="applicationPathLineEdit"/>
++ <widget class="QLineEdit" name="applicationPathLineEdit">
++ <property name="placeholderText">
++ <string>The directory containing pgAdmin4.py (do not include the file name)</string>
++ </property>
++ </widget>
+ </item>
+ </layout>
+ </item>
+diff --git a/runtime/Server.cpp b/runtime/Server.cpp
+index 33b43583480440b7..83bcdeedb09197c8 100644
+--- a/runtime/Server.cpp
++++ b/runtime/Server.cpp
+@@ -22,201 +22,85 @@
+ // App headers
+ #include "Server.h"
+
+-static void add_to_path(QString &python_path, QString path, bool prepend=false)
+-{
+- if (!python_path.contains(path))
+- {
+- if (!prepend)
+- {
+-#if defined(Q_OS_WIN)
+- if (!python_path.isEmpty() && !python_path.endsWith(";"))
+- python_path.append(";");
+-#else
+- if (!python_path.isEmpty() && !python_path.endsWith(":"))
+- python_path.append(":");
+-#endif
+-
+- python_path.append(path);
+- }
+- else
+- {
+-#if defined(Q_OS_WIN)
+- if (!python_path.isEmpty() && !python_path.startsWith(";"))
+- python_path.prepend(";");
+-#else
+- if (!python_path.isEmpty() && !python_path.startsWith(":"))
+- python_path.prepend(":");
+-#endif
+-
+- python_path.prepend(path);
+- }
+- }
+-}
+-
+ Server::Server(quint16 port, QString key)
+ {
+ // Appserver port etc
+ m_port = port;
+ m_key = key;
+- m_wcAppName = NULL;
+- m_wcPythonHome = NULL;
+
+ // Initialise Python
+- Py_NoSiteFlag=1;
+- Py_DontWriteBytecodeFlag=1;
++ Py_DontWriteBytecodeFlag = 1;
+
+- PGA_APP_NAME_UTF8 = PGA_APP_NAME.toUtf8();
++ // Get the application directory
++ QString appDir = qApp->applicationDirPath();
++
++ // Build (and canonicalise) the virtual environment path
++#ifdef Q_OS_MAC
++ QFileInfo venvBinPath(appDir + "/../Resources/venv/bin");
++#elif defined(Q_OS_WIN)
++ QFileInfo venvBinPath(appDir + "/../venv");
++#else
++ QFileInfo venvBinPath(appDir + "/../venv/bin");
++#endif
++ QString binPath = venvBinPath.canonicalFilePath();
++
++ if (binPath.isEmpty())
++ {
++ // Use default Python environment from the config, or lastly, PATH
++ QSettings settings;
++ binPath.append(settings.value("PythonExecutable").toString());
++ if (binPath.isEmpty())
++ binPath.append("python");
++ }
++ else
++ {
++ binPath.append("/python");
++ }
+
+ // Python3 requires conversion of char * to wchar_t *, so...
+ #ifdef PYTHON2
+- Py_SetProgramName(PGA_APP_NAME_UTF8.data());
++ QByteArray appName = binPath.toLocal8Bit();
++ m_pyAppName = new char[strlen(appName.data()) + 1];
++ strcpy(m_pyAppName, appName.data());
++ qDebug() << "Python interpreter: " << QString::fromLocal8Bit(m_pyAppName);
+ #else
+- char *appName = PGA_APP_NAME_UTF8.data();
+- const size_t cSize = strlen(appName)+1;
+- m_wcAppName = new wchar_t[cSize];
+- mbstowcs (m_wcAppName, appName, cSize);
+- Py_SetProgramName(m_wcAppName);
++ std::wstring appName = binPath.toStdWString();
++ m_pyAppName = new wchar_t[wcslen(appName.c_str()) + 1];
++ wcscpy(m_pyAppName, appName.c_str());
++ qDebug() << "Python interpreter: " << QString::fromWCharArray(m_pyAppName);
+ #endif
+-
+- // Setup the search path
+- QSettings settings;
+- QString python_path = settings.value("PythonPath").toString();
+-
+- // Get the application directory
+- QString app_dir = qApp->applicationDirPath(),
+- path_env = qgetenv("PATH"),
+- pythonHome;
+- QStringList path_list;
+- int i;
+-
+-#ifdef Q_OS_MAC
+- // In the case we're running in a release appbundle, we need to ensure the
+- // bundled virtual env is included in the Python path. We include it at the
+- // end, so expert users can override the path, but we do not save it, because
+- // if users move the app bundle, we'll end up with dead entries
+-
+- // Build (and canonicalise) the virtual environment path
+- QFileInfo venvBinPath(app_dir + "/../Resources/venv/bin");
+- QFileInfo venvLibPath(app_dir + "/../Resources/venv/lib/python");
+- QFileInfo venvDynLibPath(app_dir + "/../Resources/venv/lib/python/lib-dynload");
+- QFileInfo venvSitePackagesPath(app_dir + "/../Resources/venv/lib/python/site-packages");
+- QFileInfo venvPath(app_dir + "/../Resources/venv");
+-
+- // Prepend the bin directory to the path
+- add_to_path(path_env, venvBinPath.canonicalFilePath(), true);
+- // Append the path, if it's not already there
+- add_to_path(python_path, venvLibPath.canonicalFilePath());
+- add_to_path(python_path, venvDynLibPath.canonicalFilePath());
+- add_to_path(python_path, venvSitePackagesPath.canonicalFilePath());
+- add_to_path(pythonHome, venvPath.canonicalFilePath());
+-#elif defined(Q_OS_WIN)
+-
+- // In the case we're running in a release application, we need to ensure the
+- // bundled virtual env is included in the Python path. We include it at the
+- // end, so expert users can override the path, but we do not save it.
+-
+- // Build (and canonicalise) the virtual environment path
+- QFileInfo venvBinPath(app_dir + "/../venv");
+- QFileInfo venvLibPath(app_dir + "/../venv/Lib");
+- QFileInfo venvDLLsPath(app_dir + "/../venv/DLLs");
+- QFileInfo venvSitePackagesPath(app_dir + "/../venv/Lib/site-packages");
+- QFileInfo venvPath(app_dir + "/../venv");
+-
+- // Prepend the bin directory to the path
+- add_to_path(path_env, venvBinPath.canonicalFilePath(), true);
+- // Append paths, if they're not already there
+- add_to_path(python_path, venvLibPath.canonicalFilePath());
+- add_to_path(python_path, venvDLLsPath.canonicalFilePath());
+- add_to_path(python_path, venvSitePackagesPath.canonicalFilePath());
+- add_to_path(pythonHome, venvPath.canonicalFilePath());
+-#else
+- // Build (and canonicalise) the virtual environment path
+- QFileInfo venvBinPath(app_dir + "/../venv/bin");
+- QFileInfo venvLibPath(app_dir + "/../venv/lib/python");
+- QFileInfo venvDynLibPath(app_dir + "/../venv/lib/python/lib-dynload");
+- QFileInfo venvSitePackagesPath(app_dir + "/../venv/lib/python/site-packages");
+- QFileInfo venvPath(app_dir + "/../venv");
+-
+- // Prepend the bin directory to the path
+- add_to_path(path_env, venvBinPath.canonicalFilePath(), true);
+- // Append the path, if it's not already there
+- add_to_path(python_path, venvLibPath.canonicalFilePath());
+- add_to_path(python_path, venvDynLibPath.canonicalFilePath());
+- add_to_path(python_path, venvSitePackagesPath.canonicalFilePath());
+- add_to_path(pythonHome, venvPath.canonicalFilePath());
+-#endif
+-
+- qputenv("PATH", path_env.toUtf8().data());
+-
+- if (python_path.length() > 0)
+- {
+- // Split the path setting into individual entries
+- path_list = python_path.split(";", QString::SkipEmptyParts);
+- python_path = QString();
+-
+- // Add new additional path elements
+- for (i = path_list.size() - 1; i >= 0 ; --i)
+- {
+- python_path.append(path_list.at(i));
+- if (i > 0)
+- {
+-#if defined(Q_OS_WIN)
+- python_path.append(";");
+-#else
+- python_path.append(":");
+-#endif
+- }
+- }
+- qputenv("PYTHONPATH", python_path.toUtf8().data());
+- }
+-
+- qDebug() << "Python path: " << python_path
+- << "\nPython Home: " << pythonHome;
+- if (!pythonHome.isEmpty())
+- {
+- pythonHome_utf8 = pythonHome.toUtf8();
+-#ifdef PYTHON2
+- Py_SetPythonHome(pythonHome_utf8.data());
+-#else
+- char *python_home = pythonHome_utf8.data();
+- const size_t cSize = strlen(python_home) + 1;
+- m_wcPythonHome = new wchar_t[cSize];
+- mbstowcs (m_wcPythonHome, python_home, cSize);
+-
+- Py_SetPythonHome(m_wcPythonHome);
+-#endif
+- }
++ Py_SetProgramName(m_pyAppName);
+
+ Py_Initialize();
+
++ /*
++ * Untrusted search path vulnerability in the PySys_SetArgv API function in Python 2.6 and earlier, and possibly later
++ * versions, prepends an empty string to sys.path when the argv[0] argument does not contain a path separator,
++ * which might allow local users to execute arbitrary code via a Trojan horse Python file in the current working directory.
++ * Here we have to set arguments explicitly to python interpreter. Check more details in 'PySys_SetArgv' documentation.
++ */
++ PySys_SetArgvEx(1, &m_pyAppName, 0);
++
+ // Get the current path
+ PyObject* sysPath = PySys_GetObject((char*)"path");
+-
+- // Add new additional path elements
+- for (i = path_list.size() - 1; i >= 0 ; --i)
+- {
++ PyObject* sysPathRepr = PyObject_Repr(sysPath);
+ #ifdef PYTHON2
+- PyList_Append(sysPath, PyString_FromString(path_list.at(i).toUtf8().data()));
++ qDebug() << "Python path: " << QString::fromLocal8Bit(PyString_AsString(sysPathRepr));
+ #else
+-#if PY_MINOR_VERSION > 2
+- PyList_Append(sysPath, PyUnicode_DecodeFSDefault(path_list.at(i).toUtf8().data()));
+-#else
+- PyList_Append(sysPath, PyBytes_FromString(path_list.at(i).toUtf8().data()));
++ PyObject* sysPathBytes = PyUnicode_AsEncodedString(sysPathRepr, "utf8", "replace");
++ qDebug() << "Python path: " << QString::fromUtf8(PyBytes_AsString(sysPathBytes));
++ Py_DECREF(sysPathBytes);
+ #endif
+-#endif
+- }
++ Py_DECREF(sysPathRepr);
+ }
+
+ Server::~Server()
+ {
+- if (m_wcAppName)
+- delete m_wcAppName;
+-
+- if (m_wcPythonHome)
+- delete m_wcPythonHome;
+-
+ // Shutdown Python
+ Py_Finalize();
++
++ if (m_pyAppName)
++ delete [] m_pyAppName;
+ }
+
+ bool Server::Init()
+@@ -264,52 +148,29 @@ bool Server::Init()
+ void Server::run()
+ {
+ // Open the application code and run it.
+- FILE *cp = fopen(m_appfile.toUtf8().data(), "r");
++ QByteArray m_appfile_utf8 = m_appfile.toUtf8();
++ FILE *cp = fopen(m_appfile_utf8.data(), "r");
+ if (!cp)
+ {
+ setError(QString(tr("Failed to open the application file: %1, server thread exiting.")).arg(m_appfile));
+ return;
+ }
+
+ // Set the port number
+ PyRun_SimpleString(QString("PGADMIN_PORT = %1").arg(m_port).toLatin1());
+ PyRun_SimpleString(QString("PGADMIN_KEY = '%1'").arg(m_key).toLatin1());
+
+ // Run the app!
+- QByteArray m_appfile_utf8 = m_appfile.toUtf8();
+ #ifdef PYTHON2
+- /*
+- * Untrusted search path vulnerability in the PySys_SetArgv API function in Python 2.6 and earlier, and possibly later
+- * versions, prepends an empty string to sys.path when the argv[0] argument does not contain a path separator,
+- * which might allow local users to execute arbitrary code via a Trojan horse Python file in the current working directory.
+- * Here we have to set arguments explicitly to python interpreter. Check more details in 'PySys_SetArgv' documentation.
+- */
+- char* n_argv[] = { m_appfile_utf8.data() };
+- PySys_SetArgv(1, n_argv);
+-
+ PyObject* PyFileObject = PyFile_FromString(m_appfile_utf8.data(), (char *)"r");
+ int ret = PyRun_SimpleFile(PyFile_AsFile(PyFileObject), m_appfile_utf8.data());
+- if (ret != 0)
+- setError(tr("Failed to launch the application server, server thread exiting."));
+ #else
+- /*
+- * Untrusted search path vulnerability in the PySys_SetArgv API function in Python 2.6 and earlier, and possibly later
+- * versions, prepends an empty string to sys.path when the argv[0] argument does not contain a path separator,
+- * which might allow local users to execute arbitrary code via a Trojan horse Python file in the current working directory.
+- * Here we have to set arguments explicitly to python interpreter. Check more details in 'PySys_SetArgv' documentation.
+- */
+- char *appName = m_appfile_utf8.data();
+- const size_t cSize = strlen(appName)+1;
+- wchar_t* wcAppName = new wchar_t[cSize];
+- mbstowcs (wcAppName, appName, cSize);
+- wchar_t* n_argv[] = { wcAppName };
+- PySys_SetArgv(1, n_argv);
+-
+ int fd = fileno(cp);
+ PyObject* PyFileObject = PyFile_FromFd(fd, m_appfile_utf8.data(), (char *)"r", -1, NULL, NULL,NULL,1);
+- if (PyRun_SimpleFile(fdopen(PyObject_AsFileDescriptor(PyFileObject),"r"), m_appfile_utf8.data()) != 0)
+- setError(tr("Failed to launch the application server, server thread exiting."));
++ int ret = PyRun_SimpleFile(fdopen(PyObject_AsFileDescriptor(PyFileObject),"r"), m_appfile_utf8.data());
+ #endif
++ if (ret != 0)
++ setError(tr("Failed to launch the application server, server thread exiting."));
+
+ fclose(cp);
+ }
+diff --git a/runtime/Server.h b/runtime/Server.h
+index 488f9fcedc6d7dc7..207e2f157db7d7a5 100644
+--- a/runtime/Server.h
++++ b/runtime/Server.h
+@@ -40,12 +40,11 @@ private:
+
+ quint16 m_port;
+ QString m_key;
+- // Application name in UTF-8 for Python
+- wchar_t *m_wcAppName;
+- QByteArray PGA_APP_NAME_UTF8;
+- // PythonHome for Python
+- wchar_t *m_wcPythonHome;
+- QByteArray pythonHome_utf8;
++#ifdef PYTHON2
++ char *m_pyAppName;
++#else
++ wchar_t *m_pyAppName;
++#endif
+ };
+
+ #endif // SERVER_H
+diff --git a/runtime/pgAdmin4.cpp b/runtime/pgAdmin4.cpp
+index a2dbe7451557befc..ebcb4ff4d4899aaf 100644
+--- a/runtime/pgAdmin4.cpp
++++ b/runtime/pgAdmin4.cpp
+@@ -228,69 +228,65 @@ int main(int argc, char * argv[])
+ // Fire up the webserver
+ Server *server;
+
+- bool done = false;
++ server = new Server(port, key);
+
+- while (done != true)
++ if (!server->Init())
+ {
+- server = new Server(port, key);
++ splash->finish(NULL);
+
+- if (!server->Init())
++ qDebug() << server->getError();
++
++ QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError());
++ QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
++
++ exit(1);
++ }
++
++ server->start();
++
++ // This is a hack. Wait a second and then check to see if the server thread
++ // is still running. If it's not, we probably had a startup error
++ delay(1000);
++
++ // Any errors?
++ if (server->isFinished() || server->getError().length() > 0)
++ {
++ splash->finish(NULL);
++
++ qDebug() << server->getError();
++
++ QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError());
++ QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
++
++ // Allow the user to tweak the Python Path if needed
++ QSettings settings;
++ bool ok;
++
++ ConfigWindow *dlg = new ConfigWindow();
++ dlg->setWindowTitle(QWidget::tr("Configuration"));
++ dlg->setPythonExecutable(settings.value("PythonExecutable").toString());
++ dlg->setApplicationPath(settings.value("ApplicationPath").toString());
++ dlg->setModal(true);
++ ok = dlg->exec();
++
++ QString pythonexecutable = dlg->getPythonExecutable();
++ QString applicationpath = dlg->getApplicationPath();
++
++ if (ok)
+ {
+- splash->finish(NULL);
++ settings.setValue("PythonExecutable", pythonexecutable);
++ settings.setValue("ApplicationPath", applicationpath);
++ settings.sync();
+
+- qDebug() << server->getError();
++ QString msg = QString(QWidget::tr("Please restart the application to allow the changes to take effect."));
++ QMessageBox::information(NULL, QString(QWidget::tr("Restart")), msg);
+
+- QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError());
+- QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
+-
+- exit(1);
+- }
+-
+- server->start();
+-
+- // This is a hack. Wait a second and then check to see if the server thread
+- // is still running. If it's not, we probably had a startup error
+- delay(1000);
+-
+- // Any errors?
+- if (server->isFinished() || server->getError().length() > 0)
+- {
+- splash->finish(NULL);
+-
+- qDebug() << server->getError();
+-
+- QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError());
+- QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
+-
+- // Allow the user to tweak the Python Path if needed
+- QSettings settings;
+- bool ok;
+-
+- ConfigWindow *dlg = new ConfigWindow();
+- dlg->setWindowTitle(QWidget::tr("Configuration"));
+- dlg->setPythonPath(settings.value("PythonPath").toString());
+- dlg->setApplicationPath(settings.value("ApplicationPath").toString());
+- dlg->setModal(true);
+- ok = dlg->exec();
+-
+- QString pythonpath = dlg->getPythonPath();
+- QString applicationpath = dlg->getApplicationPath();
+-
+- if (ok)
+- {
+- settings.setValue("PythonPath", pythonpath);
+- settings.setValue("ApplicationPath", applicationpath);
+- settings.sync();
+- }
+- else
+- {
+- exit(1);
+- }
+-
+- delete server;
++ exit(0);
+ }
+ else
+- done = true;
++ {
++ exit(1);
++ }
+ }
+
+
+--
+2.13.0
+
Deleted: community-i686/PKGBUILD
===================================================================
--- community-i686/PKGBUILD 2017-06-18 10:59:49 UTC (rev 238032)
+++ community-i686/PKGBUILD 2017-06-18 10:59:59 UTC (rev 238033)
@@ -1,84 +0,0 @@
-# $Id$
-# Maintainer: Jerome Leclanche <jerome at leclan.ch>
-
-pkgname=pgadmin4
-pkgver=1.5
-pkgrel=2
-pkgdesc="Comprehensive design and management interface for PostgreSQL"
-arch=("i686" "x86_64")
-url="https://www.pgadmin.org/"
-license=("custom")
-depends=("qt5-webengine" "python" "postgresql-libs" "hicolor-icon-theme")
-makedepends=("python-setuptools" "imagemagick")
-source=(
- "https://ftp.postgresql.org/pub/pgadmin/pgadmin4/v$pkgver/source/$pkgname-$pkgver.tar.gz"{,.sig}
- "pgAdmin4.desktop"
- "config_distro.py"
- "config_local.py"
- # https://www.postgresql.org/message-id/CAMQ-g0dHUN2SFioNg93hCTJkRR3LsVZ-ZvhUh6in%2BO4UAU2Qow%40mail.gmail.com
- "0001-Simplify-Server-s-python-setup.patch"
-)
-sha256sums=(
- "a814d926e9af046ff8ebaf968ec37da8f26ba012de2bff655630703ed2c6bf5c"
- "SKIP"
- "9a39a321fa5a7fcf4f7f7abf6872de6de537800212e9f6f4902ed37b806765b7"
- "510c11bf26fa335548ec4c582bc9f5a5242b8e03f3cb0b7c19e6bfd12b6d663c"
- "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
- "f6a3268c0a4b88d6c06d6c92e307dece1f2e3d2ab9d80339395f525cbf23c93e"
-)
-validpgpkeys=(
- "E0C4CEEB826B1FDA4FB468E024ADFAAF698F1519"
-)
-
-
-prepare() {
- cd "$pkgname-$pkgver"
- patch -Np1 -i "../0001-Simplify-Server-s-python-setup.patch"
- convert runtime/pgAdmin4.{ico,png}
-
- _venv="$srcdir/$pkgname-$pkgver/venv"
- /usr/bin/python -m venv "$_venv"
- "$_venv/bin/python" -m pip install -r "$srcdir/$pkgname-$pkgver/requirements.txt"
- "$_venv/bin/python" -m pip install sphinx # building docs
-}
-
-
-build() {
- export LANG=en_US.UTF-8
- export LC_ALL=en_US.UTF-8
-
- cd "$pkgname-$pkgver/runtime"
- qmake CONFIG+=release
- make
-
- PATH="$_venv/bin:$PATH" make -C "$srcdir/$pkgname-$pkgver" docs
-}
-
-
-package() {
- cd "$pkgname-$pkgver"
-
- install -D runtime/pgAdmin4 "$pkgdir/usr/lib/pgadmin4/runtime/pgAdmin4"
-
- cp -a docs web "$pkgdir/usr/lib/pgadmin4"
- cp -a venv "$pkgdir/usr/lib/pgadmin4/venv"
-
- install -Dm644 "$srcdir/config_distro.py" "$pkgdir/usr/lib/pgadmin4/web/config_distro.py"
- install -Dm644 "$srcdir/config_local.py" "$pkgdir/usr/lib/pgadmin4/web/config_distro.py"
-
- ### Launcher
-
- install -Dm644 runtime/pgAdmin4-0.png "$pkgdir/usr/share/icons/hicolor/256x256/apps/pgAdmin4.png"
- install -Dm644 runtime/pgAdmin4-1.png "$pkgdir/usr/share/icons/hicolor/48x48/apps/pgAdmin4.png"
- install -Dm644 runtime/pgAdmin4-2.png "$pkgdir/usr/share/icons/hicolor/32x32/apps/pgAdmin4.png"
- install -Dm644 runtime/pgAdmin4-3.png "$pkgdir/usr/share/icons/hicolor/16x16/apps/pgAdmin4.png"
-
- install -Dm644 "$srcdir/pgAdmin4.desktop" "$pkgdir/usr/share/applications/pgAdmin4.desktop"
-
- install -D /dev/stdin "$pkgdir/usr/bin/pgadmin4" <<END
-#!/bin/sh
-exec /usr/lib/pgadmin4/runtime/pgAdmin4 "\$@"
-END
-
- install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
-}
Copied: pgadmin4/repos/community-i686/PKGBUILD (from rev 238032, pgadmin4/trunk/PKGBUILD)
===================================================================
--- community-i686/PKGBUILD (rev 0)
+++ community-i686/PKGBUILD 2017-06-18 10:59:59 UTC (rev 238033)
@@ -0,0 +1,86 @@
+# $Id$
+# Maintainer: Jerome Leclanche <jerome at leclan.ch>
+
+pkgname=pgadmin4
+pkgver=1.5
+pkgrel=3
+pkgdesc="Comprehensive design and management interface for PostgreSQL"
+arch=("i686" "x86_64")
+url="https://www.pgadmin.org/"
+license=("custom")
+depends=("qt5-webengine" "python" "postgresql-libs" "hicolor-icon-theme")
+makedepends=("python-setuptools" "imagemagick")
+source=(
+ "https://ftp.postgresql.org/pub/pgadmin/pgadmin4/v$pkgver/source/$pkgname-$pkgver.tar.gz"{,.sig}
+ "pgAdmin4.desktop"
+ "config_distro.py"
+ "config_local.py"
+ # https://www.postgresql.org/message-id/CAMQ-g0dHUN2SFioNg93hCTJkRR3LsVZ-ZvhUh6in%2BO4UAU2Qow%40mail.gmail.com
+ "0001-Simplify-Server-s-python-setup.patch"
+)
+sha256sums=(
+ "a814d926e9af046ff8ebaf968ec37da8f26ba012de2bff655630703ed2c6bf5c"
+ "SKIP"
+ "9a39a321fa5a7fcf4f7f7abf6872de6de537800212e9f6f4902ed37b806765b7"
+ "510c11bf26fa335548ec4c582bc9f5a5242b8e03f3cb0b7c19e6bfd12b6d663c"
+ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ "f6a3268c0a4b88d6c06d6c92e307dece1f2e3d2ab9d80339395f525cbf23c93e"
+)
+validpgpkeys=(
+ "E0C4CEEB826B1FDA4FB468E024ADFAAF698F1519"
+)
+
+
+prepare() {
+ cd "$pkgname-$pkgver"
+ patch -Np1 -i "../0001-Simplify-Server-s-python-setup.patch"
+ convert runtime/pgAdmin4.{ico,png}
+
+ /usr/bin/python -m venv "$srcdir/$pkgname-$pkgver/venv"
+ "$srcdir/$pkgname-$pkgver/venv/bin/python" -m pip install -r "$srcdir/$pkgname-$pkgver/requirements.txt"
+
+ /usr/bin/python -m venv "$srcdir/$pkgname-$pkgver/venv-docs"
+ "$srcdir/$pkgname-$pkgver/venv-docs/bin/python" -m pip install -r "$srcdir/$pkgname-$pkgver/requirements.txt"
+ "$srcdir/$pkgname-$pkgver/venv-docs/bin/python" -m pip install sphinx
+}
+
+
+build() {
+ export LANG=en_US.UTF-8
+ export LC_ALL=en_US.UTF-8
+
+ cd "$pkgname-$pkgver/runtime"
+ qmake CONFIG+=release
+ make
+
+ PATH="$srcdir/$pkgname-$pkgver/venv-docs/bin:$PATH" make -C "$srcdir/$pkgname-$pkgver" docs
+}
+
+
+package() {
+ cd "$pkgname-$pkgver"
+
+ install -D runtime/pgAdmin4 "$pkgdir/usr/lib/pgadmin4/runtime/pgAdmin4"
+
+ cp -a docs web "$pkgdir/usr/lib/pgadmin4"
+ cp -a venv "$pkgdir/usr/lib/pgadmin4/venv"
+
+ install -Dm644 "$srcdir/config_distro.py" "$pkgdir/usr/lib/pgadmin4/web/config_distro.py"
+ install -Dm644 "$srcdir/config_local.py" "$pkgdir/usr/lib/pgadmin4/web/config_local.py"
+
+ ### Launcher
+
+ install -Dm644 runtime/pgAdmin4-0.png "$pkgdir/usr/share/icons/hicolor/256x256/apps/pgAdmin4.png"
+ install -Dm644 runtime/pgAdmin4-1.png "$pkgdir/usr/share/icons/hicolor/48x48/apps/pgAdmin4.png"
+ install -Dm644 runtime/pgAdmin4-2.png "$pkgdir/usr/share/icons/hicolor/32x32/apps/pgAdmin4.png"
+ install -Dm644 runtime/pgAdmin4-3.png "$pkgdir/usr/share/icons/hicolor/16x16/apps/pgAdmin4.png"
+
+ install -Dm644 "$srcdir/pgAdmin4.desktop" "$pkgdir/usr/share/applications/pgAdmin4.desktop"
+
+ install -D /dev/stdin "$pkgdir/usr/bin/pgadmin4" <<END
+#!/bin/sh
+exec /usr/lib/pgadmin4/runtime/pgAdmin4 "\$@"
+END
+
+ install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
+}
Deleted: community-i686/config_distro.py
===================================================================
--- community-i686/config_distro.py 2017-06-18 10:59:49 UTC (rev 238032)
+++ community-i686/config_distro.py 2017-06-18 10:59:59 UTC (rev 238033)
@@ -1,2 +0,0 @@
-SERVER_MODE = False
-HELP_PATH = "/usr/lib/pgadmin4/docs/en_US/_build/html/"
Copied: pgadmin4/repos/community-i686/config_distro.py (from rev 238032, pgadmin4/trunk/config_distro.py)
===================================================================
--- community-i686/config_distro.py (rev 0)
+++ community-i686/config_distro.py 2017-06-18 10:59:59 UTC (rev 238033)
@@ -0,0 +1,2 @@
+SERVER_MODE = False
+HELP_PATH = "/usr/lib/pgadmin4/docs/en_US/_build/html/"
Deleted: community-i686/config_local.py
===================================================================
Copied: pgadmin4/repos/community-i686/config_local.py (from rev 238032, pgadmin4/trunk/config_local.py)
===================================================================
Deleted: community-i686/pgAdmin4.desktop
===================================================================
--- community-i686/pgAdmin4.desktop 2017-06-18 10:59:49 UTC (rev 238032)
+++ community-i686/pgAdmin4.desktop 2017-06-18 10:59:59 UTC (rev 238033)
@@ -1,11 +0,0 @@
-[Desktop Entry]
-Encoding=UTF-8
-Name=pgAdmin 4
-Exec=/usr/lib/pgadmin4/runtime/pgAdmin4
-Icon=pgAdmin4
-Type=Application
-Categories=Application;Development;
-MimeType=text/html
-DocPath=/usr/lib/pgadmin4/docs/en_US/_build/html/index.html
-Comment=PostgreSQL Tools
-Keywords=database;db;sql;query;administration;development;
Copied: pgadmin4/repos/community-i686/pgAdmin4.desktop (from rev 238032, pgadmin4/trunk/pgAdmin4.desktop)
===================================================================
--- community-i686/pgAdmin4.desktop (rev 0)
+++ community-i686/pgAdmin4.desktop 2017-06-18 10:59:59 UTC (rev 238033)
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Name=pgAdmin 4
+Exec=/usr/lib/pgadmin4/runtime/pgAdmin4
+Icon=pgAdmin4
+Type=Application
+Categories=Application;Development;
+MimeType=text/html
+DocPath=/usr/lib/pgadmin4/docs/en_US/_build/html/index.html
+Comment=PostgreSQL Tools
+Keywords=database;db;sql;query;administration;development;
Deleted: community-x86_64/0001-Simplify-Server-s-python-setup.patch
===================================================================
--- community-x86_64/0001-Simplify-Server-s-python-setup.patch 2017-06-18 10:59:49 UTC (rev 238032)
+++ community-x86_64/0001-Simplify-Server-s-python-setup.patch 2017-06-18 10:59:59 UTC (rev 238033)
@@ -1,633 +0,0 @@
-From a5a1c332e23a094e0c2a1c9513fb9f6b05cbbf05 Mon Sep 17 00:00:00 2001
-From: "Jan Alexander Steffens (heftig)" <jan.steffens at gmail.com>
-Date: Sat, 28 Jan 2017 01:19:06 +0100
-Subject: [PATCH] Simplify Server's python setup
----
- runtime/BrowserWindow.cpp | 6 +-
- runtime/ConfigWindow.cpp | 16 ++-
- runtime/ConfigWindow.h | 6 +-
- runtime/ConfigWindow.ui | 22 +++-
- runtime/Server.cpp | 253 +++++++++++-----------------------------------
- runtime/Server.h | 11 +-
- runtime/pgAdmin4.cpp | 106 ++++++++++---------
- 7 files changed, 149 insertions(+), 271 deletions(-)
-
-diff --git a/runtime/BrowserWindow.cpp b/runtime/BrowserWindow.cpp
-index 516b8689818bddc9..a2ee4895f5351565 100644
---- a/runtime/BrowserWindow.cpp
-+++ b/runtime/BrowserWindow.cpp
-@@ -1286,17 +1286,17 @@ void BrowserWindow::preferences()
-
- ConfigWindow *dlg = new ConfigWindow();
- dlg->setWindowTitle(QWidget::tr("Configuration"));
-- dlg->setPythonPath(settings.value("PythonPath").toString());
-+ dlg->setPythonExecutable(settings.value("PythonExecutable").toString());
- dlg->setApplicationPath(settings.value("ApplicationPath").toString());
- dlg->setModal(true);
- ok = dlg->exec();
-
-- QString pythonpath = dlg->getPythonPath();
-+ QString pythonexecutable = dlg->getPythonExecutable();
- QString applicationpath = dlg->getApplicationPath();
-
- if (ok)
- {
-- settings.setValue("PythonPath", pythonpath);
-+ settings.setValue("PythonExecutable", pythonexecutable);
- settings.setValue("ApplicationPath", applicationpath);
- }
- }
-diff --git a/runtime/ConfigWindow.cpp b/runtime/ConfigWindow.cpp
-index 3fb1a2738eb89ec0..c31345bf08d06d88 100644
---- a/runtime/ConfigWindow.cpp
-+++ b/runtime/ConfigWindow.cpp
-@@ -17,37 +17,45 @@ ConfigWindow::ConfigWindow(QWidget *parent) :
- ui(new Ui::ConfigWindow)
- {
- ui->setupUi(this);
-+
-+#ifdef PYTHON2
-+ ui->pythonExecutableLineEdit->setPlaceholderText(
-+ QString(QWidget::tr("The Python 2 executable to use (may be within a virtual environment)")));
-+#else
-+ ui->pythonExecutableLineEdit->setPlaceholderText(
-+ QString(QWidget::tr("The Python 3 executable to use (may be within a virtual environment)")));
-+#endif
- }
-
- ConfigWindow::~ConfigWindow()
- {
- delete ui;
- }
-
- void ConfigWindow::on_buttonBox_accepted()
- {
- this->close();
- }
-
- void ConfigWindow::on_buttonBox_rejected()
- {
- this->close();
- }
-
--QString ConfigWindow::getPythonPath()
-+QString ConfigWindow::getPythonExecutable()
- {
-- return ui->pythonPathLineEdit->text();
-+ return ui->pythonExecutableLineEdit->text();
- }
-
- QString ConfigWindow::getApplicationPath()
- {
- return ui->applicationPathLineEdit->text();
- }
-
-
--void ConfigWindow::setPythonPath(QString path)
-+void ConfigWindow::setPythonExecutable(QString path)
- {
-- ui->pythonPathLineEdit->setText(path);
-+ ui->pythonExecutableLineEdit->setText(path);
- }
-
- void ConfigWindow::setApplicationPath(QString path)
-diff --git a/runtime/ConfigWindow.h b/runtime/ConfigWindow.h
-index 0027a742aca7b762..c4487fcc6e97f354 100644
---- a/runtime/ConfigWindow.h
-+++ b/runtime/ConfigWindow.h
-@@ -26,19 +26,19 @@ public:
- explicit ConfigWindow(QWidget *parent = 0);
- ~ConfigWindow();
-
-- QString getPythonPath();
-+ QString getPythonExecutable();
- QString getApplicationPath();
-
-- void setPythonPath(QString path);
-+ void setPythonExecutable(QString path);
- void setApplicationPath(QString path);
-
- private slots:
- void on_buttonBox_accepted();
- void on_buttonBox_rejected();
-
- private:
- Ui::ConfigWindow *ui;
-- QString m_pythonpath, m_applicationpath;
-+ QString m_pythonexecutable, m_applicationpath;
- };
-
- #endif // CONFIGWINDOW_H
-diff --git a/runtime/ConfigWindow.ui b/runtime/ConfigWindow.ui
-index 40d87be43803204a..8b379052a1da8cd0 100644
---- a/runtime/ConfigWindow.ui
-+++ b/runtime/ConfigWindow.ui
-@@ -29,24 +29,38 @@
- <enum>QFormLayout::ExpandingFieldsGrow</enum>
- </property>
- <item row="0" column="0">
-- <widget class="QLabel" name="pythonPathLabel">
-+ <widget class="QLabel" name="pythonExecutableLabel">
-+ <property name="sizeIncrement">
-+ <size>
-+ <width>0</width>
-+ <height>1</height>
-+ </size>
-+ </property>
- <property name="text">
-- <string>Python Path</string>
-+ <string>Python Executable</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
-- <widget class="QLineEdit" name="pythonPathLineEdit"/>
-+ <widget class="QLineEdit" name="pythonExecutableLineEdit">
-+ <property name="placeholderText">
-+ <string>The python executable to use (may be within a virtual environment)</string>
-+ </property>
-+ </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="applicationPathLabel">
- <property name="text">
- <string>Application Path</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
-- <widget class="QLineEdit" name="applicationPathLineEdit"/>
-+ <widget class="QLineEdit" name="applicationPathLineEdit">
-+ <property name="placeholderText">
-+ <string>The directory containing pgAdmin4.py (do not include the file name)</string>
-+ </property>
-+ </widget>
- </item>
- </layout>
- </item>
-diff --git a/runtime/Server.cpp b/runtime/Server.cpp
-index 33b43583480440b7..83bcdeedb09197c8 100644
---- a/runtime/Server.cpp
-+++ b/runtime/Server.cpp
-@@ -22,201 +22,85 @@
- // App headers
- #include "Server.h"
-
--static void add_to_path(QString &python_path, QString path, bool prepend=false)
--{
-- if (!python_path.contains(path))
-- {
-- if (!prepend)
-- {
--#if defined(Q_OS_WIN)
-- if (!python_path.isEmpty() && !python_path.endsWith(";"))
-- python_path.append(";");
--#else
-- if (!python_path.isEmpty() && !python_path.endsWith(":"))
-- python_path.append(":");
--#endif
--
-- python_path.append(path);
-- }
-- else
-- {
--#if defined(Q_OS_WIN)
-- if (!python_path.isEmpty() && !python_path.startsWith(";"))
-- python_path.prepend(";");
--#else
-- if (!python_path.isEmpty() && !python_path.startsWith(":"))
-- python_path.prepend(":");
--#endif
--
-- python_path.prepend(path);
-- }
-- }
--}
--
- Server::Server(quint16 port, QString key)
- {
- // Appserver port etc
- m_port = port;
- m_key = key;
-- m_wcAppName = NULL;
-- m_wcPythonHome = NULL;
-
- // Initialise Python
-- Py_NoSiteFlag=1;
-- Py_DontWriteBytecodeFlag=1;
-+ Py_DontWriteBytecodeFlag = 1;
-
-- PGA_APP_NAME_UTF8 = PGA_APP_NAME.toUtf8();
-+ // Get the application directory
-+ QString appDir = qApp->applicationDirPath();
-+
-+ // Build (and canonicalise) the virtual environment path
-+#ifdef Q_OS_MAC
-+ QFileInfo venvBinPath(appDir + "/../Resources/venv/bin");
-+#elif defined(Q_OS_WIN)
-+ QFileInfo venvBinPath(appDir + "/../venv");
-+#else
-+ QFileInfo venvBinPath(appDir + "/../venv/bin");
-+#endif
-+ QString binPath = venvBinPath.canonicalFilePath();
-+
-+ if (binPath.isEmpty())
-+ {
-+ // Use default Python environment from the config, or lastly, PATH
-+ QSettings settings;
-+ binPath.append(settings.value("PythonExecutable").toString());
-+ if (binPath.isEmpty())
-+ binPath.append("python");
-+ }
-+ else
-+ {
-+ binPath.append("/python");
-+ }
-
- // Python3 requires conversion of char * to wchar_t *, so...
- #ifdef PYTHON2
-- Py_SetProgramName(PGA_APP_NAME_UTF8.data());
-+ QByteArray appName = binPath.toLocal8Bit();
-+ m_pyAppName = new char[strlen(appName.data()) + 1];
-+ strcpy(m_pyAppName, appName.data());
-+ qDebug() << "Python interpreter: " << QString::fromLocal8Bit(m_pyAppName);
- #else
-- char *appName = PGA_APP_NAME_UTF8.data();
-- const size_t cSize = strlen(appName)+1;
-- m_wcAppName = new wchar_t[cSize];
-- mbstowcs (m_wcAppName, appName, cSize);
-- Py_SetProgramName(m_wcAppName);
-+ std::wstring appName = binPath.toStdWString();
-+ m_pyAppName = new wchar_t[wcslen(appName.c_str()) + 1];
-+ wcscpy(m_pyAppName, appName.c_str());
-+ qDebug() << "Python interpreter: " << QString::fromWCharArray(m_pyAppName);
- #endif
--
-- // Setup the search path
-- QSettings settings;
-- QString python_path = settings.value("PythonPath").toString();
--
-- // Get the application directory
-- QString app_dir = qApp->applicationDirPath(),
-- path_env = qgetenv("PATH"),
-- pythonHome;
-- QStringList path_list;
-- int i;
--
--#ifdef Q_OS_MAC
-- // In the case we're running in a release appbundle, we need to ensure the
-- // bundled virtual env is included in the Python path. We include it at the
-- // end, so expert users can override the path, but we do not save it, because
-- // if users move the app bundle, we'll end up with dead entries
--
-- // Build (and canonicalise) the virtual environment path
-- QFileInfo venvBinPath(app_dir + "/../Resources/venv/bin");
-- QFileInfo venvLibPath(app_dir + "/../Resources/venv/lib/python");
-- QFileInfo venvDynLibPath(app_dir + "/../Resources/venv/lib/python/lib-dynload");
-- QFileInfo venvSitePackagesPath(app_dir + "/../Resources/venv/lib/python/site-packages");
-- QFileInfo venvPath(app_dir + "/../Resources/venv");
--
-- // Prepend the bin directory to the path
-- add_to_path(path_env, venvBinPath.canonicalFilePath(), true);
-- // Append the path, if it's not already there
-- add_to_path(python_path, venvLibPath.canonicalFilePath());
-- add_to_path(python_path, venvDynLibPath.canonicalFilePath());
-- add_to_path(python_path, venvSitePackagesPath.canonicalFilePath());
-- add_to_path(pythonHome, venvPath.canonicalFilePath());
--#elif defined(Q_OS_WIN)
--
-- // In the case we're running in a release application, we need to ensure the
-- // bundled virtual env is included in the Python path. We include it at the
-- // end, so expert users can override the path, but we do not save it.
--
-- // Build (and canonicalise) the virtual environment path
-- QFileInfo venvBinPath(app_dir + "/../venv");
-- QFileInfo venvLibPath(app_dir + "/../venv/Lib");
-- QFileInfo venvDLLsPath(app_dir + "/../venv/DLLs");
-- QFileInfo venvSitePackagesPath(app_dir + "/../venv/Lib/site-packages");
-- QFileInfo venvPath(app_dir + "/../venv");
--
-- // Prepend the bin directory to the path
-- add_to_path(path_env, venvBinPath.canonicalFilePath(), true);
-- // Append paths, if they're not already there
-- add_to_path(python_path, venvLibPath.canonicalFilePath());
-- add_to_path(python_path, venvDLLsPath.canonicalFilePath());
-- add_to_path(python_path, venvSitePackagesPath.canonicalFilePath());
-- add_to_path(pythonHome, venvPath.canonicalFilePath());
--#else
-- // Build (and canonicalise) the virtual environment path
-- QFileInfo venvBinPath(app_dir + "/../venv/bin");
-- QFileInfo venvLibPath(app_dir + "/../venv/lib/python");
-- QFileInfo venvDynLibPath(app_dir + "/../venv/lib/python/lib-dynload");
-- QFileInfo venvSitePackagesPath(app_dir + "/../venv/lib/python/site-packages");
-- QFileInfo venvPath(app_dir + "/../venv");
--
-- // Prepend the bin directory to the path
-- add_to_path(path_env, venvBinPath.canonicalFilePath(), true);
-- // Append the path, if it's not already there
-- add_to_path(python_path, venvLibPath.canonicalFilePath());
-- add_to_path(python_path, venvDynLibPath.canonicalFilePath());
-- add_to_path(python_path, venvSitePackagesPath.canonicalFilePath());
-- add_to_path(pythonHome, venvPath.canonicalFilePath());
--#endif
--
-- qputenv("PATH", path_env.toUtf8().data());
--
-- if (python_path.length() > 0)
-- {
-- // Split the path setting into individual entries
-- path_list = python_path.split(";", QString::SkipEmptyParts);
-- python_path = QString();
--
-- // Add new additional path elements
-- for (i = path_list.size() - 1; i >= 0 ; --i)
-- {
-- python_path.append(path_list.at(i));
-- if (i > 0)
-- {
--#if defined(Q_OS_WIN)
-- python_path.append(";");
--#else
-- python_path.append(":");
--#endif
-- }
-- }
-- qputenv("PYTHONPATH", python_path.toUtf8().data());
-- }
--
-- qDebug() << "Python path: " << python_path
-- << "\nPython Home: " << pythonHome;
-- if (!pythonHome.isEmpty())
-- {
-- pythonHome_utf8 = pythonHome.toUtf8();
--#ifdef PYTHON2
-- Py_SetPythonHome(pythonHome_utf8.data());
--#else
-- char *python_home = pythonHome_utf8.data();
-- const size_t cSize = strlen(python_home) + 1;
-- m_wcPythonHome = new wchar_t[cSize];
-- mbstowcs (m_wcPythonHome, python_home, cSize);
--
-- Py_SetPythonHome(m_wcPythonHome);
--#endif
-- }
-+ Py_SetProgramName(m_pyAppName);
-
- Py_Initialize();
-
-+ /*
-+ * Untrusted search path vulnerability in the PySys_SetArgv API function in Python 2.6 and earlier, and possibly later
-+ * versions, prepends an empty string to sys.path when the argv[0] argument does not contain a path separator,
-+ * which might allow local users to execute arbitrary code via a Trojan horse Python file in the current working directory.
-+ * Here we have to set arguments explicitly to python interpreter. Check more details in 'PySys_SetArgv' documentation.
-+ */
-+ PySys_SetArgvEx(1, &m_pyAppName, 0);
-+
- // Get the current path
- PyObject* sysPath = PySys_GetObject((char*)"path");
--
-- // Add new additional path elements
-- for (i = path_list.size() - 1; i >= 0 ; --i)
-- {
-+ PyObject* sysPathRepr = PyObject_Repr(sysPath);
- #ifdef PYTHON2
-- PyList_Append(sysPath, PyString_FromString(path_list.at(i).toUtf8().data()));
-+ qDebug() << "Python path: " << QString::fromLocal8Bit(PyString_AsString(sysPathRepr));
- #else
--#if PY_MINOR_VERSION > 2
-- PyList_Append(sysPath, PyUnicode_DecodeFSDefault(path_list.at(i).toUtf8().data()));
--#else
-- PyList_Append(sysPath, PyBytes_FromString(path_list.at(i).toUtf8().data()));
-+ PyObject* sysPathBytes = PyUnicode_AsEncodedString(sysPathRepr, "utf8", "replace");
-+ qDebug() << "Python path: " << QString::fromUtf8(PyBytes_AsString(sysPathBytes));
-+ Py_DECREF(sysPathBytes);
- #endif
--#endif
-- }
-+ Py_DECREF(sysPathRepr);
- }
-
- Server::~Server()
- {
-- if (m_wcAppName)
-- delete m_wcAppName;
--
-- if (m_wcPythonHome)
-- delete m_wcPythonHome;
--
- // Shutdown Python
- Py_Finalize();
-+
-+ if (m_pyAppName)
-+ delete [] m_pyAppName;
- }
-
- bool Server::Init()
-@@ -264,52 +148,29 @@ bool Server::Init()
- void Server::run()
- {
- // Open the application code and run it.
-- FILE *cp = fopen(m_appfile.toUtf8().data(), "r");
-+ QByteArray m_appfile_utf8 = m_appfile.toUtf8();
-+ FILE *cp = fopen(m_appfile_utf8.data(), "r");
- if (!cp)
- {
- setError(QString(tr("Failed to open the application file: %1, server thread exiting.")).arg(m_appfile));
- return;
- }
-
- // Set the port number
- PyRun_SimpleString(QString("PGADMIN_PORT = %1").arg(m_port).toLatin1());
- PyRun_SimpleString(QString("PGADMIN_KEY = '%1'").arg(m_key).toLatin1());
-
- // Run the app!
-- QByteArray m_appfile_utf8 = m_appfile.toUtf8();
- #ifdef PYTHON2
-- /*
-- * Untrusted search path vulnerability in the PySys_SetArgv API function in Python 2.6 and earlier, and possibly later
-- * versions, prepends an empty string to sys.path when the argv[0] argument does not contain a path separator,
-- * which might allow local users to execute arbitrary code via a Trojan horse Python file in the current working directory.
-- * Here we have to set arguments explicitly to python interpreter. Check more details in 'PySys_SetArgv' documentation.
-- */
-- char* n_argv[] = { m_appfile_utf8.data() };
-- PySys_SetArgv(1, n_argv);
--
- PyObject* PyFileObject = PyFile_FromString(m_appfile_utf8.data(), (char *)"r");
- int ret = PyRun_SimpleFile(PyFile_AsFile(PyFileObject), m_appfile_utf8.data());
-- if (ret != 0)
-- setError(tr("Failed to launch the application server, server thread exiting."));
- #else
-- /*
-- * Untrusted search path vulnerability in the PySys_SetArgv API function in Python 2.6 and earlier, and possibly later
-- * versions, prepends an empty string to sys.path when the argv[0] argument does not contain a path separator,
-- * which might allow local users to execute arbitrary code via a Trojan horse Python file in the current working directory.
-- * Here we have to set arguments explicitly to python interpreter. Check more details in 'PySys_SetArgv' documentation.
-- */
-- char *appName = m_appfile_utf8.data();
-- const size_t cSize = strlen(appName)+1;
-- wchar_t* wcAppName = new wchar_t[cSize];
-- mbstowcs (wcAppName, appName, cSize);
-- wchar_t* n_argv[] = { wcAppName };
-- PySys_SetArgv(1, n_argv);
--
- int fd = fileno(cp);
- PyObject* PyFileObject = PyFile_FromFd(fd, m_appfile_utf8.data(), (char *)"r", -1, NULL, NULL,NULL,1);
-- if (PyRun_SimpleFile(fdopen(PyObject_AsFileDescriptor(PyFileObject),"r"), m_appfile_utf8.data()) != 0)
-- setError(tr("Failed to launch the application server, server thread exiting."));
-+ int ret = PyRun_SimpleFile(fdopen(PyObject_AsFileDescriptor(PyFileObject),"r"), m_appfile_utf8.data());
- #endif
-+ if (ret != 0)
-+ setError(tr("Failed to launch the application server, server thread exiting."));
-
- fclose(cp);
- }
-diff --git a/runtime/Server.h b/runtime/Server.h
-index 488f9fcedc6d7dc7..207e2f157db7d7a5 100644
---- a/runtime/Server.h
-+++ b/runtime/Server.h
-@@ -40,12 +40,11 @@ private:
-
- quint16 m_port;
- QString m_key;
-- // Application name in UTF-8 for Python
-- wchar_t *m_wcAppName;
-- QByteArray PGA_APP_NAME_UTF8;
-- // PythonHome for Python
-- wchar_t *m_wcPythonHome;
-- QByteArray pythonHome_utf8;
-+#ifdef PYTHON2
-+ char *m_pyAppName;
-+#else
-+ wchar_t *m_pyAppName;
-+#endif
- };
-
- #endif // SERVER_H
-diff --git a/runtime/pgAdmin4.cpp b/runtime/pgAdmin4.cpp
-index a2dbe7451557befc..ebcb4ff4d4899aaf 100644
---- a/runtime/pgAdmin4.cpp
-+++ b/runtime/pgAdmin4.cpp
-@@ -228,69 +228,65 @@ int main(int argc, char * argv[])
- // Fire up the webserver
- Server *server;
-
-- bool done = false;
-+ server = new Server(port, key);
-
-- while (done != true)
-+ if (!server->Init())
- {
-- server = new Server(port, key);
-+ splash->finish(NULL);
-
-- if (!server->Init())
-+ qDebug() << server->getError();
-+
-+ QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError());
-+ QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
-+
-+ exit(1);
-+ }
-+
-+ server->start();
-+
-+ // This is a hack. Wait a second and then check to see if the server thread
-+ // is still running. If it's not, we probably had a startup error
-+ delay(1000);
-+
-+ // Any errors?
-+ if (server->isFinished() || server->getError().length() > 0)
-+ {
-+ splash->finish(NULL);
-+
-+ qDebug() << server->getError();
-+
-+ QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError());
-+ QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
-+
-+ // Allow the user to tweak the Python Path if needed
-+ QSettings settings;
-+ bool ok;
-+
-+ ConfigWindow *dlg = new ConfigWindow();
-+ dlg->setWindowTitle(QWidget::tr("Configuration"));
-+ dlg->setPythonExecutable(settings.value("PythonExecutable").toString());
-+ dlg->setApplicationPath(settings.value("ApplicationPath").toString());
-+ dlg->setModal(true);
-+ ok = dlg->exec();
-+
-+ QString pythonexecutable = dlg->getPythonExecutable();
-+ QString applicationpath = dlg->getApplicationPath();
-+
-+ if (ok)
- {
-- splash->finish(NULL);
-+ settings.setValue("PythonExecutable", pythonexecutable);
-+ settings.setValue("ApplicationPath", applicationpath);
-+ settings.sync();
-
-- qDebug() << server->getError();
-+ QString msg = QString(QWidget::tr("Please restart the application to allow the changes to take effect."));
-+ QMessageBox::information(NULL, QString(QWidget::tr("Restart")), msg);
-
-- QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError());
-- QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
--
-- exit(1);
-- }
--
-- server->start();
--
-- // This is a hack. Wait a second and then check to see if the server thread
-- // is still running. If it's not, we probably had a startup error
-- delay(1000);
--
-- // Any errors?
-- if (server->isFinished() || server->getError().length() > 0)
-- {
-- splash->finish(NULL);
--
-- qDebug() << server->getError();
--
-- QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError());
-- QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
--
-- // Allow the user to tweak the Python Path if needed
-- QSettings settings;
-- bool ok;
--
-- ConfigWindow *dlg = new ConfigWindow();
-- dlg->setWindowTitle(QWidget::tr("Configuration"));
-- dlg->setPythonPath(settings.value("PythonPath").toString());
-- dlg->setApplicationPath(settings.value("ApplicationPath").toString());
-- dlg->setModal(true);
-- ok = dlg->exec();
--
-- QString pythonpath = dlg->getPythonPath();
-- QString applicationpath = dlg->getApplicationPath();
--
-- if (ok)
-- {
-- settings.setValue("PythonPath", pythonpath);
-- settings.setValue("ApplicationPath", applicationpath);
-- settings.sync();
-- }
-- else
-- {
-- exit(1);
-- }
--
-- delete server;
-+ exit(0);
- }
- else
-- done = true;
-+ {
-+ exit(1);
-+ }
- }
-
-
---
-2.13.0
-
Copied: pgadmin4/repos/community-x86_64/0001-Simplify-Server-s-python-setup.patch (from rev 238032, pgadmin4/trunk/0001-Simplify-Server-s-python-setup.patch)
===================================================================
--- community-x86_64/0001-Simplify-Server-s-python-setup.patch (rev 0)
+++ community-x86_64/0001-Simplify-Server-s-python-setup.patch 2017-06-18 10:59:59 UTC (rev 238033)
@@ -0,0 +1,633 @@
+From a5a1c332e23a094e0c2a1c9513fb9f6b05cbbf05 Mon Sep 17 00:00:00 2001
+From: "Jan Alexander Steffens (heftig)" <jan.steffens at gmail.com>
+Date: Sat, 28 Jan 2017 01:19:06 +0100
+Subject: [PATCH] Simplify Server's python setup
+---
+ runtime/BrowserWindow.cpp | 6 +-
+ runtime/ConfigWindow.cpp | 16 ++-
+ runtime/ConfigWindow.h | 6 +-
+ runtime/ConfigWindow.ui | 22 +++-
+ runtime/Server.cpp | 253 +++++++++++-----------------------------------
+ runtime/Server.h | 11 +-
+ runtime/pgAdmin4.cpp | 106 ++++++++++---------
+ 7 files changed, 149 insertions(+), 271 deletions(-)
+
+diff --git a/runtime/BrowserWindow.cpp b/runtime/BrowserWindow.cpp
+index 516b8689818bddc9..a2ee4895f5351565 100644
+--- a/runtime/BrowserWindow.cpp
++++ b/runtime/BrowserWindow.cpp
+@@ -1286,17 +1286,17 @@ void BrowserWindow::preferences()
+
+ ConfigWindow *dlg = new ConfigWindow();
+ dlg->setWindowTitle(QWidget::tr("Configuration"));
+- dlg->setPythonPath(settings.value("PythonPath").toString());
++ dlg->setPythonExecutable(settings.value("PythonExecutable").toString());
+ dlg->setApplicationPath(settings.value("ApplicationPath").toString());
+ dlg->setModal(true);
+ ok = dlg->exec();
+
+- QString pythonpath = dlg->getPythonPath();
++ QString pythonexecutable = dlg->getPythonExecutable();
+ QString applicationpath = dlg->getApplicationPath();
+
+ if (ok)
+ {
+- settings.setValue("PythonPath", pythonpath);
++ settings.setValue("PythonExecutable", pythonexecutable);
+ settings.setValue("ApplicationPath", applicationpath);
+ }
+ }
+diff --git a/runtime/ConfigWindow.cpp b/runtime/ConfigWindow.cpp
+index 3fb1a2738eb89ec0..c31345bf08d06d88 100644
+--- a/runtime/ConfigWindow.cpp
++++ b/runtime/ConfigWindow.cpp
+@@ -17,37 +17,45 @@ ConfigWindow::ConfigWindow(QWidget *parent) :
+ ui(new Ui::ConfigWindow)
+ {
+ ui->setupUi(this);
++
++#ifdef PYTHON2
++ ui->pythonExecutableLineEdit->setPlaceholderText(
++ QString(QWidget::tr("The Python 2 executable to use (may be within a virtual environment)")));
++#else
++ ui->pythonExecutableLineEdit->setPlaceholderText(
++ QString(QWidget::tr("The Python 3 executable to use (may be within a virtual environment)")));
++#endif
+ }
+
+ ConfigWindow::~ConfigWindow()
+ {
+ delete ui;
+ }
+
+ void ConfigWindow::on_buttonBox_accepted()
+ {
+ this->close();
+ }
+
+ void ConfigWindow::on_buttonBox_rejected()
+ {
+ this->close();
+ }
+
+-QString ConfigWindow::getPythonPath()
++QString ConfigWindow::getPythonExecutable()
+ {
+- return ui->pythonPathLineEdit->text();
++ return ui->pythonExecutableLineEdit->text();
+ }
+
+ QString ConfigWindow::getApplicationPath()
+ {
+ return ui->applicationPathLineEdit->text();
+ }
+
+
+-void ConfigWindow::setPythonPath(QString path)
++void ConfigWindow::setPythonExecutable(QString path)
+ {
+- ui->pythonPathLineEdit->setText(path);
++ ui->pythonExecutableLineEdit->setText(path);
+ }
+
+ void ConfigWindow::setApplicationPath(QString path)
+diff --git a/runtime/ConfigWindow.h b/runtime/ConfigWindow.h
+index 0027a742aca7b762..c4487fcc6e97f354 100644
+--- a/runtime/ConfigWindow.h
++++ b/runtime/ConfigWindow.h
+@@ -26,19 +26,19 @@ public:
+ explicit ConfigWindow(QWidget *parent = 0);
+ ~ConfigWindow();
+
+- QString getPythonPath();
++ QString getPythonExecutable();
+ QString getApplicationPath();
+
+- void setPythonPath(QString path);
++ void setPythonExecutable(QString path);
+ void setApplicationPath(QString path);
+
+ private slots:
+ void on_buttonBox_accepted();
+ void on_buttonBox_rejected();
+
+ private:
+ Ui::ConfigWindow *ui;
+- QString m_pythonpath, m_applicationpath;
++ QString m_pythonexecutable, m_applicationpath;
+ };
+
+ #endif // CONFIGWINDOW_H
+diff --git a/runtime/ConfigWindow.ui b/runtime/ConfigWindow.ui
+index 40d87be43803204a..8b379052a1da8cd0 100644
+--- a/runtime/ConfigWindow.ui
++++ b/runtime/ConfigWindow.ui
+@@ -29,24 +29,38 @@
+ <enum>QFormLayout::ExpandingFieldsGrow</enum>
+ </property>
+ <item row="0" column="0">
+- <widget class="QLabel" name="pythonPathLabel">
++ <widget class="QLabel" name="pythonExecutableLabel">
++ <property name="sizeIncrement">
++ <size>
++ <width>0</width>
++ <height>1</height>
++ </size>
++ </property>
+ <property name="text">
+- <string>Python Path</string>
++ <string>Python Executable</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+- <widget class="QLineEdit" name="pythonPathLineEdit"/>
++ <widget class="QLineEdit" name="pythonExecutableLineEdit">
++ <property name="placeholderText">
++ <string>The python executable to use (may be within a virtual environment)</string>
++ </property>
++ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="applicationPathLabel">
+ <property name="text">
+ <string>Application Path</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+- <widget class="QLineEdit" name="applicationPathLineEdit"/>
++ <widget class="QLineEdit" name="applicationPathLineEdit">
++ <property name="placeholderText">
++ <string>The directory containing pgAdmin4.py (do not include the file name)</string>
++ </property>
++ </widget>
+ </item>
+ </layout>
+ </item>
+diff --git a/runtime/Server.cpp b/runtime/Server.cpp
+index 33b43583480440b7..83bcdeedb09197c8 100644
+--- a/runtime/Server.cpp
++++ b/runtime/Server.cpp
+@@ -22,201 +22,85 @@
+ // App headers
+ #include "Server.h"
+
+-static void add_to_path(QString &python_path, QString path, bool prepend=false)
+-{
+- if (!python_path.contains(path))
+- {
+- if (!prepend)
+- {
+-#if defined(Q_OS_WIN)
+- if (!python_path.isEmpty() && !python_path.endsWith(";"))
+- python_path.append(";");
+-#else
+- if (!python_path.isEmpty() && !python_path.endsWith(":"))
+- python_path.append(":");
+-#endif
+-
+- python_path.append(path);
+- }
+- else
+- {
+-#if defined(Q_OS_WIN)
+- if (!python_path.isEmpty() && !python_path.startsWith(";"))
+- python_path.prepend(";");
+-#else
+- if (!python_path.isEmpty() && !python_path.startsWith(":"))
+- python_path.prepend(":");
+-#endif
+-
+- python_path.prepend(path);
+- }
+- }
+-}
+-
+ Server::Server(quint16 port, QString key)
+ {
+ // Appserver port etc
+ m_port = port;
+ m_key = key;
+- m_wcAppName = NULL;
+- m_wcPythonHome = NULL;
+
+ // Initialise Python
+- Py_NoSiteFlag=1;
+- Py_DontWriteBytecodeFlag=1;
++ Py_DontWriteBytecodeFlag = 1;
+
+- PGA_APP_NAME_UTF8 = PGA_APP_NAME.toUtf8();
++ // Get the application directory
++ QString appDir = qApp->applicationDirPath();
++
++ // Build (and canonicalise) the virtual environment path
++#ifdef Q_OS_MAC
++ QFileInfo venvBinPath(appDir + "/../Resources/venv/bin");
++#elif defined(Q_OS_WIN)
++ QFileInfo venvBinPath(appDir + "/../venv");
++#else
++ QFileInfo venvBinPath(appDir + "/../venv/bin");
++#endif
++ QString binPath = venvBinPath.canonicalFilePath();
++
++ if (binPath.isEmpty())
++ {
++ // Use default Python environment from the config, or lastly, PATH
++ QSettings settings;
++ binPath.append(settings.value("PythonExecutable").toString());
++ if (binPath.isEmpty())
++ binPath.append("python");
++ }
++ else
++ {
++ binPath.append("/python");
++ }
+
+ // Python3 requires conversion of char * to wchar_t *, so...
+ #ifdef PYTHON2
+- Py_SetProgramName(PGA_APP_NAME_UTF8.data());
++ QByteArray appName = binPath.toLocal8Bit();
++ m_pyAppName = new char[strlen(appName.data()) + 1];
++ strcpy(m_pyAppName, appName.data());
++ qDebug() << "Python interpreter: " << QString::fromLocal8Bit(m_pyAppName);
+ #else
+- char *appName = PGA_APP_NAME_UTF8.data();
+- const size_t cSize = strlen(appName)+1;
+- m_wcAppName = new wchar_t[cSize];
+- mbstowcs (m_wcAppName, appName, cSize);
+- Py_SetProgramName(m_wcAppName);
++ std::wstring appName = binPath.toStdWString();
++ m_pyAppName = new wchar_t[wcslen(appName.c_str()) + 1];
++ wcscpy(m_pyAppName, appName.c_str());
++ qDebug() << "Python interpreter: " << QString::fromWCharArray(m_pyAppName);
+ #endif
+-
+- // Setup the search path
+- QSettings settings;
+- QString python_path = settings.value("PythonPath").toString();
+-
+- // Get the application directory
+- QString app_dir = qApp->applicationDirPath(),
+- path_env = qgetenv("PATH"),
+- pythonHome;
+- QStringList path_list;
+- int i;
+-
+-#ifdef Q_OS_MAC
+- // In the case we're running in a release appbundle, we need to ensure the
+- // bundled virtual env is included in the Python path. We include it at the
+- // end, so expert users can override the path, but we do not save it, because
+- // if users move the app bundle, we'll end up with dead entries
+-
+- // Build (and canonicalise) the virtual environment path
+- QFileInfo venvBinPath(app_dir + "/../Resources/venv/bin");
+- QFileInfo venvLibPath(app_dir + "/../Resources/venv/lib/python");
+- QFileInfo venvDynLibPath(app_dir + "/../Resources/venv/lib/python/lib-dynload");
+- QFileInfo venvSitePackagesPath(app_dir + "/../Resources/venv/lib/python/site-packages");
+- QFileInfo venvPath(app_dir + "/../Resources/venv");
+-
+- // Prepend the bin directory to the path
+- add_to_path(path_env, venvBinPath.canonicalFilePath(), true);
+- // Append the path, if it's not already there
+- add_to_path(python_path, venvLibPath.canonicalFilePath());
+- add_to_path(python_path, venvDynLibPath.canonicalFilePath());
+- add_to_path(python_path, venvSitePackagesPath.canonicalFilePath());
+- add_to_path(pythonHome, venvPath.canonicalFilePath());
+-#elif defined(Q_OS_WIN)
+-
+- // In the case we're running in a release application, we need to ensure the
+- // bundled virtual env is included in the Python path. We include it at the
+- // end, so expert users can override the path, but we do not save it.
+-
+- // Build (and canonicalise) the virtual environment path
+- QFileInfo venvBinPath(app_dir + "/../venv");
+- QFileInfo venvLibPath(app_dir + "/../venv/Lib");
+- QFileInfo venvDLLsPath(app_dir + "/../venv/DLLs");
+- QFileInfo venvSitePackagesPath(app_dir + "/../venv/Lib/site-packages");
+- QFileInfo venvPath(app_dir + "/../venv");
+-
+- // Prepend the bin directory to the path
+- add_to_path(path_env, venvBinPath.canonicalFilePath(), true);
+- // Append paths, if they're not already there
+- add_to_path(python_path, venvLibPath.canonicalFilePath());
+- add_to_path(python_path, venvDLLsPath.canonicalFilePath());
+- add_to_path(python_path, venvSitePackagesPath.canonicalFilePath());
+- add_to_path(pythonHome, venvPath.canonicalFilePath());
+-#else
+- // Build (and canonicalise) the virtual environment path
+- QFileInfo venvBinPath(app_dir + "/../venv/bin");
+- QFileInfo venvLibPath(app_dir + "/../venv/lib/python");
+- QFileInfo venvDynLibPath(app_dir + "/../venv/lib/python/lib-dynload");
+- QFileInfo venvSitePackagesPath(app_dir + "/../venv/lib/python/site-packages");
+- QFileInfo venvPath(app_dir + "/../venv");
+-
+- // Prepend the bin directory to the path
+- add_to_path(path_env, venvBinPath.canonicalFilePath(), true);
+- // Append the path, if it's not already there
+- add_to_path(python_path, venvLibPath.canonicalFilePath());
+- add_to_path(python_path, venvDynLibPath.canonicalFilePath());
+- add_to_path(python_path, venvSitePackagesPath.canonicalFilePath());
+- add_to_path(pythonHome, venvPath.canonicalFilePath());
+-#endif
+-
+- qputenv("PATH", path_env.toUtf8().data());
+-
+- if (python_path.length() > 0)
+- {
+- // Split the path setting into individual entries
+- path_list = python_path.split(";", QString::SkipEmptyParts);
+- python_path = QString();
+-
+- // Add new additional path elements
+- for (i = path_list.size() - 1; i >= 0 ; --i)
+- {
+- python_path.append(path_list.at(i));
+- if (i > 0)
+- {
+-#if defined(Q_OS_WIN)
+- python_path.append(";");
+-#else
+- python_path.append(":");
+-#endif
+- }
+- }
+- qputenv("PYTHONPATH", python_path.toUtf8().data());
+- }
+-
+- qDebug() << "Python path: " << python_path
+- << "\nPython Home: " << pythonHome;
+- if (!pythonHome.isEmpty())
+- {
+- pythonHome_utf8 = pythonHome.toUtf8();
+-#ifdef PYTHON2
+- Py_SetPythonHome(pythonHome_utf8.data());
+-#else
+- char *python_home = pythonHome_utf8.data();
+- const size_t cSize = strlen(python_home) + 1;
+- m_wcPythonHome = new wchar_t[cSize];
+- mbstowcs (m_wcPythonHome, python_home, cSize);
+-
+- Py_SetPythonHome(m_wcPythonHome);
+-#endif
+- }
++ Py_SetProgramName(m_pyAppName);
+
+ Py_Initialize();
+
++ /*
++ * Untrusted search path vulnerability in the PySys_SetArgv API function in Python 2.6 and earlier, and possibly later
++ * versions, prepends an empty string to sys.path when the argv[0] argument does not contain a path separator,
++ * which might allow local users to execute arbitrary code via a Trojan horse Python file in the current working directory.
++ * Here we have to set arguments explicitly to python interpreter. Check more details in 'PySys_SetArgv' documentation.
++ */
++ PySys_SetArgvEx(1, &m_pyAppName, 0);
++
+ // Get the current path
+ PyObject* sysPath = PySys_GetObject((char*)"path");
+-
+- // Add new additional path elements
+- for (i = path_list.size() - 1; i >= 0 ; --i)
+- {
++ PyObject* sysPathRepr = PyObject_Repr(sysPath);
+ #ifdef PYTHON2
+- PyList_Append(sysPath, PyString_FromString(path_list.at(i).toUtf8().data()));
++ qDebug() << "Python path: " << QString::fromLocal8Bit(PyString_AsString(sysPathRepr));
+ #else
+-#if PY_MINOR_VERSION > 2
+- PyList_Append(sysPath, PyUnicode_DecodeFSDefault(path_list.at(i).toUtf8().data()));
+-#else
+- PyList_Append(sysPath, PyBytes_FromString(path_list.at(i).toUtf8().data()));
++ PyObject* sysPathBytes = PyUnicode_AsEncodedString(sysPathRepr, "utf8", "replace");
++ qDebug() << "Python path: " << QString::fromUtf8(PyBytes_AsString(sysPathBytes));
++ Py_DECREF(sysPathBytes);
+ #endif
+-#endif
+- }
++ Py_DECREF(sysPathRepr);
+ }
+
+ Server::~Server()
+ {
+- if (m_wcAppName)
+- delete m_wcAppName;
+-
+- if (m_wcPythonHome)
+- delete m_wcPythonHome;
+-
+ // Shutdown Python
+ Py_Finalize();
++
++ if (m_pyAppName)
++ delete [] m_pyAppName;
+ }
+
+ bool Server::Init()
+@@ -264,52 +148,29 @@ bool Server::Init()
+ void Server::run()
+ {
+ // Open the application code and run it.
+- FILE *cp = fopen(m_appfile.toUtf8().data(), "r");
++ QByteArray m_appfile_utf8 = m_appfile.toUtf8();
++ FILE *cp = fopen(m_appfile_utf8.data(), "r");
+ if (!cp)
+ {
+ setError(QString(tr("Failed to open the application file: %1, server thread exiting.")).arg(m_appfile));
+ return;
+ }
+
+ // Set the port number
+ PyRun_SimpleString(QString("PGADMIN_PORT = %1").arg(m_port).toLatin1());
+ PyRun_SimpleString(QString("PGADMIN_KEY = '%1'").arg(m_key).toLatin1());
+
+ // Run the app!
+- QByteArray m_appfile_utf8 = m_appfile.toUtf8();
+ #ifdef PYTHON2
+- /*
+- * Untrusted search path vulnerability in the PySys_SetArgv API function in Python 2.6 and earlier, and possibly later
+- * versions, prepends an empty string to sys.path when the argv[0] argument does not contain a path separator,
+- * which might allow local users to execute arbitrary code via a Trojan horse Python file in the current working directory.
+- * Here we have to set arguments explicitly to python interpreter. Check more details in 'PySys_SetArgv' documentation.
+- */
+- char* n_argv[] = { m_appfile_utf8.data() };
+- PySys_SetArgv(1, n_argv);
+-
+ PyObject* PyFileObject = PyFile_FromString(m_appfile_utf8.data(), (char *)"r");
+ int ret = PyRun_SimpleFile(PyFile_AsFile(PyFileObject), m_appfile_utf8.data());
+- if (ret != 0)
+- setError(tr("Failed to launch the application server, server thread exiting."));
+ #else
+- /*
+- * Untrusted search path vulnerability in the PySys_SetArgv API function in Python 2.6 and earlier, and possibly later
+- * versions, prepends an empty string to sys.path when the argv[0] argument does not contain a path separator,
+- * which might allow local users to execute arbitrary code via a Trojan horse Python file in the current working directory.
+- * Here we have to set arguments explicitly to python interpreter. Check more details in 'PySys_SetArgv' documentation.
+- */
+- char *appName = m_appfile_utf8.data();
+- const size_t cSize = strlen(appName)+1;
+- wchar_t* wcAppName = new wchar_t[cSize];
+- mbstowcs (wcAppName, appName, cSize);
+- wchar_t* n_argv[] = { wcAppName };
+- PySys_SetArgv(1, n_argv);
+-
+ int fd = fileno(cp);
+ PyObject* PyFileObject = PyFile_FromFd(fd, m_appfile_utf8.data(), (char *)"r", -1, NULL, NULL,NULL,1);
+- if (PyRun_SimpleFile(fdopen(PyObject_AsFileDescriptor(PyFileObject),"r"), m_appfile_utf8.data()) != 0)
+- setError(tr("Failed to launch the application server, server thread exiting."));
++ int ret = PyRun_SimpleFile(fdopen(PyObject_AsFileDescriptor(PyFileObject),"r"), m_appfile_utf8.data());
+ #endif
++ if (ret != 0)
++ setError(tr("Failed to launch the application server, server thread exiting."));
+
+ fclose(cp);
+ }
+diff --git a/runtime/Server.h b/runtime/Server.h
+index 488f9fcedc6d7dc7..207e2f157db7d7a5 100644
+--- a/runtime/Server.h
++++ b/runtime/Server.h
+@@ -40,12 +40,11 @@ private:
+
+ quint16 m_port;
+ QString m_key;
+- // Application name in UTF-8 for Python
+- wchar_t *m_wcAppName;
+- QByteArray PGA_APP_NAME_UTF8;
+- // PythonHome for Python
+- wchar_t *m_wcPythonHome;
+- QByteArray pythonHome_utf8;
++#ifdef PYTHON2
++ char *m_pyAppName;
++#else
++ wchar_t *m_pyAppName;
++#endif
+ };
+
+ #endif // SERVER_H
+diff --git a/runtime/pgAdmin4.cpp b/runtime/pgAdmin4.cpp
+index a2dbe7451557befc..ebcb4ff4d4899aaf 100644
+--- a/runtime/pgAdmin4.cpp
++++ b/runtime/pgAdmin4.cpp
+@@ -228,69 +228,65 @@ int main(int argc, char * argv[])
+ // Fire up the webserver
+ Server *server;
+
+- bool done = false;
++ server = new Server(port, key);
+
+- while (done != true)
++ if (!server->Init())
+ {
+- server = new Server(port, key);
++ splash->finish(NULL);
+
+- if (!server->Init())
++ qDebug() << server->getError();
++
++ QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError());
++ QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
++
++ exit(1);
++ }
++
++ server->start();
++
++ // This is a hack. Wait a second and then check to see if the server thread
++ // is still running. If it's not, we probably had a startup error
++ delay(1000);
++
++ // Any errors?
++ if (server->isFinished() || server->getError().length() > 0)
++ {
++ splash->finish(NULL);
++
++ qDebug() << server->getError();
++
++ QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError());
++ QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
++
++ // Allow the user to tweak the Python Path if needed
++ QSettings settings;
++ bool ok;
++
++ ConfigWindow *dlg = new ConfigWindow();
++ dlg->setWindowTitle(QWidget::tr("Configuration"));
++ dlg->setPythonExecutable(settings.value("PythonExecutable").toString());
++ dlg->setApplicationPath(settings.value("ApplicationPath").toString());
++ dlg->setModal(true);
++ ok = dlg->exec();
++
++ QString pythonexecutable = dlg->getPythonExecutable();
++ QString applicationpath = dlg->getApplicationPath();
++
++ if (ok)
+ {
+- splash->finish(NULL);
++ settings.setValue("PythonExecutable", pythonexecutable);
++ settings.setValue("ApplicationPath", applicationpath);
++ settings.sync();
+
+- qDebug() << server->getError();
++ QString msg = QString(QWidget::tr("Please restart the application to allow the changes to take effect."));
++ QMessageBox::information(NULL, QString(QWidget::tr("Restart")), msg);
+
+- QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError());
+- QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
+-
+- exit(1);
+- }
+-
+- server->start();
+-
+- // This is a hack. Wait a second and then check to see if the server thread
+- // is still running. If it's not, we probably had a startup error
+- delay(1000);
+-
+- // Any errors?
+- if (server->isFinished() || server->getError().length() > 0)
+- {
+- splash->finish(NULL);
+-
+- qDebug() << server->getError();
+-
+- QString error = QString(QWidget::tr("An error occurred initialising the application server:\n\n%1")).arg(server->getError());
+- QMessageBox::critical(NULL, QString(QWidget::tr("Fatal Error")), error);
+-
+- // Allow the user to tweak the Python Path if needed
+- QSettings settings;
+- bool ok;
+-
+- ConfigWindow *dlg = new ConfigWindow();
+- dlg->setWindowTitle(QWidget::tr("Configuration"));
+- dlg->setPythonPath(settings.value("PythonPath").toString());
+- dlg->setApplicationPath(settings.value("ApplicationPath").toString());
+- dlg->setModal(true);
+- ok = dlg->exec();
+-
+- QString pythonpath = dlg->getPythonPath();
+- QString applicationpath = dlg->getApplicationPath();
+-
+- if (ok)
+- {
+- settings.setValue("PythonPath", pythonpath);
+- settings.setValue("ApplicationPath", applicationpath);
+- settings.sync();
+- }
+- else
+- {
+- exit(1);
+- }
+-
+- delete server;
++ exit(0);
+ }
+ else
+- done = true;
++ {
++ exit(1);
++ }
+ }
+
+
+--
+2.13.0
+
Deleted: community-x86_64/PKGBUILD
===================================================================
--- community-x86_64/PKGBUILD 2017-06-18 10:59:49 UTC (rev 238032)
+++ community-x86_64/PKGBUILD 2017-06-18 10:59:59 UTC (rev 238033)
@@ -1,84 +0,0 @@
-# $Id$
-# Maintainer: Jerome Leclanche <jerome at leclan.ch>
-
-pkgname=pgadmin4
-pkgver=1.5
-pkgrel=2
-pkgdesc="Comprehensive design and management interface for PostgreSQL"
-arch=("i686" "x86_64")
-url="https://www.pgadmin.org/"
-license=("custom")
-depends=("qt5-webengine" "python" "postgresql-libs" "hicolor-icon-theme")
-makedepends=("python-setuptools" "imagemagick")
-source=(
- "https://ftp.postgresql.org/pub/pgadmin/pgadmin4/v$pkgver/source/$pkgname-$pkgver.tar.gz"{,.sig}
- "pgAdmin4.desktop"
- "config_distro.py"
- "config_local.py"
- # https://www.postgresql.org/message-id/CAMQ-g0dHUN2SFioNg93hCTJkRR3LsVZ-ZvhUh6in%2BO4UAU2Qow%40mail.gmail.com
- "0001-Simplify-Server-s-python-setup.patch"
-)
-sha256sums=(
- "a814d926e9af046ff8ebaf968ec37da8f26ba012de2bff655630703ed2c6bf5c"
- "SKIP"
- "9a39a321fa5a7fcf4f7f7abf6872de6de537800212e9f6f4902ed37b806765b7"
- "510c11bf26fa335548ec4c582bc9f5a5242b8e03f3cb0b7c19e6bfd12b6d663c"
- "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
- "f6a3268c0a4b88d6c06d6c92e307dece1f2e3d2ab9d80339395f525cbf23c93e"
-)
-validpgpkeys=(
- "E0C4CEEB826B1FDA4FB468E024ADFAAF698F1519"
-)
-
-
-prepare() {
- cd "$pkgname-$pkgver"
- patch -Np1 -i "../0001-Simplify-Server-s-python-setup.patch"
- convert runtime/pgAdmin4.{ico,png}
-
- _venv="$srcdir/$pkgname-$pkgver/venv"
- /usr/bin/python -m venv "$_venv"
- "$_venv/bin/python" -m pip install -r "$srcdir/$pkgname-$pkgver/requirements.txt"
- "$_venv/bin/python" -m pip install sphinx # building docs
-}
-
-
-build() {
- export LANG=en_US.UTF-8
- export LC_ALL=en_US.UTF-8
-
- cd "$pkgname-$pkgver/runtime"
- qmake CONFIG+=release
- make
-
- PATH="$_venv/bin:$PATH" make -C "$srcdir/$pkgname-$pkgver" docs
-}
-
-
-package() {
- cd "$pkgname-$pkgver"
-
- install -D runtime/pgAdmin4 "$pkgdir/usr/lib/pgadmin4/runtime/pgAdmin4"
-
- cp -a docs web "$pkgdir/usr/lib/pgadmin4"
- cp -a venv "$pkgdir/usr/lib/pgadmin4/venv"
-
- install -Dm644 "$srcdir/config_distro.py" "$pkgdir/usr/lib/pgadmin4/web/config_distro.py"
- install -Dm644 "$srcdir/config_local.py" "$pkgdir/usr/lib/pgadmin4/web/config_distro.py"
-
- ### Launcher
-
- install -Dm644 runtime/pgAdmin4-0.png "$pkgdir/usr/share/icons/hicolor/256x256/apps/pgAdmin4.png"
- install -Dm644 runtime/pgAdmin4-1.png "$pkgdir/usr/share/icons/hicolor/48x48/apps/pgAdmin4.png"
- install -Dm644 runtime/pgAdmin4-2.png "$pkgdir/usr/share/icons/hicolor/32x32/apps/pgAdmin4.png"
- install -Dm644 runtime/pgAdmin4-3.png "$pkgdir/usr/share/icons/hicolor/16x16/apps/pgAdmin4.png"
-
- install -Dm644 "$srcdir/pgAdmin4.desktop" "$pkgdir/usr/share/applications/pgAdmin4.desktop"
-
- install -D /dev/stdin "$pkgdir/usr/bin/pgadmin4" <<END
-#!/bin/sh
-exec /usr/lib/pgadmin4/runtime/pgAdmin4 "\$@"
-END
-
- install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
-}
Copied: pgadmin4/repos/community-x86_64/PKGBUILD (from rev 238032, pgadmin4/trunk/PKGBUILD)
===================================================================
--- community-x86_64/PKGBUILD (rev 0)
+++ community-x86_64/PKGBUILD 2017-06-18 10:59:59 UTC (rev 238033)
@@ -0,0 +1,86 @@
+# $Id$
+# Maintainer: Jerome Leclanche <jerome at leclan.ch>
+
+pkgname=pgadmin4
+pkgver=1.5
+pkgrel=3
+pkgdesc="Comprehensive design and management interface for PostgreSQL"
+arch=("i686" "x86_64")
+url="https://www.pgadmin.org/"
+license=("custom")
+depends=("qt5-webengine" "python" "postgresql-libs" "hicolor-icon-theme")
+makedepends=("python-setuptools" "imagemagick")
+source=(
+ "https://ftp.postgresql.org/pub/pgadmin/pgadmin4/v$pkgver/source/$pkgname-$pkgver.tar.gz"{,.sig}
+ "pgAdmin4.desktop"
+ "config_distro.py"
+ "config_local.py"
+ # https://www.postgresql.org/message-id/CAMQ-g0dHUN2SFioNg93hCTJkRR3LsVZ-ZvhUh6in%2BO4UAU2Qow%40mail.gmail.com
+ "0001-Simplify-Server-s-python-setup.patch"
+)
+sha256sums=(
+ "a814d926e9af046ff8ebaf968ec37da8f26ba012de2bff655630703ed2c6bf5c"
+ "SKIP"
+ "9a39a321fa5a7fcf4f7f7abf6872de6de537800212e9f6f4902ed37b806765b7"
+ "510c11bf26fa335548ec4c582bc9f5a5242b8e03f3cb0b7c19e6bfd12b6d663c"
+ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
+ "f6a3268c0a4b88d6c06d6c92e307dece1f2e3d2ab9d80339395f525cbf23c93e"
+)
+validpgpkeys=(
+ "E0C4CEEB826B1FDA4FB468E024ADFAAF698F1519"
+)
+
+
+prepare() {
+ cd "$pkgname-$pkgver"
+ patch -Np1 -i "../0001-Simplify-Server-s-python-setup.patch"
+ convert runtime/pgAdmin4.{ico,png}
+
+ /usr/bin/python -m venv "$srcdir/$pkgname-$pkgver/venv"
+ "$srcdir/$pkgname-$pkgver/venv/bin/python" -m pip install -r "$srcdir/$pkgname-$pkgver/requirements.txt"
+
+ /usr/bin/python -m venv "$srcdir/$pkgname-$pkgver/venv-docs"
+ "$srcdir/$pkgname-$pkgver/venv-docs/bin/python" -m pip install -r "$srcdir/$pkgname-$pkgver/requirements.txt"
+ "$srcdir/$pkgname-$pkgver/venv-docs/bin/python" -m pip install sphinx
+}
+
+
+build() {
+ export LANG=en_US.UTF-8
+ export LC_ALL=en_US.UTF-8
+
+ cd "$pkgname-$pkgver/runtime"
+ qmake CONFIG+=release
+ make
+
+ PATH="$srcdir/$pkgname-$pkgver/venv-docs/bin:$PATH" make -C "$srcdir/$pkgname-$pkgver" docs
+}
+
+
+package() {
+ cd "$pkgname-$pkgver"
+
+ install -D runtime/pgAdmin4 "$pkgdir/usr/lib/pgadmin4/runtime/pgAdmin4"
+
+ cp -a docs web "$pkgdir/usr/lib/pgadmin4"
+ cp -a venv "$pkgdir/usr/lib/pgadmin4/venv"
+
+ install -Dm644 "$srcdir/config_distro.py" "$pkgdir/usr/lib/pgadmin4/web/config_distro.py"
+ install -Dm644 "$srcdir/config_local.py" "$pkgdir/usr/lib/pgadmin4/web/config_local.py"
+
+ ### Launcher
+
+ install -Dm644 runtime/pgAdmin4-0.png "$pkgdir/usr/share/icons/hicolor/256x256/apps/pgAdmin4.png"
+ install -Dm644 runtime/pgAdmin4-1.png "$pkgdir/usr/share/icons/hicolor/48x48/apps/pgAdmin4.png"
+ install -Dm644 runtime/pgAdmin4-2.png "$pkgdir/usr/share/icons/hicolor/32x32/apps/pgAdmin4.png"
+ install -Dm644 runtime/pgAdmin4-3.png "$pkgdir/usr/share/icons/hicolor/16x16/apps/pgAdmin4.png"
+
+ install -Dm644 "$srcdir/pgAdmin4.desktop" "$pkgdir/usr/share/applications/pgAdmin4.desktop"
+
+ install -D /dev/stdin "$pkgdir/usr/bin/pgadmin4" <<END
+#!/bin/sh
+exec /usr/lib/pgadmin4/runtime/pgAdmin4 "\$@"
+END
+
+ install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
+}
Deleted: community-x86_64/config_distro.py
===================================================================
--- community-x86_64/config_distro.py 2017-06-18 10:59:49 UTC (rev 238032)
+++ community-x86_64/config_distro.py 2017-06-18 10:59:59 UTC (rev 238033)
@@ -1,2 +0,0 @@
-SERVER_MODE = False
-HELP_PATH = "/usr/lib/pgadmin4/docs/en_US/_build/html/"
Copied: pgadmin4/repos/community-x86_64/config_distro.py (from rev 238032, pgadmin4/trunk/config_distro.py)
===================================================================
--- community-x86_64/config_distro.py (rev 0)
+++ community-x86_64/config_distro.py 2017-06-18 10:59:59 UTC (rev 238033)
@@ -0,0 +1,2 @@
+SERVER_MODE = False
+HELP_PATH = "/usr/lib/pgadmin4/docs/en_US/_build/html/"
Deleted: community-x86_64/config_local.py
===================================================================
Copied: pgadmin4/repos/community-x86_64/config_local.py (from rev 238032, pgadmin4/trunk/config_local.py)
===================================================================
Deleted: community-x86_64/pgAdmin4.desktop
===================================================================
--- community-x86_64/pgAdmin4.desktop 2017-06-18 10:59:49 UTC (rev 238032)
+++ community-x86_64/pgAdmin4.desktop 2017-06-18 10:59:59 UTC (rev 238033)
@@ -1,11 +0,0 @@
-[Desktop Entry]
-Encoding=UTF-8
-Name=pgAdmin 4
-Exec=/usr/lib/pgadmin4/runtime/pgAdmin4
-Icon=pgAdmin4
-Type=Application
-Categories=Application;Development;
-MimeType=text/html
-DocPath=/usr/lib/pgadmin4/docs/en_US/_build/html/index.html
-Comment=PostgreSQL Tools
-Keywords=database;db;sql;query;administration;development;
Copied: pgadmin4/repos/community-x86_64/pgAdmin4.desktop (from rev 238032, pgadmin4/trunk/pgAdmin4.desktop)
===================================================================
--- community-x86_64/pgAdmin4.desktop (rev 0)
+++ community-x86_64/pgAdmin4.desktop 2017-06-18 10:59:59 UTC (rev 238033)
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Name=pgAdmin 4
+Exec=/usr/lib/pgadmin4/runtime/pgAdmin4
+Icon=pgAdmin4
+Type=Application
+Categories=Application;Development;
+MimeType=text/html
+DocPath=/usr/lib/pgadmin4/docs/en_US/_build/html/index.html
+Comment=PostgreSQL Tools
+Keywords=database;db;sql;query;administration;development;
More information about the arch-commits
mailing list