Switch from Paste for serving to Waitress
[mediagoblin.git] / mediagoblin / app.py
index e5442010f3ddd742e6dfa825db0cb285eb0ec7e4..345aa048dd70a36de5a18585e36de7a68a702752 100644 (file)
@@ -16,6 +16,7 @@
 
 import os
 import logging
+from contextlib import contextmanager
 
 from mediagoblin.routing import get_url_map
 from mediagoblin.tools.routing import endpoint_to_controller
@@ -84,11 +85,11 @@ class MediaGoblinApp(object):
         ##############
 
         # Open and setup the config
-        global_config, app_config = setup_global_and_app_config(config_path)
+        self.global_config, self.app_config = setup_global_and_app_config(config_path)
 
         media_type_warning()
 
-        setup_crypto()
+        setup_crypto(self.app_config)
 
         ##########################################
         # Setup other connections / useful objects
@@ -106,7 +107,10 @@ class MediaGoblinApp(object):
         setup_plugins()
 
         # Set up the database
-        self.db = setup_database(app_config['run_migrations'])
+        if DISABLE_GLOBALS:
+            self.db_manager = setup_database(self)
+        else:
+            self.db = setup_database(self)
 
         # Quit app if need to run dbupdate
         ## NOTE: This is currently commented out due to session errors..
@@ -114,11 +118,11 @@ class MediaGoblinApp(object):
         # check_db_up_to_date()
 
         # Register themes
-        self.theme_registry, self.current_theme = register_themes(app_config)
+        self.theme_registry, self.current_theme = register_themes(self.app_config)
 
         # Get the template environment
         self.template_loader = get_jinja_loader(
-            app_config.get('local_templates'),
+            self.app_config.get('local_templates'),
             self.current_theme,
             PluginManager().get_template_paths()
             )
@@ -126,7 +130,7 @@ class MediaGoblinApp(object):
         # Check if authentication plugin is enabled and respond accordingly.
         self.auth = check_auth_enabled()
         if not self.auth:
-            app_config['allow_comments'] = False
+            self.app_config['allow_comments'] = False
 
         # Set up storage systems
         self.public_store, self.queue_store = setup_storage()
@@ -135,16 +139,16 @@ class MediaGoblinApp(object):
         self.url_map = get_url_map()
 
         # set up staticdirector tool
-        self.staticdirector = get_staticdirector(app_config)
+        self.staticdirector = get_staticdirector(self.app_config)
 
         # Setup celery, if appropriate
-        if setup_celery and not app_config.get('celery_setup_elsewhere'):
+        if setup_celery and not self.app_config.get('celery_setup_elsewhere'):
             if os.environ.get('CELERY_ALWAYS_EAGER', 'false').lower() == 'true':
                 setup_celery_from_config(
-                    app_config, global_config,
+                    self.app_config, self.global_config,
                     force_celery_always_eager=True)
             else:
-                setup_celery_from_config(app_config, global_config)
+                setup_celery_from_config(self.app_config, self.global_config)
 
         #######################################################
         # Insert appropriate things into mediagoblin.mg_globals
@@ -163,13 +167,14 @@ class MediaGoblinApp(object):
 
         # Workbench *currently* only used by celery, so this only
         # matters in always eager mode :)
-        setup_workbench()
+        self.workbench_manager = setup_workbench()
 
         # instantiate application meddleware
         self.meddleware = [common.import_component(m)(self)
                            for m in meddleware.ENABLED_MEDDLEWARE]
 
-    def gen_context(self, ctx=None):
+    @contextmanager
+    def gen_context(self, ctx=None, **kwargs):
         """
         Attach contextual information to request, or generate a context object
 
@@ -177,6 +182,13 @@ class MediaGoblinApp(object):
         information (current translation, etc) are attached to this
         object.
         """
+        if DISABLE_GLOBALS:
+            with self.db_manager.session_scope() as db:
+                yield self._gen_context(db, ctx)
+        else:
+            yield self._gen_context(self.db, ctx)
+
+    def _gen_context(self, db, ctx, **kwargs):
         # Set up context
         # --------------
 
@@ -191,7 +203,8 @@ class MediaGoblinApp(object):
         # Also attach a few utilities from request.app for convenience?
         ctx.app = self
 
-        ctx.db = self.db
+        ctx.db = db
+
         ctx.staticdirect = self.staticdirector
 
         # Do special things if this is a request
@@ -214,7 +227,7 @@ class MediaGoblinApp(object):
         # This should be moved over for certain, but how to deal with
         # request.locale?
         request.template_env = template.get_jinja_env(
-            self.template_loader, request.locale)
+            self, self.template_loader, request.locale)
 
         mg_request.setup_user_in_request(request)
 
@@ -259,8 +272,10 @@ class MediaGoblinApp(object):
             environ.pop('HTTPS')
 
         ## Attach utilities to the request object
-        request = self.gen_context(request)
+        with self.gen_context(request) as request:
+            return self._finish_call_backend(request, environ, start_response)
 
+    def _finish_call_backend(self, request, environ, start_response):
         # Log user out if authentication_disabled
         no_auth_logout(request)
 
@@ -326,9 +341,10 @@ class MediaGoblinApp(object):
         try:
             return self.call_backend(environ, start_response)
         finally:
-            # Reset the sql session, so that the next request
-            # gets a fresh session
-            self.db.reset_after_request()
+            if not DISABLE_GLOBALS:
+                # Reset the sql session, so that the next request
+                # gets a fresh session
+                self.db.reset_after_request()
 
 
 def paste_app_factory(global_config, **app_config):
@@ -349,34 +365,3 @@ def paste_app_factory(global_config, **app_config):
     mgoblin_app = hook_transform('wrap_wsgi', mgoblin_app)
 
     return mgoblin_app
-
-
-def paste_server_selector(wsgi_app, global_config=None, **app_config):
-    """
-    Select between gunicorn and paste depending on what ia available
-    """
-    # See if we can import the gunicorn server...
-    # otherwise we'll use the paste server
-    try:
-        import gunicorn
-    except ImportError:
-        gunicorn = None
-
-    if gunicorn is None:
-        # use paste
-        from paste.httpserver import server_runner
-
-        cleaned_app_config = dict(
-            [(key, app_config[key])
-             for key in app_config
-             if key in ["host", "port", "handler", "ssl_pem", "ssl_context",
-                        "server_version", "protocol_version", "start_loop",
-                        "daemon_threads", "socket_timeout", "use_threadpool",
-                        "threadpool_workers", "threadpool_options",
-                        "request_queue_size"]])
-
-        return server_runner(wsgi_app, global_config, **cleaned_app_config)
-    else:
-        # use gunicorn
-        from gunicorn.app.pasterapp import PasterServerApplication
-        return PasterServerApplication(wsgi_app, global_config, **app_config)