[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