PageRenderTime 29ms CodeModel.GetById 14ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/galaxy/webapps/demo_sequencer/buildapp.py

https://bitbucket.org/cistrome/cistrome-harvard/
Python | 171 lines | 144 code | 8 blank | 19 comment | 6 complexity | e1de7c4f0f371604753c226626b4deaa MD5 | raw file
  1"""
  2Provides factory methods to assemble the Galaxy web application
  3"""
  4
  5import logging, atexit
  6import os, os.path, sys
  7
  8from inspect import isclass
  9
 10from paste.request import parse_formvars
 11from paste.util import import_string
 12from paste import httpexceptions
 13from galaxy.util import asbool
 14import pkg_resources
 15
 16log = logging.getLogger( __name__ )
 17
 18import config
 19import galaxy.webapps.demo_sequencer.framework
 20
 21def add_ui_controllers( webapp, app ):
 22    """
 23    Search for controllers in the 'galaxy.webapps.demo_sequencer.controllers'
 24    directory and add them to the webapp.
 25    """
 26    from galaxy.web.base.controller import BaseUIController
 27    from galaxy.web.base.controller import ControllerUnavailable
 28    import galaxy.webapps.demo_sequencer.controllers
 29    controller_dir = galaxy.webapps.demo_sequencer.controllers.__path__[0]
 30    for fname in os.listdir( controller_dir ):
 31        if not fname.startswith( "_" ) and fname.endswith( ".py" ):
 32            name = fname[:-3]
 33            module_name = "galaxy.webapps.demo_sequencer.controllers." + name
 34            module = __import__( module_name )
 35            for comp in module_name.split( "." )[1:]:
 36                module = getattr( module, comp )
 37            # Look for a controller inside the modules
 38            for key in dir( module ):
 39                T = getattr( module, key )
 40                if isclass( T ) and T is not BaseUIController and issubclass( T, BaseUIController ):
 41                    webapp.add_ui_controller( name, T( app ) )
 42
 43def app_factory( global_conf, **kwargs ):
 44    """Return a wsgi application serving the root object"""
 45    # Create the Galaxy application unless passed in
 46    if 'app' in kwargs:
 47        app = kwargs.pop( 'app' )
 48    else:
 49        try:
 50            from galaxy.webapps.demo_sequencer.app import UniverseApplication
 51            app = UniverseApplication( global_conf = global_conf, **kwargs )
 52        except:
 53            import traceback, sys
 54            traceback.print_exc()
 55            sys.exit( 1 )
 56    atexit.register( app.shutdown )
 57    # Create the universe WSGI application
 58    webapp = galaxy.webapps.demo_sequencer.framework.WebApplication( app, session_cookie='galaxydemo_sequencersession', name="demo_sequencer" )
 59    add_ui_controllers( webapp, app )
 60    # These two routes handle our simple needs at the moment
 61    webapp.add_route( '/:controller/:action', action='index' )
 62    webapp.add_route( '/:action', controller='common', action='index' )
 63    webapp.finalize_config()
 64    # Wrap the webapp in some useful middleware
 65    if kwargs.get( 'middleware', True ):
 66        webapp = wrap_in_middleware( webapp, global_conf, **kwargs )
 67    if kwargs.get( 'static_enabled', True ):
 68        webapp = wrap_in_static( webapp, global_conf, **kwargs )
 69    # Return
 70    return webapp
 71
 72def wrap_in_middleware( app, global_conf, **local_conf ):
 73    """Based on the configuration wrap `app` in a set of common and useful middleware."""
 74    # Merge the global and local configurations
 75    conf = global_conf.copy()
 76    conf.update(local_conf)
 77    debug = asbool( conf.get( 'debug', False ) )
 78    # First put into place httpexceptions, which must be most closely
 79    # wrapped around the application (it can interact poorly with
 80    # other middleware):
 81    app = httpexceptions.make_middleware( app, conf )
 82    log.debug( "Enabling 'httpexceptions' middleware" )
 83    # The recursive middleware allows for including requests in other
 84    # requests or forwarding of requests, all on the server side.
 85    if asbool(conf.get('use_recursive', True)):
 86        from paste import recursive
 87        app = recursive.RecursiveMiddleware( app, conf )
 88        log.debug( "Enabling 'recursive' middleware" )
 89    # Various debug middleware that can only be turned on if the debug
 90    # flag is set, either because they are insecure or greatly hurt
 91    # performance
 92    if debug:
 93        # Middleware to check for WSGI compliance
 94        if asbool( conf.get( 'use_lint', True ) ):
 95            from paste import lint
 96            app = lint.make_middleware( app, conf )
 97            log.debug( "Enabling 'lint' middleware" )
 98        # Middleware to run the python profiler on each request
 99        if asbool( conf.get( 'use_profile', False ) ):
