mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2024-11-24 09:40:21 -06:00
Add automatic browser menu integration for modules.
Modules may now include functions that return lists of menu items that will be included on the main browser window menu. While we're at it, move the test views into a separate module.
This commit is contained in:
parent
0cff5fca2c
commit
d492da3ca1
@ -17,11 +17,14 @@ from flask_security.utils import login_user
|
|||||||
from flask_mail import Mail
|
from flask_mail import Mail
|
||||||
from settings_model import db, Role, User
|
from settings_model import db, Role, User
|
||||||
|
|
||||||
import inspect, logging, os
|
import inspect, imp, logging, os
|
||||||
|
|
||||||
# Configuration settings
|
# Configuration settings
|
||||||
import config
|
import config
|
||||||
|
|
||||||
|
# Global module list
|
||||||
|
modules = [ ]
|
||||||
|
|
||||||
def create_app(app_name=config.APP_NAME):
|
def create_app(app_name=config.APP_NAME):
|
||||||
"""Create the Flask application, startup logging and dynamically load
|
"""Create the Flask application, startup logging and dynamically load
|
||||||
additional modules (blueprints) that are found in this directory."""
|
additional modules (blueprints) that are found in this directory."""
|
||||||
@ -88,6 +91,7 @@ def create_app(app_name=config.APP_NAME):
|
|||||||
|
|
||||||
path = os.path.dirname(os.path.realpath(__file__))
|
path = os.path.dirname(os.path.realpath(__file__))
|
||||||
files = os.listdir(path)
|
files = os.listdir(path)
|
||||||
|
|
||||||
for f in files:
|
for f in files:
|
||||||
d = os.path.join(path, f)
|
d = os.path.join(path, f)
|
||||||
if os.path.isdir(d) and os.path.isfile(os.path.join(d, '__init__.py')):
|
if os.path.isdir(d) and os.path.isfile(os.path.join(d, '__init__.py')):
|
||||||
@ -98,10 +102,16 @@ def create_app(app_name=config.APP_NAME):
|
|||||||
|
|
||||||
# Looks like a module, so import it, and register the blueprint if present
|
# Looks like a module, so import it, and register the blueprint if present
|
||||||
# We rely on the ordering of syspath to ensure we actually get the right
|
# We rely on the ordering of syspath to ensure we actually get the right
|
||||||
# module here.
|
# module here. Note that we also try to load the 'browser' module for
|
||||||
|
# the browser integration hooks.
|
||||||
app.logger.info('Examining potential module: %s' % d)
|
app.logger.info('Examining potential module: %s' % d)
|
||||||
module = __import__(f, globals(), locals(), ['views'], -1)
|
module = __import__(f, globals(), locals(), ['browser', 'views'], -1)
|
||||||
if hasattr(module.views, 'blueprint'):
|
|
||||||
|
# Add the module to the global module list
|
||||||
|
modules.append(module)
|
||||||
|
|
||||||
|
# Register the blueprint if present
|
||||||
|
if 'views' in dir(module) and 'blueprint' in dir(module.views):
|
||||||
app.logger.info('Registering blueprint module: %s' % f)
|
app.logger.info('Registering blueprint module: %s' % f)
|
||||||
app.register_blueprint(module.views.blueprint)
|
app.register_blueprint(module.views.blueprint)
|
||||||
|
|
||||||
|
0
web/pgadmin/about/__init__.py
Normal file
0
web/pgadmin/about/__init__.py
Normal file
18
web/pgadmin/about/browser.py
Normal file
18
web/pgadmin/about/browser.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2014, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
"""Browser integration functions for the About module."""
|
||||||
|
|
||||||
|
from flask import url_for
|
||||||
|
|
||||||
|
import config
|
||||||
|
|
||||||
|
def get_help_menu_items():
|
||||||
|
"""Return a (set) of dicts of help menu items, with name, priority and URL."""
|
||||||
|
return [{'name': 'About %s' % (config.APP_NAME), 'priority': 999, 'url': url_for('about.index')}]
|
1
web/pgadmin/about/templates/about/index.html
Normal file
1
web/pgadmin/about/templates/about/index.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
About {{ config.APP_NAME }}
|
27
web/pgadmin/about/views.py
Normal file
27
web/pgadmin/about/views.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2014, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
"""A blueprint module implementing the about box."""
|
||||||
|
MODULE_NAME = 'about'
|
||||||
|
|
||||||
|
import config
|
||||||
|
from flask import Blueprint, current_app, render_template
|
||||||
|
from flask.ext.security import login_required
|
||||||
|
|
||||||
|
# Initialise the module
|
||||||
|
blueprint = Blueprint(MODULE_NAME, __name__, static_folder='static', static_url_path='', template_folder='templates', url_prefix='/' + MODULE_NAME)
|
||||||
|
|
||||||
|
##########################################################################
|
||||||
|
# A test page
|
||||||
|
##########################################################################
|
||||||
|
@blueprint.route("/")
|
||||||
|
@login_required
|
||||||
|
def index():
|
||||||
|
"""Render the about box."""
|
||||||
|
return render_template(MODULE_NAME + '/index.html')
|
@ -16,18 +16,40 @@
|
|||||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||||
|
|
||||||
<ul class="nav navbar-nav">
|
<ul class="nav navbar-nav">
|
||||||
|
|
||||||
<li class="dropdown">
|
<li class="dropdown">
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">File <span class="caret"></span></a>
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">File <span class="caret"></span></a>
|
||||||
<ul class="dropdown-menu" role="menu">
|
<ul class="dropdown-menu" role="menu">
|
||||||
<li><a href="{{ url_for('utils.test') }}">Test URL</a></li>
|
{% for file_item in file_items %}
|
||||||
<li><a href="{{ url_for('utils.ping') }}">Ping</a></li>
|
<li><a href="{{ file_item.url }}">{{ file_item.name|safe }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li class="dropdown">
|
||||||
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Edit <span class="caret"></span></a>
|
||||||
|
<ul class="dropdown-menu" role="menu">
|
||||||
|
{% for edit_item in edit_items %}
|
||||||
|
<li><a href="{{ edit_item.url }}">{{ edit_item.name|safe }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dropdown">
|
||||||
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Tools <span class="caret"></span></a>
|
||||||
|
<ul class="dropdown-menu" role="menu">
|
||||||
|
{% for tools_item in tools_items %}
|
||||||
|
<li><a href="{{ tools_item.url }}">{{ tools_item.name|safe }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li class="dropdown">
|
<li class="dropdown">
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Help <span class="caret"></span></a>
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Help <span class="caret"></span></a>
|
||||||
<ul class="dropdown-menu" role="menu">
|
<ul class="dropdown-menu" role="menu">
|
||||||
|
{% for help_item in help_items %}
|
||||||
|
<li><a href="{{ help_item.url }}">{{ help_item.name|safe }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
@ -10,11 +10,15 @@
|
|||||||
"""A blueprint module implementing the core pgAdmin browser."""
|
"""A blueprint module implementing the core pgAdmin browser."""
|
||||||
MODULE_NAME = 'browser'
|
MODULE_NAME = 'browser'
|
||||||
|
|
||||||
import config
|
|
||||||
from flask import Blueprint, current_app, render_template
|
from flask import Blueprint, current_app, render_template
|
||||||
from flaskext.gravatar import Gravatar
|
from flaskext.gravatar import Gravatar
|
||||||
from flask.ext.security import login_required
|
from flask.ext.security import login_required
|
||||||
from flask.ext.login import current_user
|
from flask.ext.login import current_user
|
||||||
|
from inspect import getmoduleinfo, getmembers
|
||||||
|
|
||||||
|
from pgadmin import modules
|
||||||
|
|
||||||
|
import config
|
||||||
|
|
||||||
# Initialise the module
|
# Initialise the module
|
||||||
blueprint = Blueprint(MODULE_NAME, __name__, static_folder='static', static_url_path='', template_folder='templates', url_prefix='/' + MODULE_NAME)
|
blueprint = Blueprint(MODULE_NAME, __name__, static_folder='static', static_url_path='', template_folder='templates', url_prefix='/' + MODULE_NAME)
|
||||||
@ -26,6 +30,7 @@ blueprint = Blueprint(MODULE_NAME, __name__, static_folder='static', static_url
|
|||||||
@login_required
|
@login_required
|
||||||
def index():
|
def index():
|
||||||
"""Render and process the main browser window."""
|
"""Render and process the main browser window."""
|
||||||
|
# Get the Gravatar
|
||||||
gravatar = Gravatar(current_app,
|
gravatar = Gravatar(current_app,
|
||||||
size=100,
|
size=100,
|
||||||
rating='g',
|
rating='g',
|
||||||
@ -34,4 +39,37 @@ def index():
|
|||||||
use_ssl=False,
|
use_ssl=False,
|
||||||
base_url=None)
|
base_url=None)
|
||||||
|
|
||||||
return render_template(MODULE_NAME + '/index.html', username=current_user.email)
|
# Get the menu items from the module
|
||||||
|
file_items = [ ]
|
||||||
|
edit_items = [ ]
|
||||||
|
tools_items = [ ]
|
||||||
|
help_items = [ ]
|
||||||
|
|
||||||
|
for module in modules:
|
||||||
|
# Get the edit menu items
|
||||||
|
if 'browser' in dir(module) and 'get_file_menu_items' in dir(module.browser):
|
||||||
|
file_items.extend(module.browser.get_file_menu_items())
|
||||||
|
|
||||||
|
# Get the edit menu items
|
||||||
|
if 'browser' in dir(module) and 'get_edit_menu_items' in dir(module.browser):
|
||||||
|
edit_items.extend(module.browser.get_edit_menu_items())
|
||||||
|
|
||||||
|
# Get the tools menu items
|
||||||
|
if 'browser' in dir(module) and 'get_tools_menu_items' in dir(module.browser):
|
||||||
|
tools_items.extend(module.browser.get_tools_menu_items())
|
||||||
|
|
||||||
|
# Get the help menu items
|
||||||
|
if 'browser' in dir(module) and 'get_help_menu_items' in dir(module.browser):
|
||||||
|
help_items.extend(module.browser.get_help_menu_items())
|
||||||
|
|
||||||
|
file_items = sorted(file_items, key=lambda k: k['priority'])
|
||||||
|
edit_items = sorted(edit_items, key=lambda k: k['priority'])
|
||||||
|
tools_items = sorted(tools_items, key=lambda k: k['priority'])
|
||||||
|
help_items = sorted(help_items, key=lambda k: k['priority'])
|
||||||
|
|
||||||
|
return render_template(MODULE_NAME + '/index.html',
|
||||||
|
username=current_user.email,
|
||||||
|
file_items=file_items,
|
||||||
|
edit_items=edit_items,
|
||||||
|
tools_items=tools_items,
|
||||||
|
help_items=help_items)
|
||||||
|
0
web/pgadmin/test/__init__.py
Normal file
0
web/pgadmin/test/__init__.py
Normal file
16
web/pgadmin/test/browser.py
Normal file
16
web/pgadmin/test/browser.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2014, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
"""Browser integration functions for the Test module."""
|
||||||
|
|
||||||
|
from flask import url_for
|
||||||
|
|
||||||
|
def get_file_menu_items():
|
||||||
|
"""Return a (set) of dicts of file menu items, with name, priority and URL."""
|
||||||
|
return [{'name': 'Generated Test HTML', 'priority': 100, 'url': url_for('test.generated')}]
|
35
web/pgadmin/test/views.py
Normal file
35
web/pgadmin/test/views.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2014, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
"""A blueprint module providing utility functions for the application."""
|
||||||
|
MODULE_NAME = 'test'
|
||||||
|
|
||||||
|
import config
|
||||||
|
from flask import Blueprint, render_template
|
||||||
|
from flask.ext.security import login_required
|
||||||
|
from time import time, ctime
|
||||||
|
|
||||||
|
# Initialise the module
|
||||||
|
blueprint = Blueprint(MODULE_NAME, __name__, static_folder='static', static_url_path='', template_folder='templates', url_prefix='/' + MODULE_NAME)
|
||||||
|
|
||||||
|
##########################################################################
|
||||||
|
# A test page
|
||||||
|
##########################################################################
|
||||||
|
@blueprint.route("/generated")
|
||||||
|
@login_required
|
||||||
|
def generated():
|
||||||
|
"""Generate a simple test page to demonstrate that output can be rendered."""
|
||||||
|
output = """
|
||||||
|
Today is <b>%s</b>
|
||||||
|
<br />
|
||||||
|
<i>This is Flask-generated HTML.</i>
|
||||||
|
<br /><br />
|
||||||
|
<a href="http://www.pgadmin.org/">%s v%s</a>""" % (ctime(time()), config.APP_NAME, config.APP_VERSION)
|
||||||
|
|
||||||
|
return output
|
@ -18,22 +18,6 @@ from time import time, ctime
|
|||||||
# Initialise the module
|
# Initialise the module
|
||||||
blueprint = Blueprint(MODULE_NAME, __name__, static_folder='static', static_url_path='', template_folder='templates', url_prefix='/' + MODULE_NAME)
|
blueprint = Blueprint(MODULE_NAME, __name__, static_folder='static', static_url_path='', template_folder='templates', url_prefix='/' + MODULE_NAME)
|
||||||
|
|
||||||
##########################################################################
|
|
||||||
# A test page
|
|
||||||
##########################################################################
|
|
||||||
@blueprint.route("/test")
|
|
||||||
@login_required
|
|
||||||
def test():
|
|
||||||
"""Generate a simple test page to demonstrate that output can be rendered."""
|
|
||||||
output = """
|
|
||||||
Today is <b>%s</b>
|
|
||||||
<br />
|
|
||||||
<i>This is Flask-generated HTML.</i>
|
|
||||||
<br /><br />
|
|
||||||
<a href="http://www.pgadmin.org/">%s v%s</a>""" % (ctime(time()), config.APP_NAME, config.APP_VERSION)
|
|
||||||
|
|
||||||
return output
|
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# A special URL used to "ping" the server
|
# A special URL used to "ping" the server
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
Loading…
Reference in New Issue
Block a user