documentation for get_jinja_env
[mediagoblin.git] / mediagoblin / app.py
1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2011 Free Software Foundation, Inc
3 #
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU Affero General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17 import sys
18 import urllib
19
20 from beaker.middleware import SessionMiddleware
21 import routes
22 import mongokit
23 from webob import Request, exc
24
25 from mediagoblin import routing, util, models
26
27
28 class Error(Exception): pass
29 class ImproperlyConfigured(Error): pass
30
31
32 def load_controller(string):
33 module_name, func_name = string.split(':', 1)
34 __import__(module_name)
35 module = sys.modules[module_name]
36 func = getattr(module, func_name)
37 return func
38
39
40 class MediaGoblinApp(object):
41 """
42 Really basic wsgi app using routes and WebOb.
43 """
44 def __init__(self, connection, database_path, user_template_path=None):
45 self.template_env = util.get_jinja_env(user_template_path)
46 self.connection = connection
47 self.db = connection[database_path]
48 self.routing = routing.get_mapper()
49
50 models.register_models(connection)
51
52 def __call__(self, environ, start_response):
53 request = Request(environ)
54 path_info = request.path_info
55 route_match = self.routing.match(path_info)
56
57 # No matching page?
58 if route_match is None:
59 # Try to do see if we have a match with a trailing slash
60 # added and if so, redirect
61 if not path_info.endswith('/') \
62 and request.method == 'GET' \
63 and self.routing.match(path_info + '/'):
64 new_path_info = path_info + '/'
65 if request.GET:
66 new_path_info = '%s?%s' % (
67 new_path_info, urllib.urlencode(request.GET))
68 redirect = exc.HTTPTemporaryRedirect(location=new_path_info)
69 return request.get_response(redirect)(environ, start_response)
70
71 # Okay, no matches. 404 time!
72 return exc.HTTPNotFound()(environ, start_response)
73
74 controller = load_controller(route_match['controller'])
75 request.start_response = start_response
76
77 request.matchdict = route_match
78 request.app = self
79 request.template_env = self.template_env
80 request.urlgen = routes.URLGenerator(self.routing, environ)
81 request.db = self.db
82 # Do we really want to load this via middleware? Maybe?
83 request.session = request.environ['beaker.session']
84 util.setup_user_in_request(request)
85
86 return controller(request)(environ, start_response)
87
88
89 def paste_app_factory(global_config, **kw):
90 connection = mongokit.Connection(
91 kw.get('db_host'), kw.get('db_port'))
92
93 mgoblin_app = MediaGoblinApp(
94 connection, kw.get('db_name', 'mediagoblin'),
95 user_template_path=kw.get('local_templates'))
96
97 return mgoblin_app