Fixed the letter case of the javascript file names.

Also, JSON data should be returned to the client using an
application/json MIME-TYPE using flask's jsonify function.
This commit is contained in:
Ronan Dunklau 2015-06-29 12:12:27 +05:30 committed by Ashesh Vashi
parent 751f8383fa
commit 9e0b011ec8
8 changed files with 144 additions and 161 deletions

View File

@ -22,21 +22,23 @@ from . import NODE_TYPE, sub_nodes
def register_submodules(app):
"""Register any child node blueprints"""
register_modules(app, __file__, all_nodes, sub_nodes, 'pgadmin.browser.server_groups')
def get_nodes():
"""Return a JSON document listing the server groups for the user"""
groups = ServerGroup.query.filter_by(user_id=current_user.id)
value = ''
# TODO: Move this JSON generation to a Server method
# this code is duplicated somewhere else
for group in groups:
value += '{"id":"%s/%d","label":"%s","icon":"icon-%s","inode":true,"_type":"%s"},' % (NODE_TYPE, group.id, group.name, NODE_TYPE, NODE_TYPE)
value = value[:-1]
return value
yield {
"id": "%s/%d" % (NODE_TYPE, group.id),
"label": group.name,
"icon": "icon-%s" % NODE_TYPE,
"inode": True,
"_type": NODE_TYPE
}
def get_standard_menu_items():
"""Return a (set) of dicts of standard menu items (create/drop/rename), with
"""Return a (set) of dicts of standard menu items (create/drop/rename), with
object type, action and the function name (no parens) to call on click."""
return [
{'type': 'server-group', 'action': 'drop', 'priority': 10, 'function': 'drop_server_group'},
@ -45,22 +47,22 @@ def get_standard_menu_items():
def get_create_menu_items():
"""Return a (set) of dicts of create menu items, with a Javascript array of
object types on which the option should appear, name, label and the function
"""Return a (set) of dicts of create menu items, with a Javascript array of
object types on which the option should appear, name, label and the function
name (no parens) to call on click."""
return [
{'type': "['server-group']", 'name': 'create_server_group', 'label': gettext('Server Group...'), 'priority': 10, 'function': 'create_server_group'}
]
def get_context_menu_items():
"""Return a (set) of dicts of content menu items with name, node type, label, priority and JS"""
return [
{'name': 'delete_server_group', 'type': NODE_TYPE, 'label': gettext('Delete server group'), 'priority': 10, 'onclick': 'drop_server_group(item);'},
{'name': 'rename_server_group', 'type': NODE_TYPE, 'label': gettext('Rename server group...'), 'priority': 20, 'onclick': 'rename_server_group(item);'}
]
def get_script_snippets():
"""Return the script snippets needed to handle treeview node operations."""
return render_template('server_groups/server_groups.js')
@ -72,5 +74,5 @@ def get_css_snippets():
css += " background: url('%s') 0 0 no-repeat !important;\n" % \
url_for('NODE-%s.static' % NODE_TYPE, filename='img/server-group.png')
css += "}\n"
return css

View File

