# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+import os
import urllib
import routes
-import mongokit
-from paste.deploy.converters import asbool, asint
from webob import Request, exc
-from mediagoblin import routing, util, models, storage, staticdirect
-from mediagoblin.globals import setup_globals
-from mediagoblin.celery_setup import setup_celery_from_config
-
-
-class Error(Exception): pass
-class ImproperlyConfigured(Error): pass
+from mediagoblin import routing, util, storage
+from mediagoblin.db.open import setup_connection_and_db_from_config
+from mediagoblin.db.util import MigrationManager
+from mediagoblin.mg_globals import setup_globals
+from mediagoblin.init.celery import setup_celery_from_config
+from mediagoblin.init import get_jinja_loader, get_staticdirector, \
+ setup_global_and_app_config, setup_workbench
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, database_path,
- public_store, queue_store,
- staticdirector,
- email_sender_address, email_debug_mode,
- user_template_path=None):
+ 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, app_config = setup_global_and_app_config(config_path)
+
+ ##########################################
+ # Setup other connections / useful objects
+ ##########################################
+
+ # Set up the database
+ self.connection, self.db = setup_connection_and_db_from_config(
+ app_config)
+
+ # Init the migration number if necessary
+ migration_manager = MigrationManager(self.db)
+ migration_manager.install_migration_version_if_missing()
+
+ # Tiny hack to warn user if our migration is out of date
+ if not migration_manager.database_at_latest_migration():
+ print (
+ "*WARNING:* Your migrations are out of date, "
+ "maybe run ./bin/gmg migrate?")
+
# Get the template environment
- self.template_loader = util.get_jinja_loader(user_template_path)
+ self.template_loader = 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 = connection[database_path]
- models.register_models(connection)
+ self.public_store = storage.storage_system_from_config(
+ app_config, 'publicstore')
+ self.queue_store = storage.storage_system_from_config(
+ app_config, 'queuestore')
# set up routing
self.routing = routing.get_mapper()
# set up staticdirector tool
- self.staticdirector = staticdirector
-
+ self.staticdirector = get_staticdirector(app_config)
+
+ # 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=self,
+ db_connection=self.connection,
database=self.db,
public_store=self.public_store,
queue_store=self.queue_store)
+ # Workbench *currently* only used by celery, so this only
+ # matters in always eager mode :)
+ setup_workbench()
+
def __call__(self, environ, start_response):
request = Request(environ)
path_info = request.path_info
def paste_app_factory(global_config, **app_config):
- # Get the database connection
- port = app_config.get('db_port')
- if port:
- port = asint(port)
- connection = mongokit.Connection(
- app_config.get('db_host'), port)
-
- # 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")
-
- setup_celery_from_config(app_config, global_config)
-
- mgoblin_app = MediaGoblinApp(
- connection, app_config.get('db_name', 'mediagoblin'),
- 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'))
+ mgoblin_app = MediaGoblinApp(app_config['config'])
return mgoblin_app