100            import profile
101            app = profile.ProfileMiddleware( app, conf )
102            log.debug( "Enabling 'profile' middleware" )
103        # Middleware that intercepts print statements and shows them on the
104        # returned page
105        if asbool( conf.get( 'use_printdebug', True ) ):
106            from paste.debug import prints
107            app = prints.PrintDebugMiddleware( app, conf )
108            log.debug( "Enabling 'print debug' middleware" )
109    if debug and asbool( conf.get( 'use_interactive', False ) ):
110        # Interactive exception debugging, scary dangerous if publicly
111        # accessible, if not enabled we'll use the regular error printing
112        # middleware.
113        pkg_resources.require( "WebError" )
114        from weberror import evalexception
115        app = evalexception.EvalException( app, conf,
116                                           templating_formatters=build_template_error_formatters() )
117        log.debug( "Enabling 'eval exceptions' middleware" )
118    else:
119        # Not in interactive debug mode, just use the regular error middleware
120        from paste.exceptions import errormiddleware
121        app = errormiddleware.ErrorMiddleware( app, conf )
122        log.debug( "Enabling 'error' middleware" )
123    # Transaction logging (apache access.log style)
124    if asbool( conf.get( 'use_translogger', True ) ):
125        from paste.translogger import TransLogger
126        app = TransLogger( app )
127        log.debug( "Enabling 'trans logger' middleware" )
128    # X-Forwarded-Host handling
129    from galaxy.web.framework.middleware.xforwardedhost import XForwardedHostMiddleware
130    app = XForwardedHostMiddleware( app )
131    log.debug( "Enabling 'x-forwarded-host' middleware" )
132    return app
133
134def wrap_in_static( app, global_conf, **local_conf ):
135    from paste.urlmap import URLMap
136    from galaxy.web.framework.middleware.static import CacheableStaticURLParser as Static
137    urlmap = URLMap()
138    # Merge the global and local configurations
139    conf = global_conf.copy()
140    conf.update(local_conf)
141    # Get cache time in seconds
142    cache_time = conf.get( "static_cache_time", None )
143    if cache_time is not None:
144        cache_time = int( cache_time )
145    # Send to dynamic app by default
146    urlmap["/"] = app
147    # Define static mappings from config
148    urlmap["/static"] = Static( conf.get( "static_dir" ), cache_time )
149    urlmap["/images"] = Static( conf.get( "static_images_dir" ), cache_time )
150    urlmap["/static/scripts"] = Static( conf.get( "static_scripts_dir" ), cache_time )
151    urlmap["/static/style"] = Static( conf.get( "static_style_dir" ), cache_time )
152    urlmap["/favicon.ico"] = Static( conf.get( "static_favicon_dir" ), cache_time )
153    # URL mapper becomes the root webapp
154    return urlmap
155
156def build_template_error_formatters():
157    """
158    Build a list of template error formatters for WebError. When an error
159    occurs, WebError pass the exception to each function in this list until
160    one returns a value, which will be displayed on the error page.
161    """
162    formatters = []
163    # Formatter for mako
164    import mako.exceptions
165    def mako_html_data( exc_value ):
166        if isinstance( exc_value, ( mako.exceptions.CompileException, mako.exceptions.SyntaxException ) ):
167            return mako.exceptions.html_error_template().render( full=False, css=False )
168        if isinstance( exc_value, AttributeError ) and exc_value.args[0].startswith( "'Undefined' object has no attribute" ):
169            return mako.exceptions.html_error_template().render( full=False, css=False )
170    formatters.append( mako_html_data )
171    return formatters