@ -19,27 +19,30 @@ from . import NODE_TYPE
def get_nodes(server_group):
"""Return a JSON document listing the server groups for the user"""
servers = Server.query.filter_by(user_id=current_user.id, servergroup_id=server_group)
value = ''
for server in servers:
value += '{"id":"%s/%d","label":"%s","icon":"icon-%s","inode":true,"_type":"%s"},' % (NODE_TYPE, server.id, server.name, NODE_TYPE, NODE_TYPE)
value = value[:-1]
return value
# TODO: Move this JSON generation to a Server method
for server in servers:
yield {
"id": "%s/%d" % (NODE_TYPE, server.id),
"label": server.name,
"icon": "icon-%s" % NODE_TYPE,
"inode": True,
"_type": NODE_TYPE
}
def get_standard_menu_items():
"""Return a (set) of dicts of standard menu items (create/drop/rename), with
"""Return a (set) of dicts of standard menu items (create/drop/rename), with
object type, action, priority and the function to call on click."""
return [
{'type': 'server', 'action': 'drop', 'priority': 50, 'function': 'drop_server'},
{'type': 'server', 'action': 'rename', 'priority': 60, 'function': 'rename_server'}
]
def get_create_menu_items():
"""Return a (set) of dicts of create menu items, with a Javascript array of
object types on which the option should appear, name, label, priority and
"""Return a (set) of dicts of create menu items, with a Javascript array of
object types on which the option should appear, name, label, priority and
the function name (no parens) to call on click."""
return [
{'type': "['server-group', 'server']", 'name': 'create_server', 'label': gettext('Server...'), 'priority': 50, 'function': 'create_server'}
@ -52,8 +55,8 @@ def get_context_menu_items():
{'name': 'delete_server', 'type': NODE_TYPE, 'label': gettext('Delete server'), 'priority': 50, 'onclick': 'drop_server(item);'},
{'name': 'rename_server', 'type': NODE_TYPE, 'label': gettext('Rename server...'), 'priority': 60, 'onclick': 'rename_server(item);'}
]
def get_script_snippets():
"""Return the script snippets needed to handle treeview node operations."""
return render_template('servers/servers.js')
@ -65,5 +68,5 @@ def get_css_snippets():
css += " background: url('%s') 0 0 no-repeat !important;\n" % \
url_for('NODE-%s.static' % NODE_TYPE, filename='img/server.png')
css += "}\n"
return css

View File

