diff --git a/web/app/__init__.py b/web/app/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/web/config.py b/web/config.py
index 302626dd2..36ea7c2bb 100644
--- a/web/config.py
+++ b/web/config.py
@@ -31,12 +31,16 @@ APP_SUFFIX = 'dev'
# The application version string, constructed from the components
APP_VERSION = '%s.%s.%s-%s' % (APP_MAJOR, APP_MINOR, APP_REVISION, APP_SUFFIX)
+# DO NOT CHANGE!
+# List of modules to enable
+MODULES = [ 'utils' ]
+
##########################################################################
# Log settings
##########################################################################
# Debug mode?
-DEBUG = True
+DEBUG = False
# Application log level - one of:
# CRITICAL 50
@@ -47,7 +51,7 @@ DEBUG = True
# DEBUG 10
# NOTSET 0
CONSOLE_LOG_LEVEL = WARNING
-FILE_LOG_LEVEL = DEBUG
+FILE_LOG_LEVEL = INFO
# Log format.
CONSOLE_LOG_FORMAT='%(asctime)s: %(levelname)s\t%(name)s:\t%(message)s'
diff --git a/web/pgAdmin4.py b/web/pgAdmin4.py
old mode 100755
new mode 100644
index e4afd6cbf..bd593cc5b
--- a/web/pgAdmin4.py
+++ b/web/pgAdmin4.py
@@ -9,75 +9,24 @@
#
##########################################################################
-import logging
import os, sys
-from flask import Flask
-from time import time, ctime
# We need to include the root directory in sys.path to ensure that we can
# find everything we need when running in the standalone runtime.
-sys.path.append(os.path.dirname(__file__))
+sys.path.append(os.path.dirname(os.path.realpath(__file__)))
+sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'pgadmin'))
-# Configuration settings
import config
-
-# Setup the app object
-app = Flask(__name__, static_url_path='')
-
-##########################################################################
-# Setup logging and log the application startup
-##########################################################################
-
-# Add SQL level logging, and set the base logging level
-logging.addLevelName(25, 'SQL')
-app.logger.setLevel(logging.DEBUG)
-
-# We also need to update the handler on the webserver in order to see request.
-# Setting the level prevents werkzeug from setting up it's own stream handler
-# thus ensuring all the logging goes through the pgAdmin logger.
-logger = logging.getLogger('werkzeug')
-logger.setLevel(logging.INFO)
-
-# File logging
-fh = logging.FileHandler(config.LOG_FILE)
-fh.setLevel(config.FILE_LOG_LEVEL)
-fh.setFormatter(logging.Formatter(config.FILE_LOG_FORMAT))
-app.logger.addHandler(fh)
-logger.addHandler(fh)
-
-# Console logging
-ch = logging.StreamHandler()
-ch.setLevel(config.CONSOLE_LOG_LEVEL)
-ch.setFormatter(logging.Formatter(config.CONSOLE_LOG_FORMAT))
-app.logger.addHandler(ch)
-logger.addHandler(ch)
-
-app.logger.info('################################################################################')
-app.logger.info('Starting %s v%s...', config.APP_NAME, config.APP_VERSION)
-app.logger.info('################################################################################')
-
-# The main index page
-@app.route("/")
-def index():
-
- output = """
-Today is %s
-
-This is Flask-generated HTML.
-
-%s v%s""" % (ctime(time()), config.APP_NAME, config.APP_VERSION)
-
- return output
-
-# A special URL used to "ping" the server
-@app.route("/ping")
-def ping():
- return "PING"
+from pgadmin import create_app
##########################################################################
# Server starup
##########################################################################
+# Create the app!
+app = create_app()
+app.logger.debug("Python syspath: %s", sys.path)
+
# 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
# Flask default.
@@ -88,9 +37,8 @@ else:
app.logger.debug('PGADMIN_PORT is not set in the runtime environment, using default of %s', config.DEFAULT_SERVER_PORT)
server_port = config.DEFAULT_SERVER_PORT
-if __name__ == '__main__':
- try:
- app.run(port=server_port)
- except IOError:
- app.logger.error("Error starting the web server: %s", sys.exc_info())
+try:
+ app.run(port=server_port)
+except IOError:
+ app.logger.error("Error starting the app server: %s", sys.exc_info())
diff --git a/web/pgadmin/__init__.py b/web/pgadmin/__init__.py
new file mode 100644
index 000000000..4bdf4219e
--- /dev/null
+++ b/web/pgadmin/__init__.py
@@ -0,0 +1,63 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2014, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+# pgadmin/__init__.py - Main application startup
+#
+##########################################################################
+
+import logging
+import os, sys
+from flask import Flask
+from time import time, ctime
+
+# Configuration settings
+import config
+
+def create_app(app_name=config.APP_NAME):
+
+ # Setup the app object
+ app = Flask(__name__, static_url_path='')
+ app.config.from_object(config)
+
+ ##########################################################################
+ # Setup logging and log the application startup
+ ##########################################################################
+
+ # Add SQL level logging, and set the base logging level
+ logging.addLevelName(25, 'SQL')
+ app.logger.setLevel(logging.DEBUG)
+
+ # We also need to update the handler on the webserver in order to see request.
+ # Setting the level prevents werkzeug from setting up it's own stream handler
+ # thus ensuring all the logging goes through the pgAdmin logger.
+ logger = logging.getLogger('werkzeug')
+ logger.setLevel(logging.INFO)
+
+ # File logging
+ fh = logging.FileHandler(config.LOG_FILE)
+ fh.setLevel(config.FILE_LOG_LEVEL)
+ fh.setFormatter(logging.Formatter(config.FILE_LOG_FORMAT))
+ app.logger.addHandler(fh)
+ logger.addHandler(fh)
+
+ # Console logging
+ ch = logging.StreamHandler()
+ ch.setLevel(config.CONSOLE_LOG_LEVEL)
+ ch.setFormatter(logging.Formatter(config.CONSOLE_LOG_FORMAT))
+ app.logger.addHandler(ch)
+ logger.addHandler(ch)
+
+ # Log the startup
+ app.logger.info('################################################################################')
+ app.logger.info('Starting %s v%s...', config.APP_NAME, config.APP_VERSION)
+ app.logger.info('################################################################################')
+
+ # Register all the modules
+ for m in config.MODULES:
+ app.register_module(__import__('%s.views' % m).module)
+
+ return app
diff --git a/web/pgadmin/utils/__init__.py b/web/pgadmin/utils/__init__.py
new file mode 100644
index 000000000..369f9721e
--- /dev/null
+++ b/web/pgadmin/utils/__init__.py
@@ -0,0 +1,14 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2014, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+# utils/__init__.py - Initialise the module
+#
+##########################################################################
+
+from flask import Module
+
+module = Module(__name__, 'utils')
diff --git a/web/pgadmin/utils/views.py b/web/pgadmin/utils/views.py
new file mode 100644
index 000000000..a78a79a91
--- /dev/null
+++ b/web/pgadmin/utils/views.py
@@ -0,0 +1,36 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2014, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+# utils/views.py - Utility views
+#
+##########################################################################
+
+import config
+from utils import module
+from time import time, ctime
+
+##########################################################################
+# A test page
+##########################################################################
+@module.route("/test")
+def index():
+
+ output = """
+Today is %s
+
+This is Flask-generated HTML.
+
+%s v%s""" % (ctime(time()), config.APP_NAME, config.APP_VERSION)
+
+ return output
+
+##########################################################################
+# A special URL used to "ping" the server
+##########################################################################
+@module.route("/ping")
+def ping():
+ return "PING"