# GNU MediaGoblin -- federated, autonomous media hosting
-# Copyright (C) 2011 Free Software Foundation, Inc
+# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
import routes
from webob import Request, exc
-from mediagoblin import routing, util
+from mediagoblin import routing, middleware
+from mediagoblin.tools import common, translate, template
+from mediagoblin.tools.response import render_404
+from mediagoblin.tools import request as mg_request
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, setup_database,
- setup_storage)
+ setup_storage, setup_beaker_cache)
class MediaGoblinApp(object):
# Get the template environment
self.template_loader = get_jinja_loader(
app_config.get('user_template_path'))
-
+
# Set up storage systems
self.public_store, self.queue_store = setup_storage()
# set up staticdirector tool
self.staticdirector = get_staticdirector(app_config)
+ # set up caching
+ self.cache = setup_beaker_cache()
+
# Setup celery, if appropriate
if setup_celery and not app_config.get('celery_setup_elsewhere'):
if os.environ.get('CELERY_ALWAYS_EAGER'):
# object.
#######################################################
- setup_globals(app = self)
+ setup_globals(app=self)
# Workbench *currently* only used by celery, so this only
# matters in always eager mode :)
setup_workbench()
+ # instantiate application middleware
+ self.middleware = [common.import_component(m)(self)
+ for m in middleware.ENABLED_MIDDLEWARE]
+
def __call__(self, environ, start_response):
request = Request(environ)
- path_info = request.path_info
+
+ # pass the request through our middleware classes
+ for m in self.middleware:
+ response = m.process_request(request)
+ if response is not None:
+ return response(environ, start_response)
## Routing / controller loading stuff
+ path_info = request.path_info
route_match = self.routing.match(path_info)
+ # By using fcgi, mediagoblin can run under a base path
+ # like /mediagoblin/. request.path_info contains the
+ # path inside mediagoblin. If the something needs the
+ # full path of the current page, that should include
+ # the basepath.
+ # Note: urlgen and routes are fine!
+ request.full_path = environ["SCRIPT_NAME"] + request.path_info
+ # python-routes uses SCRIPT_NAME. So let's use that too.
+ # The other option would be:
+ # request.full_path = environ["SCRIPT_URL"]
+
+ ## Attach utilities to the request object
+ request.matchdict = route_match
+ request.urlgen = routes.URLGenerator(self.routing, environ)
+ # Do we really want to load this via middleware? Maybe?
+ request.session = request.environ['beaker.session']
+ # Attach self as request.app
+ # Also attach a few utilities from request.app for convenience?
+ request.app = self
+ request.locale = translate.get_locale_from_request(request)
+
+ request.template_env = template.get_jinja_env(
+ self.template_loader, request.locale)
+ request.db = self.db
+ request.staticdirect = self.staticdirector
+
+ mg_request.setup_user_in_request(request)
+
# No matching page?
if route_match is None:
# Try to do see if we have a match with a trailing slash
return request.get_response(redirect)(environ, start_response)
# Okay, no matches. 404 time!
- return exc.HTTPNotFound()(environ, start_response)
+ request.matchdict = {} # in case our template expects it
+ return render_404(request)(environ, start_response)
- controller = util.import_component(route_match['controller'])
+ controller = common.import_component(route_match['controller'])
request.start_response = start_response
- ## Attach utilities to the request object
- request.matchdict = route_match
- request.urlgen = routes.URLGenerator(self.routing, environ)
- # Do we really want to load this via middleware? Maybe?
- request.session = request.environ['beaker.session']
- # Attach self as request.app
- # Also attach a few utilities from request.app for convenience?
- request.app = self
- request.locale = util.get_locale_from_request(request)
-
- request.template_env = util.get_jinja_env(
- self.template_loader, request.locale)
- request.db = self.db
- request.staticdirect = self.staticdirector
+ # get the response from the controller
+ response = controller(request)
- util.setup_user_in_request(request)
+ # pass the response through the middleware
+ for m in self.middleware[::-1]:
+ m.process_response(request, response)
- return controller(request)(environ, start_response)
+ return response(environ, start_response)
def paste_app_factory(global_config, **app_config):
- mgoblin_app = MediaGoblinApp(app_config['config'])
+ configs = app_config['config'].split()
+ mediagoblin_config = None
+ for config in configs:
+ if os.path.exists(config) and os.access(config, os.R_OK):
+ mediagoblin_config = config
+ break
+
+ if not mediagoblin_config:
+ raise IOError("Usable mediagoblin config not found.")
+
+ mgoblin_app = MediaGoblinApp(mediagoblin_config)
return mgoblin_app