""" plugin_dbui.py Controllers expose by the plugin: index database configuration Author: R. Le Gac """ import json import os API = """ App.csvUrl = '/%s/plugin_dbui/csv'; App.config = %s; App.debug = %s; App.name = '%s'; App.REMOTE_API = { 'url': '/%s/plugin_dbui/call', 'type': 'remoting', 'actions': %s };""" def about(): fn = os.path.join("applications", request.application, "static", "ABOUT.html") return open(fn, 'rb').read() def call(): """Action to handle the Ext.Direct protocol. """ return directSvc() def csv(): """Action returning the content of a table as a CSV file. Foreign keys are replaced by the parent column. """ from gluon.contenttype import contenttype from plugin_dbui import (get_foreign_field, get_where_query, is_foreign_field, is_table_with_foreign_fields) tablename = request.vars['tableName'] response.headers['Content-Type'] = contenttype('.csv') response.headers['Content-Disposition'] = 'attachment; filename=%s.csv;' % tablename table = db[tablename] query = table.id > 0 # replace foreign key by parent fields # and build the query to resolve foreign keys if is_table_with_foreign_fields(table): fields = [] query = ((query) & (get_where_query(table))) for field in table: if is_foreign_field(field): k_table, k_field, k_key = get_foreign_field(field) fields.append(db[k_table][k_field]) else: fields.append(field) else: fields = [table.ALL] # interrogate the database rows = db(query).select(*fields) return str(rows) def dbui_conf(): """Action returning the javascript script configuring the plugin dbui: application name, store definition,... """ from gluon.contrib import simplejson as json from plugin_dbui import (DBUI, get_all_tables, to_jsonstore, to_model, to_treeNodes, to_viewport) di = {} # build the dictionary required by Ext.direct # containing the definition of the remote procedure for (k, f) in directSvc.procedures.iteritems(): action, method = k.split('.') if action == DBUI: nargs = f.func_code.co_argcount else: nargs = f.__func__.func_code.co_argcount - 1 if action not in di: di[action] = [] di[action].append({'name': method, 'len': nargs}) # the definition of the models config = {'models': {}, 'stores': {}, 'treeNodes': [], 'viewport': None} for table in get_all_tables(db): config['models'][table._tablename] = to_model(table) # the stores configuration (static, for each table,...) # NOTE: the interface require a store for all tables including alias. # The only way to extract them is to scan the attributes list of # the DAL since the method db.tables() or any variant return # tables but not the alias one config['stores'].update(plugins.dbui.static_stores) for table in get_all_tables(db): cfg = to_jsonstore(table) config['stores'][cfg['storeId']] = cfg # the tree nodes configuration for the TreeStore config['treeNodes'] = to_treeNodes() # the viewport configuration config['viewport'] = to_viewport() # debug mode debug = 'false' if 'debug' in request.vars: debug = 'true' # fill the javascript template app = request.application script = API % (app, json.dumps(config), debug, app, app, json.dumps(di)) # return the response as a javascript response.headers['Content-Type'] = 'text/javascript' return script def debug(): """Action to run the plugin in debug mode. Load dynamically the javascript source code for all libraries. Active the debug mode on the server and client side. EXAMPLES http://localhost:8000/myapp/plugin_dbui/debug http://localhost:8000/myapp/plugin_dbui/debug?script=foo URL OPTIONS script run the javascript foo in the framework defined by the plugin. The scripts are stored in the directory defined by the plugin configuration app_script_dir. """ from plugin_dbui import get_file_paths, get_script_path plugin = plugins.dbui # css files response.files.extend(get_file_paths(plugin.extjs_css, ext='.css')) response.files.extend(get_file_paths(plugin.dbui_css, ext='.css')) response.files.extend(get_file_paths(plugin.ace_css, ext='.css')) response.files.extend(get_file_paths(plugin.app_css, ext='.css')) # debug version of the javascript libraries response.files.extend(get_file_paths(plugin.ace_libmin, ext='.js')) response.files.extend(get_file_paths(plugin.mathjax_libmin, ext='.js')) response.files.extend(get_file_paths(plugin.extjs_debug, ext='.js')) response.files.extend(get_file_paths(plugin.dbui_debug, ext='.js')) response.files.extend(get_file_paths(plugin.app_debug, ext='.js')) # language files response.files.extend(get_file_paths(plugin.extjs_lg, ext='.js')) response.files.extend(get_file_paths(plugin.dbui_lg, ext='.js')) response.files.extend(get_file_paths(plugin.app_lg, ext='.js')) # URL for the dbui configuration activating the debug # mode on the client side response.files.append(plugin.dbui_conf_debug) # main script which can be defined in many different ways pscript = get_script_path(plugin) response.files.append(pscript) # switch ON the debug mode on the server side session.debug = True # select the view response.view = 'plugin_dbui/index.html' # return the plugin configuration parameter as well as the response return dict(plugin=plugin) def documentations(): """Return the Ext.data.Array configuration for the documentation and for the source code. """ from plugin_dbui import get_reference_paths # alias a = '<a href="%s" target="_blank">%s</a>' trDev = T("Documentation for developers") trJS = T("Javascript API") trPy = T("Python API") # documentation of the application apath, lpath = get_reference_paths() userdoc = "" if os.path.exists(os.path.join(apath, 'static/docs/database.png')): userdoc = a % (URL('static', 'docs/database.png'), T("Data base scheme")) pydoc = "" if os.path.exists(os.path.join(apath, 'static/docs/epydoc/index.html')): pydoc = a % (URL('static', 'docs/epydoc/index.html'), trPy) jsdoc = "" if os.path.exists(os.path.join(apath, 'static/docs/jsduck/index.html')): jsdoc = a % (URL('static', 'docs/jsduck/index.html'), trJS) # configuration of the Ext.data.Array for the documentation cfg = dict() cfg['fields'] = [{'name': 'code', 'type': 'string'}, {'name': 'developer', 'type': 'string'}, {'name': 'python', 'type': 'string'}, {'name': 'javascript', 'type': 'string'}] r1 = (request.application, userdoc, pydoc, jsdoc) r2 = (a % ("https://marprod.in2p3.fr/plugin_dbui_book", "plugin_dbui"), a % ("https://marprod.in2p3.fr/plugin_dbui_book/default/chapter/29", trDev), a % (URL('static', 'plugin_dbui/docs/epydoc/index.html'), trPy), a % (URL('static', 'plugin_dbui/docs/jsduck/index.html'), trJS)) r3 = (a % ("http://web2py.com/", "Web2py"), a % ("http://web2py.com/book", trDev), a % ("http://www.web2py.com/examples/static/epydoc/index.html", trPy), "") r4 = (a % ("http://www.sencha.com/products/extjs/", "Ext JS"), "", "", a % ("http://docs.sencha.com/extjs/4.2.1/", trJS)) r5 = (a % ("http://www.mathjax.org/", "MathJax"), "", "", a % ("http://docs.mathjax.org/", trJS)) r6 = (a % ("http://ace.c9.io/#nav=about", "Ace"), "", "", a % ("http://ace.c9.io/#nav=api", trJS)) cfg['data'] = [r1, r2, r3, r4, r5, r6] cfg_doc = json.dumps(cfg) # configuration of the Ext.data.Array for the source code cfg = dict() cfg['fields'] = [{'name': 'code', 'type': 'string'}, {'name': 'source', 'type': 'string'}] r1 = (request.application, "<em>git clone http://marwww.in2p3.fr/~legac/wap/git/%s.git</em>" % request.application) r2 = ("plugin_dbui", "<em>git clone http://marwww.in2p3.fr/~legac/wap/git/web2py_plugin_dbui.git</em>") r3 = ("Web2py", "<em>git clone git://github.com/web2py/web2py.git</em>") r4 = ("Ext JS", "<em>Download from the Ext JS web site.</em><br>" "<em>In the local directory: %s/static/plugin_extjs/src</em>" % request.application) r5 = ("MathJax", "<em>git clone http://github.com/mathjax/MathJax</em>") r6 = ("Ace", "<em>git clone git://github.com/ajaxorg/ace.git</em>") cfg['data'] = [r1, r2, r3, r4, r5, r6] cfg_src = json.dumps(cfg) return dict(cfg_doc=cfg_doc, cfg_src=cfg_src) def index(): """Default Action to run the plugin Load compressed version of all libraries. EXAMPLES http://localhost:8000/myapp/plugin_dbui http://localhost:8000/myapp/plugin_dbui?script=foo URL OPTIONS script run the javascript foo in the framework defined by the plugin. The scripts are stored in the directory defined by the plugin configuration app_script_dir. """ from plugin_dbui import get_file_paths, get_script_path plugin = plugins.dbui # css files response.files.extend(get_file_paths(plugin.extjs_css, ext='.css')) response.files.extend(get_file_paths(plugin.dbui_css, ext='.css')) response.files.extend(get_file_paths(plugin.ace_css, ext='.css')) response.files.extend(get_file_paths(plugin.app_css, ext='.css')) # compressed version of the javascript libraries response.files.extend(get_file_paths(plugin.ace_libmin, ext='.js')) response.files.extend(get_file_paths(plugin.mathjax_libmin, ext='.js')) response.files.extend(get_file_paths(plugin.extjs_libmin, ext='.js')) response.files.extend(get_file_paths(plugin.dbui_libmin, ext='.js')) response.files.extend(get_file_paths(plugin.app_libmin, ext='.js')) # language files response.files.extend(get_file_paths(plugin.extjs_lg, ext='.js')) response.files.extend(get_file_paths(plugin.dbui_lg, ext='.js')) response.files.extend(get_file_paths(plugin.app_lg, ext='.js')) # URL for dbui configuration script response.files.append(plugin.dbui_conf) # main script which can be defined in many different ways pscript = get_script_path(plugin) response.files.append(pscript) # switch off the debug mode on the server side session.debug = False # return the plugin configuration parameter as well as the response return dict(plugin=plugin) def status(): return dict(request=request, response=response, session=session) def versions(): """Return the versions of the different part of the code. """ from plugin_dbui import get_versions # the configuration for the Ext.data.ArrayStore cfg = dict() cfg['fields'] = [{'name': 'code', 'type': 'string'}, {'name': 'version', 'type': 'string'}] cfg['data'] = get_versions() return dict(cfg_store=json.dumps(cfg))