Adds documentation.
[mediagoblin.git] / mediagoblin / app.py
CommitLineData
e5572c60
ML
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
31a8ff42
CAW
17import sys
18import urllib
19
b61874b2 20from beaker.middleware import SessionMiddleware
31a8ff42 21import routes
2b4e236a 22import mongokit
b61874b2 23from webob import Request, exc
31a8ff42 24
2b4e236a 25from mediagoblin import routing, util, models
31a8ff42
CAW
26
27
28class Error(Exception): pass
29class ImproperlyConfigured(Error): pass
30
31
32def 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
40class MediagoblinApp(object):
41 """
42 Really basic wsgi app using routes and WebOb.
43 """
2b4e236a 44 def __init__(self, connection, database_path, user_template_path=None):
31a8ff42 45 self.template_env = util.get_jinja_env(user_template_path)
2b4e236a 46 self.connection = connection
65d7374c 47 self.db = connection[database_path]
0f63a944 48 self.routing = routing.get_mapper()
31a8ff42 49
2b4e236a
CAW
50 models.register_models(connection)
51
31a8ff42
CAW
52 def __call__(self, environ, start_response):
53 request = Request(environ)
54 path_info = request.path_info
0f63a944 55 route_match = self.routing.match(path_info)
31a8ff42
CAW
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' \
0f63a944 63 and self.routing.match(path_info + '/'):
31a8ff42
CAW
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
0f63a944 80 request.urlgen = routes.URLGenerator(self.routing, environ)
2b4e236a 81 request.db = self.db
7846e406 82 # Do we really want to load this via middleware? Maybe?
14ba9383 83 request.session = request.environ['beaker.session']
a3fdcf5c 84 util.setup_user_in_request(request)
31a8ff42
CAW
85
86 return controller(request)(environ, start_response)
87
88
89def paste_app_factory(global_config, **kw):
2b4e236a
CAW
90 connection = mongokit.Connection(
91 kw.get('db_host'), kw.get('db_port'))
73e0dbcc 92
b61874b2 93 mgoblin_app = MediagoblinApp(
2b4e236a
CAW
94 connection, kw.get('db_name', 'mediagoblin'),
95 user_template_path=kw.get('local_templates'))
b61874b2 96
c4d71564 97 return mgoblin_app