Move entire app structure over to using the new config system.
authorChristopher Allan Webber <cwebber@dustycloud.org>
Sat, 18 Jun 2011 22:59:38 +0000 (17:59 -0500)
committerChristopher Allan Webber <cwebber@dustycloud.org>
Sat, 18 Jun 2011 22:59:38 +0000 (17:59 -0500)
This is a huge change!  This means several things.

 - From the python point of view, launching the application is a heck
   of a lot cleaner.  You just need to pass in the config file path to
   MediaGoblinApp's __init__() and whether or not this funtion should
   setup celery and you're good.
 - There are now two separate config files, separating the server
   setup from the application setup.
   - server.ini: the paste deploy config file, which configures the
     applications and server setup but *NOT* the mediagoblin application
     itself.
   - mediagoblin.ini: where you configure mediagoblin (and possibly celery)
 - Launching the application is now different.  Instead of:
     ./bin/paster serve mediagoblin.ini --reload
   We launch like:
     ./bin/paster serve server.ini --reload

mediagoblin/app.py
mediagoblin/config_spec.ini
server.ini [moved from mediagoblin.ini with 60% similarity]

index a1c6b5123ea5d58b35fc69b6de3d5c0c947ac744..da1aba478b33efbaca2708f9d6638ec78670bf6c 100644 (file)
@@ -18,14 +18,15 @@ import os
 import urllib
 
 import routes
-from paste.deploy.converters import asbool
 from webob import Request, exc
 
 from mediagoblin import routing, util, storage, staticdirect
+from mediagoblin.config import (
+    read_mediagoblin_config, generate_validation_report)
 from mediagoblin.db.open import setup_connection_and_db_from_config
 from mediagoblin.mg_globals import setup_globals
 from mediagoblin.celery_setup import setup_celery_from_config
-from mediagoblin.workbench import WorkbenchManager, DEFAULT_WORKBENCH_DIR
+from mediagoblin.workbench import WorkbenchManager
 
 
 class Error(Exception): pass
@@ -34,42 +35,101 @@ class ImproperlyConfigured(Error): pass
 
 class MediaGoblinApp(object):
     """
-    Really basic wsgi app using routes and WebOb.
+    WSGI application of MediaGoblin
+
+    ... this is the heart of the program!
     """
-    def __init__(self, connection, db,
-                 public_store, queue_store,
-                 staticdirector,
-                 email_sender_address, email_debug_mode,
-                 user_template_path=None,
-                 workbench_path=DEFAULT_WORKBENCH_DIR):
+    def __init__(self, config_path, setup_celery=True):
+        """
+        Initialize the application based on a configuration file.
+
+        Arguments:
+         - config_path: path to the configuration file we're opening.
+         - setup_celery: whether or not to setup celery during init.
+           (Note: setting 'celery_setup_elsewhere' also disables
+           setting up celery.)
+        """
+        ##############
+        # Setup config
+        ##############
+
+        # Open and setup the config
+        global_config, validation_result = read_mediagoblin_config(config_path)
+        app_config = global_config['mediagoblin']
+        # report errors if necessary
+        validation_report = generate_validation_report(
+            global_config, validation_result)
+        if validation_report:
+            raise ImproperlyConfigured(validation_report)
+
+        ##########################################
+        # Setup other connections / useful objects
+        ##########################################
+
+        # Set up the database
+        self.connection, self.db = setup_connection_and_db_from_config(
+            app_config)
+
         # Get the template environment
-        self.template_loader = util.get_jinja_loader(user_template_path)
+        self.template_loader = util.get_jinja_loader(
+            app_config.get('user_template_path'))
         
         # Set up storage systems
-        self.public_store = public_store
-        self.queue_store = queue_store
-
-        # Set up database
-        self.connection = connection
-        self.db = db
+        self.public_store = storage.storage_system_from_paste_config(
+            app_config, 'publicstore')
+        self.queue_store = storage.storage_system_from_paste_config(
+            app_config, 'queuestore')
 
         # set up routing
         self.routing = routing.get_mapper()
 
         # set up staticdirector tool
-        self.staticdirector = staticdirector
-
+        if app_config.has_key('direct_remote_path'):
+            self.staticdirector = staticdirect.RemoteStaticDirect(
+                app_config['direct_remote_path'].strip())
+        elif app_config.has_key('direct_remote_paths'):
+            direct_remote_path_lines = app_config[
+                'direct_remote_paths'].strip().splitlines()
+            self.staticdirector = staticdirect.MultiRemoteStaticDirect(
+                dict([line.strip().split(' ', 1)
+                      for line in direct_remote_path_lines]))
+        else:
+            raise ImproperlyConfigured(
+                "One of direct_remote_path or "
+                "direct_remote_paths must be provided")
+
+        # Setup celery, if appropriate
+        if setup_celery and not app_config.get('celery_setup_elsewhere'):
+            if os.environ.get('CELERY_ALWAYS_EAGER'):
+                setup_celery_from_config(
+                    app_config, global_config,
+                    force_celery_always_eager=True)
+            else:
+                setup_celery_from_config(app_config, global_config)
+
+        #######################################################
+        # Insert appropriate things into mediagoblin.mg_globals
+        #
         # certain properties need to be accessed globally eg from
         # validators, etc, which might not access to the request
         # object.