@ -9,17 +9,22 @@
"""Defines views for management of servers"""
from flask import Blueprint, Response, current_app, request
from flask import Blueprint, request
from flask.ext.babel import gettext
from flask.ext.security import current_user, login_required
from . import NODE_TYPE, NODE_PATH
from pgadmin.utils.ajax import make_json_response
from pgadmin.settings.settings_model import db, ServerGroup
import config
from pgadmin.settings.settings_model import db, Server
import traceback
# Initialise the module
blueprint = Blueprint("NODE-" + NODE_TYPE, __name__, static_folder='static', static_url_path='', template_folder='templates', url_prefix=NODE_PATH)
blueprint = Blueprint("NODE-" + NODE_TYPE, __name__,
static_folder='static',
static_url_path='',
template_folder='templates',
url_prefix=NODE_PATH)
@blueprint.route('/add/', methods=['POST'])
@login_required
@ -27,30 +32,29 @@ def add():
"""Add a server node to the settings database"""
success = 1
errormsg = ''
data = { }
data = {}
success = False
errormsg = ''
if request.form['name'] != '':
server = Server(user_id=current_user.id, name=request.form['name'])
try:
db.session.add(server)
db.session.commit()
success = True
except Exception as e:
success = 0
errormsg = e.message
else:
success = 0
errormsg = gettext('No server name was specified')
if success == 1:
if success:
data['id'] = server.id
data['name'] = server.name
return make_json_response(success=success,
errormsg=errormsg,
info=traceback.format_exc(),
result=request.form,
return make_json_response(success=success,
errormsg=errormsg,
info=traceback.format_exc(),
result=request.form,
data=data)
@blueprint.route('/delete/', methods=['POST'])
@ -63,7 +67,7 @@ def delete():
if request.form['id'] != '':
# There can be only one record at most
servergroup = Server.query.filter_by(user_id=current_user.id, id=int(request.form['id'])).first()
if server is None:
success = 0
errormsg = gettext('The specified server could not be found.')
@ -78,10 +82,10 @@ def delete():
else:
success = 0
errormsg = gettext('No server was specified.')
return make_json_response(success=success,
errormsg=errormsg,
info=traceback.format_exc(),
return make_json_response(success=success,
errormsg=errormsg,
info=traceback.format_exc(),
result=request.form)
@blueprint.route('/rename/', methods=['POST'])
@ -94,7 +98,7 @@ def rename():
if request.form['id'] != '':
# There can be only one record at most
servergroup = Server.query.filter_by(user_id=current_user.id, id=int(request.form['id'])).first()
if server is None:
success = 0
errormsg = gettext('The specified server could not be found.')
@ -109,9 +113,9 @@ def rename():
else:
success = 0
errormsg = gettext('No server was specified.')
return make_json_response(success=success,
errormsg=errormsg,
info=traceback.format_exc(),
return make_json_response(success=success,
errormsg=errormsg,
info=traceback.format_exc(),
result=request.form)

View File

@ -26,24 +26,13 @@ blueprint = Blueprint("NODE-" + NODE_TYPE, __name__, static_folder='static', st
@login_required
def get_nodes(server_group):
"""Build a list of treeview nodes from the child nodes."""
value = '['
nodes = []
for node in sub_nodes:
if 'hooks' in dir(node) and 'get_nodes' in dir(node.hooks):
value += node.hooks.get_nodes(server_group) + ','
if value[-1:] == ',':
value = value[:-1]
value += ']'
resp = Response(response=value,
status=200,
mimetype="text/json")
return resp
if hasattr(node, 'hooks') and hasattr(node.hooks, 'get_nodes'):
nodes.extend(node.hooks.get_nodes(server_group))
return make_json_response(data=nodes)
@blueprint.route('/add/', methods=['POST'])
@login_required
def add():
@ -51,7 +40,7 @@ def add():
success = 1
errormsg = ''
data = { }
if request.form['name'] != '':
servergroup = ServerGroup(user_id=current_user.id, name=request.form['name'])
@ -65,15 +54,15 @@ def add():
else:
success = 0
errormsg = gettext('No server group name was specified')
if success == 1:
data['id'] = servergroup.id
data['name'] = servergroup.name
return make_json_response(success=success,
errormsg=errormsg,
info=traceback.format_exc(),
result=request.form,
return make_json_response(success=success,
errormsg=errormsg,
info=traceback.format_exc(),
result=request.form,
data=data)
@blueprint.route('/delete/', methods=['POST'])
@ -86,7 +75,7 @@ def delete():
if request.form['id'] != '':
# There can be only one record at most
servergroup = ServerGroup.query.filter_by(user_id=current_user.id, id=int(request.form['id'])).first()
if servergroup is None:
success = 0
errormsg = gettext('The specified server group could not be found.')
@ -101,10 +90,10 @@ def delete():
else:
success = 0
errormsg = gettext('No server group was specified.')
return make_json_response(success=success,
errormsg=errormsg,
info=traceback.format_exc(),
return make_json_response(success=success,
errormsg=errormsg,
info=traceback.format_exc(),
result=request.form)
@blueprint.route('/rename/', methods=['POST'])
@ -117,7 +106,7 @@ def rename():
if request.form['id'] != '':
# There can be only one record at most
servergroup = ServerGroup.query.filter_by(user_id=current_user.id, id=int(request.form['id'])).first()
if servergroup is None:
success = 0
errormsg = gettext('The specified server group could not be found.')
@ -132,9 +121,9 @@ def rename():
else:
success = 0
errormsg = gettext('No server group was specified.')
return make_json_response(success=success,
errormsg=errormsg,
info=traceback.format_exc(),
return make_json_response(success=success,
errormsg=errormsg,
info=traceback.format_exc(),
result=request.form)

View File

@ -292,7 +292,12 @@ ALTER TABLE tickets_detail \n\
// Initialise the treeview
$('#tree').aciTree({
ajax: {
url: '{{ url_for('browser.get_nodes') }}'
url: '{{ url_for('browser.get_nodes') }}',
converters: {
'text json': function(payload) {
return $.parseJSON(payload).data;
}
}
},
});
tree = $('#tree').aciTree('api');

View File

@ -20,6 +20,7 @@ from . import sub_nodes
from pgadmin.browser import all_nodes
from pgadmin import modules
from pgadmin.settings import get_setting
from pgadmin.utils.ajax import make_json_response
import config
@ -50,7 +51,7 @@ def index():
scripts = [ ]
modules_and_nodes = modules + all_nodes
# Add browser stylesheets
stylesheets.append(url_for('static', filename='css/codemirror/codemirror.css'))
@ -60,32 +61,32 @@ def index():
stylesheets.append(url_for('static', filename='css/wcDocker/wcDockerSkeleton.min.css'))
stylesheets.append(url_for('static', filename='css/wcDocker/theme.css'))
stylesheets.append(url_for('static', filename='css/jQuery-contextMenu/jQuery.contextMenu.css'))
stylesheets.append(url_for('static', filename='css/jQuery-contextMenu/jquery.contextMenu.css'))
stylesheets.append(url_for('browser.static', filename='css/browser.css'))
stylesheets.append(url_for('browser.static', filename='css/aciTree/css/aciTree.css'))
stylesheets.append(url_for('browser.browser_css'))
# Add browser scripts
scripts.append(url_for('static', filename='js/codemirror/codemirror.js'))
scripts.append(url_for('static', filename='js/codemirror/mode/sql.js'))
if config.DEBUG:
scripts.append(url_for('static', filename='js/wcDocker/wcDocker.js'))
else:
scripts.append(url_for('static', filename='js/wcDocker/wcDocker.min.js'))
scripts.append(url_for('static', filename='js/jQuery-contextMenu/jquery.ui.position.js'))
scripts.append(url_for('static', filename='js/jQuery-contextMenu/jQuery.contextMenu.js'))
scripts.append(url_for('static', filename='js/jQuery-contextMenu/jquery.contextMenu.js'))
scripts.append(url_for('browser.static', filename='js/aciTree/jquery.aciPlugin.min.js'))
scripts.append(url_for('browser.static', filename='js/aciTree/jquery.aciTree.dom.js'))
scripts.append(url_for('browser.static', filename='js/aciTree/jquery.aciTree.min.js'))
scripts.append(url_for('browser.browser_js'))
for module in modules_and_nodes:
# Get the edit menu items
if 'hooks' in dir(module) and 'get_file_menu_items' in dir(module.hooks):
file_items.extend(module.hooks.get_file_menu_items())
# Get the edit menu items
if 'hooks' in dir(module) and 'get_edit_menu_items' in dir(module.hooks):
edit_items.extend(module.hooks.get_edit_menu_items())
@ -97,30 +98,30 @@ def index():
# Get the management menu items
if 'hooks' in dir(module) and 'get_management_menu_items' in dir(module.hooks):
management_items.extend(module.hooks.get_management_menu_items())
# Get the help menu items
if 'hooks' in dir(module) and 'get_help_menu_items' in dir(module.hooks):
help_items.extend(module.hooks.get_help_menu_items())
# Get any stylesheets
if 'hooks' in dir(module) and 'get_stylesheets' in dir(module.hooks):
stylesheets += module.hooks.get_stylesheets()
# Get any scripts
if 'hooks' in dir(module) and 'get_scripts' in dir(module.hooks):
scripts += module.hooks.get_scripts()
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'])
management_items = sorted(management_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,
return render_template(MODULE_NAME + '/index.html',
username=current_user.email,
file_items=file_items,
edit_items=edit_items,
tools_items=tools_items,
management_items=management_items,
help_items=help_items,
stylesheets = stylesheets,
@ -132,15 +133,15 @@ def browser_js():
"""Render and return JS snippets from the nodes and modules."""
snippets = ''
modules_and_nodes = modules + all_nodes
# Load the core browser code first
# Get the context menu items
standard_items = [ ]
create_items = [ ]
context_items = [ ]
panel_items = [ ]
for module in modules_and_nodes:
# Get any standard menu items
if 'hooks' in dir(module) and 'get_standard_menu_items' in dir(module.hooks):
@ -149,11 +150,11 @@ def browser_js():
# Get any create menu items
if 'hooks' in dir(module) and 'get_create_menu_items' in dir(module.hooks):
create_items.extend(module.hooks.get_create_menu_items())
# Get any context menu items
if 'hooks' in dir(module) and 'get_context_menu_items' in dir(module.hooks):
context_items.extend(module.hooks.get_context_menu_items())
# Get any panels
if 'hooks' in dir(module) and 'get_panels' in dir(module.hooks):
panel_items += module.hooks.get_panels()
@ -162,25 +163,25 @@ def browser_js():
create_items = sorted(create_items, key=lambda k: k['priority'])
context_items = sorted(context_items, key=lambda k: k['priority'])
panel_items = sorted(panel_items, key=lambda k: k['priority'])
layout = get_setting('Browser/Layout', default='')
snippets += render_template('browser/js/browser.js',
snippets += render_template('browser/js/browser.js',
layout = layout,
standard_items = standard_items,
create_items = create_items,
context_items = context_items,
panel_items = panel_items)
# Add module and node specific code
for module in modules_and_nodes:
if 'hooks' in dir(module) and 'get_script_snippets' in dir(module.hooks):
snippets += module.hooks.get_script_snippets()
resp = Response(response=snippets,
status=200,
mimetype="application/javascript")
return resp
@blueprint.route("/browser.css")
@ -189,15 +190,15 @@ def browser_css():
"""Render and return CSS snippets from the nodes and modules."""
snippets = ''
modules_and_nodes = modules + all_nodes
for module in modules_and_nodes:
if 'hooks' in dir(module) and 'get_css_snippets' in dir(module.hooks):
snippets += module.hooks.get_css_snippets()
resp = Response(response=snippets,
status=200,
mimetype="text/css")
return resp
@ -206,21 +207,8 @@ def browser_css():
def get_nodes():
"""Build a list of treeview nodes from the child nodes."""
value = '['
nodes = []
for node in sub_nodes:
if 'hooks' in dir(node) and 'get_nodes' in dir(node.hooks):
value += node.hooks.get_nodes() + ','
if value[-1:] == ',':
value = value[:-1]
value += ']'
resp = Response(response=value,
status=200,
mimetype="text/json")
return resp
if hasattr(node, 'hooks') and hasattr(node.hooks, 'get_nodes'):
nodes.extend(node.hooks.get_nodes())
return make_json_response(data=nodes)

View File

@ -9,7 +9,7 @@
"""Defines the models for the configuration database.
If any of the models are updated, you (yes, you, the developer) MUST do two
If any of the models are updated, you (yes, you, the developer) MUST do two
things:
1) Increment SETTINGS_SCHEMA_VERSION in config.py
@ -28,12 +28,13 @@ roles_users = db.Table('roles_users',
db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))
class Version(db.Model):
"""Version numbers for reference/upgrade purposes"""
__tablename__ = 'version'
name = db.Column(db.String(32), primary_key=True)
value = db.Column(db.Integer(), nullable=False)
class Role(db.Model, RoleMixin):
"""Define a security role"""
__tablename__ = 'role'
@ -51,7 +52,7 @@ class User(db.Model, UserMixin):
confirmed_at = db.Column(db.DateTime())
roles = db.relationship('Role', secondary=roles_users,
backref=db.backref('users', lazy='dynamic'))
class Setting(db.Model):
"""Define a setting object"""
__tablename__ = 'setting'
@ -66,7 +67,7 @@ class ServerGroup(db.Model):
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
name = db.Column(db.String(128), nullable=False)
__table_args__ = (db.UniqueConstraint('user_id', 'name'),)
class Server(db.Model):
"""Define a registered Postgres server"""
@ -80,5 +81,3 @@ class Server(db.Model):
maintenance_db = db.Column(db.String(64), nullable=False)
username = db.Column(db.String(64), nullable=False)
ssl_mode = db.Column(db.String(16), nullable=False)

View File

@ -9,20 +9,13 @@
"""Utility functions for dealing with AJAX."""
from flask import Response
from flask import jsonify
import json
def make_json_response(success=1, errormsg='', info='', result={}, data={}):
def make_json_response(success=True, **kwargs):
"""Create a HTML response document describing the results of a request and
containing the data."""
doc = { }
doc['success'] = success
doc['errormsg'] = errormsg
doc['info'] = info
doc['result'] = result
doc['data'] = data
response = Response(response=json.dumps(doc),
status=200,
mimetype="text/json")
return response
response = kwargs.copy()
response.setdefault('result', {})
response.setdefault('data', {})
return jsonify(response)