root/galaxy-central/lib/galaxy/webapps/community/buildapp.py

リビジョン 2, 8.9 KB (コミッタ: hatakeyama, 14 年 前)

import galaxy-central

行番号 
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 paste.deploy.converters import asbool
14import pkg_resources
15
16log = logging.getLogger( __name__ )
17
18import config
19import galaxy.webapps.community.model
20import galaxy.webapps.community.model.mapping
21import galaxy.web.framework
22
23def add_controllers( webapp, app ):
24    """
25    Search for controllers in the 'galaxy.webapps.controllers' module and add
26    them to the webapp.
27    """
28    from galaxy.web.base.controller import BaseController
29    from galaxy.web.base.controller import ControllerUnavailable
30    import galaxy.webapps.community.controllers
31    controller_dir = galaxy.webapps.community.controllers.__path__[0]
32    for fname in os.listdir( controller_dir ):
33        if not fname.startswith( "_" ) and fname.endswith( ".py" ):
34            name = fname[:-3]
35            module_name = "galaxy.webapps.community.controllers." + name
36            module = __import__( module_name )
37            for comp in module_name.split( "." )[1:]:
38                module = getattr( module, comp )
39            # Look for a controller inside the modules
40            for key in dir( module ):
41                T = getattr( module, key )
42                if isclass( T ) and T is not BaseController and issubclass( T, BaseController ):
43                    webapp.add_controller( name, T( app ) )
44    import galaxy.web.controllers
45    controller_dir = galaxy.web.controllers.__path__[0]
46    for fname in os.listdir( controller_dir ):
47        # TODO: fix this if we decide to use, we don't need to inspect all controllers...
48        if fname.startswith( 'user'  ) and fname.endswith( ".py" ):
49            name = fname[:-3]
50            module_name = "galaxy.web.controllers." + name
51            module = __import__( module_name )
52            for comp in module_name.split( "." )[1:]:
53                module = getattr( module, comp )
54            # Look for a controller inside the modules
55            for key in dir( module ):
56                T = getattr( module, key )
57                if isclass( T ) and T is not BaseController and issubclass( T, BaseController ):
58                    webapp.add_controller( name, T( app ) )
59
60def app_factory( global_conf, **kwargs ):
61    """Return a wsgi application serving the root object"""
62    # Create the Galaxy application unless passed in
63    if 'app' in kwargs:
64        app = kwargs.pop( 'app' )
65    else:
66        try:
67            from galaxy.webapps.community.app import UniverseApplication
68            app = UniverseApplication( global_conf = global_conf, **kwargs )
69        except:
70            import traceback, sys
71            traceback.print_exc()
72            sys.exit( 1 )
73    atexit.register( app.shutdown )
74    # Create the universe WSGI application
75    webapp = galaxy.web.framework.WebApplication( app, session_cookie='galaxycommunitysession' )
76    add_controllers( webapp, app )
77    # These two routes handle our simple needs at the moment
78    webapp.add_route( '/:controller/:action', action='index' )
79    webapp.add_route( '/:action', controller='tool', action='index' )
80    webapp.finalize_config()
81    # Wrap the webapp in some useful middleware
82    if kwargs.get( 'middleware', True ):
83        webapp = wrap_in_middleware( webapp, global_conf, **kwargs )
84    if kwargs.get( 'static_enabled', True ):
85        webapp = wrap_in_static( webapp, global_conf, **kwargs )
86    # Close any pooled database connections before forking
87    try:
88        galaxy.webapps.community.model.mapping.metadata.engine.connection_provider._pool.dispose()
89    except:
90        pass
91    # Return
92    return webapp
93   
94def wrap_in_middleware( app, global_conf, **local_conf ):
95    """Based on the configuration wrap `app` in a set of common and useful middleware."""
96    # Merge the global and local configurations
97    conf = global_conf.copy()
98    conf.update(local_conf)
99    debug = asbool( conf.get( 'debug', False ) )
100    # First put into place httpexceptions, which must be most closely
101    # wrapped around the application (it can interact poorly with
102    # other middleware):
103    app = httpexceptions.make_middleware( app, conf )
104    log.debug( "Enabling 'httpexceptions' middleware" )
105    # The recursive middleware allows for including requests in other
106    # requests or forwarding of requests, all on the server side.
107    if asbool(conf.get('use_recursive', True)):
108        from paste import recursive
109        app = recursive.RecursiveMiddleware( app, conf )
110        log.debug( "Enabling 'recursive' middleware" )
111    # Various debug middleware that can only be turned on if the debug
112    # flag is set, either because they are insecure or greatly hurt
113    # performance
114    if debug:
115        # Middleware to check for WSGI compliance
116        if asbool( conf.get( 'use_lint', True ) ):
117            from paste import lint
118            app = lint.make_middleware( app, conf )
119            log.debug( "Enabling 'lint' middleware" )
120        # Middleware to run the python profiler on each request
121        if asbool( conf.get( 'use_profile', False ) ):
122            import profile
123            app = profile.ProfileMiddleware( app, conf )
124            log.debug( "Enabling 'profile' middleware" )
125        # Middleware that intercepts print statements and shows them on the
126        # returned page
127        if asbool( conf.get( 'use_printdebug', True ) ):
128            from paste.debug import prints
129            app = prints.PrintDebugMiddleware( app, conf )
130            log.debug( "Enabling 'print debug' middleware" )
131    if debug and asbool( conf.get( 'use_interactive', False ) ):
132        # Interactive exception debugging, scary dangerous if publicly
133        # accessible, if not enabled we'll use the regular error printing
134        # middleware.
135        pkg_resources.require( "WebError" )
136        from weberror import evalexception
137        app = evalexception.EvalException( app, conf,
138                                           templating_formatters=build_template_error_formatters() )
139        log.debug( "Enabling 'eval exceptions' middleware" )
140    else:
141        # Not in interactive debug mode, just use the regular error middleware
142        from paste.exceptions import errormiddleware
143        app = errormiddleware.ErrorMiddleware( app, conf )
144        log.debug( "Enabling 'error' middleware" )
145    # Transaction logging (apache access.log style)
146    if asbool( conf.get( 'use_translogger', True ) ):
147        from paste.translogger import TransLogger
148        app = TransLogger( app )
149        log.debug( "Enabling 'trans logger' middleware" )
150    # Config middleware just stores the paste config along with the request,
151    # not sure we need this but useful
152    from paste.deploy.config import ConfigMiddleware
153    app = ConfigMiddleware( app, conf )
154    log.debug( "Enabling 'config' middleware" )
155    # X-Forwarded-Host handling
156    from galaxy.web.framework.middleware.xforwardedhost import XForwardedHostMiddleware
157    app = XForwardedHostMiddleware( app )
158    log.debug( "Enabling 'x-forwarded-host' middleware" )
159    return app
160   
161def wrap_in_static( app, global_conf, **local_conf ):
162    from paste.urlmap import URLMap
163    from galaxy.web.framework.middleware.static import CacheableStaticURLParser as Static
164    urlmap = URLMap()
165    # Merge the global and local configurations
166    conf = global_conf.copy()
167    conf.update(local_conf)
168    # Get cache time in seconds
169    cache_time = conf.get( "static_cache_time", None )
170    if cache_time is not None:
171        cache_time = int( cache_time )
172    # Send to dynamic app by default
173    urlmap["/"] = app
174    # Define static mappings from config
175    urlmap["/static"] = Static( conf.get( "static_dir" ), cache_time )
176    urlmap["/images"] = Static( conf.get( "static_images_dir" ), cache_time )
177    urlmap["/static/scripts"] = Static( conf.get( "static_scripts_dir" ), cache_time )
178    urlmap["/static/style"] = Static( conf.get( "static_style_dir" ), cache_time )
179    urlmap["/favicon.ico"] = Static( conf.get( "static_favicon_dir" ), cache_time )
180    # URL mapper becomes the root webapp
181    return urlmap
182   
183def build_template_error_formatters():
184    """
185    Build a list of template error formatters for WebError. When an error
186    occurs, WebError pass the exception to each function in this list until
187    one returns a value, which will be displayed on the error page.
188    """
189    formatters = []
190    # Formatter for mako
191    import mako.exceptions
192    def mako_html_data( exc_value ):
193        if isinstance( exc_value, ( mako.exceptions.CompileException, mako.exceptions.SyntaxException ) ):
194            return mako.exceptions.html_error_template().render( full=False, css=False )
195        if isinstance( exc_value, AttributeError ) and exc_value.args[0].startswith( "'Undefined' object has no attribute" ):
196            return mako.exceptions.html_error_template().render( full=False, css=False )
197    formatters.append( mako_html_data )
198    return formatters
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。