+        #######################################################
+
         setup_globals(
-            email_sender_address=email_sender_address,
-            email_debug_mode=email_debug_mode,
-            db_connection=connection,
+            app_config=app_config,
+            global_config=global_config,
+
+            # TODO: No need to set these two up as globals, we could
+            # just read them out of mg_globals.app_config
+            email_sender_address=app_config['email_sender_address'],
+            email_debug_mode=app_config['email_debug_mode'],
+
+            # Actual, useful to everyone objects
+            db_connection=self.connection,
             database=self.db,
             public_store=self.public_store,
             queue_store=self.queue_store,
-            workbench_manager=WorkbenchManager(workbench_path))
+            workbench_manager=WorkbenchManager(app_config['workbench_path']))
 
     def __call__(self, environ, start_response):
         request = Request(environ)
@@ -119,45 +179,6 @@ class MediaGoblinApp(object):
 
 
 def paste_app_factory(global_config, **app_config):
-    # Get the database connection
-    connection, db = setup_connection_and_db_from_config(app_config)
-
-    # Set up the storage systems.
-    public_store = storage.storage_system_from_paste_config(
-        app_config, 'publicstore')
-    queue_store = storage.storage_system_from_paste_config(
-        app_config, 'queuestore')
-
-    # Set up the staticdirect system
-    if app_config.has_key('direct_remote_path'):
-        staticdirector = staticdirect.RemoteStaticDirect(
-            app_config['direct_remote_path'].strip())
-    elif app_config.has_key('direct_remote_paths'):
-        direct_remote_path_lines = app_config[
-            'direct_remote_paths'].strip().splitlines()
-        staticdirector = staticdirect.MultiRemoteStaticDirect(
-            dict([line.strip().split(' ', 1)
-                  for line in direct_remote_path_lines]))
-    else:
-        raise ImproperlyConfigured(
-            "One of direct_remote_path or direct_remote_paths must be provided")
-
-    if not asbool(app_config.get('celery_setup_elsewhere')):
-        if asbool(os.environ.get('CELERY_ALWAYS_EAGER')):
-            setup_celery_from_config(
-                app_config, global_config,
-                force_celery_always_eager=True)
-        else:
-            setup_celery_from_config(app_config, global_config)
-
-    mgoblin_app = MediaGoblinApp(
-        connection, db,
-        public_store=public_store, queue_store=queue_store,
-        staticdirector=staticdirector,
-        email_sender_address=app_config.get(
-            'email_sender_address', 'notice@mediagoblin.example.org'),
-        email_debug_mode=asbool(app_config.get('email_debug_mode')),
-        user_template_path=app_config.get('local_templates'),
-        workbench_path=app_config.get('workbench_path', DEFAULT_WORKBENCH_DIR))
+    mgoblin_app = MediaGoblinApp(app_config['config'])
 
     return mgoblin_app
index 2e7821014802883dabf842f000a09afe0f7169cd..52e3fdfd1432ce5b248e471b634326e354626aeb 100644 (file)
@@ -4,7 +4,7 @@ queuestore_base_dir = string(default="%(here)s/user_dev/media/queue")
 publicstore_base_dir = string(default="%(here)s/user_dev/media/public")
 
 # Where temporary files used in processing and etc are kept
-workbench_base_dir = string(default="%(here)s/user_dev/media/workbench")
+workbench_path = string(default="%(here)s/user_dev/media/workbench")
 
 # 
 publicstore_base_url = string(default="/mgoblin_media/")
@@ -16,7 +16,9 @@ direct_remote_path = string(default="/mgoblin_static/")
 email_debug_mode = boolean(default=True)
 email_sender_address = string(default="notice@mediagoblin.example.org")
 
-local_templates = string(default="%(here)s/user_dev/templates/")
+# By default not set, but you might want something like:
+# "%(here)s/user_dev/templates/"
+local_templates = string()
 
 # Whether or not celery is set up via an environment variable or
 # something else (and thus mediagoblin should not attempt to set it up
similarity index 60%
rename from mediagoblin.ini
rename to server.ini
index b85f22ea172886059af537ec73eebeb8303c057f..73fbe8e8de09b9a5ab1045d9ed3c5c09d27aa441 100644 (file)
@@ -10,19 +10,11 @@ use = egg:Paste#urlmap
 [app:mediagoblin]
 use = egg:mediagoblin#app
 filter-with = beaker
-queuestore_base_dir = %(here)s/user_dev/media/queue
-publicstore_base_dir = %(here)s/user_dev/media/public
-publicstore_base_url = /mgoblin_media/
-direct_remote_path = /mgoblin_static/
-email_sender_address = "notice@mediagoblin.example.org"
-# set to false to enable sending notices
-email_debug_mode = true
-## Uncomment this to put some user-overriding templates here
-#local_templates = %(here)s/user_dev/templates/
+config = %(here)s/mediagoblin.ini
 
 [app:publicstore_serve]
 use = egg:Paste#static
-document_root = %(here)s/user_dev/media/public
+document_root = %(here)s/user_dev/media/public/
 
 [app:mediagoblin_static]
 use = egg:Paste#static