diff --git a/runtime/BrowserWindow.cpp b/runtime/BrowserWindow.cpp index b5a840c46..954d75fc7 100644 --- a/runtime/BrowserWindow.cpp +++ b/runtime/BrowserWindow.cpp @@ -32,8 +32,12 @@ // Constructor -BrowserWindow::BrowserWindow() +BrowserWindow::BrowserWindow(quint16 port) { + // Setup the URL the browser will connect to + m_appServerUrl = QString("http://localhost:%1").arg(port); + + // Setup the UI createActions(); createMenus(); @@ -48,9 +52,9 @@ BrowserWindow::BrowserWindow() restoreState(settings.value("windowState").toByteArray()); // Display the app - m_initialload = true; - m_loadattempt = 1; - webView->setUrl(PGA_SERVER_URL); + m_initialLoad = true; + m_loadAttempt = 1; + webView->setUrl(QString("http://localhost/:%1").arg(9876)); } @@ -106,43 +110,38 @@ void BrowserWindow::createMenus() // Process loading finished signals from the web view. void BrowserWindow::finishLoading(bool ok) { - if (m_initialload && !ok) + if (m_initialLoad && !ok) { // The load attempt failed. Try again up to 4 times with an // incremental backoff. - if (m_loadattempt < 5) + if (m_loadAttempt < 5) { - qDebug() << "Initial load failed. Retrying in" << m_loadattempt << "seconds."; - - if (m_loadattempt == 1) + if (m_loadAttempt > 1) { - webView->setHtml(tr("
Connecting...
")); + qDebug() << "Initial connection failed. Retrying in" << m_loadAttempt << "seconds."; + webView->setHtml(QString(tr("Failed to connect to the pgAdmin application server. Retrying in %1 seconds, ") + + tr("or click here to try again now.
")).arg(m_loadAttempt).arg(m_appServerUrl)); } else { - webView->setHtml(QString(tr("Failed to connect to the pgAdmin application server. Retrying in %1 seconds, ") + - tr("or click here to try again now.
")).arg(m_loadattempt).arg(PGA_SERVER_URL)); + webView->setHtml(QString(tr("Connecting to the application server...
"))); } - pause(m_loadattempt); - webView->setUrl(PGA_SERVER_URL); - - // Even if the server comes up while we're looping, Linux won't - // properly display the HTML data unless we explicitly process events. - QCoreApplication::processEvents(QEventLoop::AllEvents, 100); + pause(m_loadAttempt); + webView->setUrl(m_appServerUrl); + m_loadAttempt++; - m_loadattempt++; return; } else { - qDebug() << "Initial page load failed after multiple attempts. Aborting."; + qDebug() << "Initial connection failed after multiple attempts. Aborting."; webView->setHtml(QString(tr("Failed to connect to the pgAdmin application server. ") + - tr("Click here to try again.
")).arg(PGA_SERVER_URL)); + tr("Click here to try again.")).arg(m_appServerUrl)); } } - m_initialload = false; + m_initialLoad = false; } diff --git a/runtime/BrowserWindow.h b/runtime/BrowserWindow.h index 33d9ac11a..d04ff4680 100644 --- a/runtime/BrowserWindow.h +++ b/runtime/BrowserWindow.h @@ -34,7 +34,7 @@ class BrowserWindow : public QMainWindow Q_OBJECT public: - BrowserWindow(); + BrowserWindow(quint16 port); protected: void closeEvent(QCloseEvent *event); @@ -47,6 +47,7 @@ private slots: void about(); private: + QString m_appServerUrl; QWebView *webView; QMenu *fileMenu; QMenu *helpMenu; @@ -54,8 +55,8 @@ private: QAction *exitAction; QAction *aboutAction; - bool m_initialload; - int m_loadattempt; + bool m_initialLoad; + int m_loadAttempt; void createActions(); void createMenus(); diff --git a/runtime/Server.cpp b/runtime/Server.cpp index 1521af1df..fece28c58 100644 --- a/runtime/Server.cpp +++ b/runtime/Server.cpp @@ -22,8 +22,11 @@ // App headers #include "Server.h" -Server::Server() +Server::Server(quint16 port) { + // Appserver port + m_port = port; + // Initialise Python Py_SetProgramName(PGA_APP_NAME.toUtf8().data()); Py_Initialize(); @@ -74,6 +77,9 @@ void Server::run() return; } + // Set the port number + PyRun_SimpleString(QString("PGADMIN_PORT = %1").arg(m_port).toLatin1()); + if (PyRun_SimpleFile(cp, m_appfile.toUtf8().data()) != 0) setError("Failed to launch the application server, server thread exiting."); diff --git a/runtime/Server.h b/runtime/Server.h index 21f3d7b42..73c06b7e5 100644 --- a/runtime/Server.h +++ b/runtime/Server.h @@ -23,7 +23,7 @@ class Server : public QThread Q_OBJECT public: - Server(); + Server(quint16 port); ~Server(); bool Init(); @@ -37,6 +37,8 @@ private: QString m_appfile; QString m_error; + + quint16 m_port; }; #endif // SERVER_H diff --git a/runtime/pgAdmin4.cpp b/runtime/pgAdmin4.cpp index 14c720893..8dd9a627d 100644 --- a/runtime/pgAdmin4.cpp +++ b/runtime/pgAdmin4.cpp @@ -38,13 +38,17 @@ int main(int argc, char * argv[]) QCoreApplication::setOrganizationDomain("pgadmin.org"); QCoreApplication::setApplicationName(PGA_APP_NAME); + // Find an unused port number. + QTcpSocket socket; + socket.bind(0, QAbstractSocket::DontShareAddress); + quint16 port = socket.localPort(); + // Fire up the webserver - // TODO: Find an unused port number to use - Server *server = new Server(); + Server *server = new Server(port); if (!server->Init()) { - qDebug() << server->getError(); + qDebug() << server->getError(); QString error("An error occurred initialising the application server:\n\n" + server->getError()); QMessageBox::critical(NULL, QString("Fatal Error"), error); @@ -55,11 +59,10 @@ int main(int argc, char * argv[]) server->start(); // Create & show the main window - BrowserWindow browserWindow; + BrowserWindow browserWindow(port); browserWindow.show(); // Go! return app.exec(); } - diff --git a/runtime/pgAdmin4.h b/runtime/pgAdmin4.h index 76a78ed92..f7576a157 100644 --- a/runtime/pgAdmin4.h +++ b/runtime/pgAdmin4.h @@ -28,7 +28,4 @@ // Application name const QString PGA_APP_NAME = QString("pgAdmin 4"); -// Server URL -const QString PGA_SERVER_URL = QString("http://127.0.0.1:8080"); - #endif // PGADMIN4_H diff --git a/web/pgAdmin4.py b/web/pgAdmin4.py index c812d1d4c..770514c5d 100755 --- a/web/pgAdmin4.py +++ b/web/pgAdmin4.py @@ -7,11 +7,14 @@ includedir = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect if includedir not in sys.path: sys.path.insert(0, includedir) -# Do some stuff +# Rock n' roll... import cherrypy from time import time,ctime -class HelloWorld(object): + +# This is the main application class that we'll run under CherryPy. For now, +# we'll just output some basic HTML so we can see that everything is running. +class pgAdmin4(object): def index(self): output = """ Today is %s @@ -21,6 +24,21 @@ Today is %s pgAdmin 4""" % ctime(time()) return output + index.exposed = True -cherrypy.quickstart(HelloWorld()) + +# Start the web server. The port number should have already been set by the +# runtime if we're running in desktop mode, otherwise we'll just use the +# CherryPy default. + +try: + cherrypy.server.socket_port = PGADMIN_PORT +except: + pass + +try: + cherrypy.quickstart(pgAdmin4()) +except IOError: + print "Unexpected error: ", sys.exc_info()[0] +