Use request.app.db, not request.db
[mediagoblin.git] / mediagoblin / app.py
CommitLineData
8e1e744d 1# GNU MediaGoblin -- federated, autonomous media hosting
e5572c60
ML
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 urllib
18
31a8ff42 19import routes
2b4e236a 20import mongokit
b61874b2 21from webob import Request, exc
31a8ff42 22
582c4d5f 23from mediagoblin import routing, util, models, storage, staticdirect
31a8ff42
CAW
24
25
26class Error(Exception): pass
27class ImproperlyConfigured(Error): pass
28
29
8e1e744d 30class MediaGoblinApp(object):
31a8ff42
CAW
31 """
32 Really basic wsgi app using routes and WebOb.
33 """
5afdd7a1
CAW
34 def __init__(self, connection, database_path,
35 public_store, queue_store,
582c4d5f 36 staticdirector,
5afdd7a1
CAW
37 user_template_path=None):
38 # Get the template environment
31a8ff42 39 self.template_env = util.get_jinja_env(user_template_path)
5afdd7a1
CAW
40
41 # Set up storage systems
42 self.public_store = public_store
43 self.queue_store = queue_store
44
45 # Set up database
2b4e236a 46 self.connection = connection
65d7374c 47 self.db = connection[database_path]
5afdd7a1
CAW
48 models.register_models(connection)
49
50 # set up routing
0f63a944 51 self.routing = routing.get_mapper()
31a8ff42 52
582c4d5f
CAW
53 # set up staticdirector tool
54 self.staticdirector = staticdirector
2b4e236a 55
31a8ff42
CAW
56 def __call__(self, environ, start_response):
57 request = Request(environ)
58 path_info = request.path_info
582c4d5f
CAW
59
60 ## Routing / controller loading stuff
0f63a944 61 route_match = self.routing.match(path_info)
31a8ff42
CAW
62
63 # No matching page?
64 if route_match is None:
65 # Try to do see if we have a match with a trailing slash
66 # added and if so, redirect
67 if not path_info.endswith('/') \
68 and request.method == 'GET' \
0f63a944 69 and self.routing.match(path_info + '/'):
31a8ff42
CAW
70 new_path_info = path_info + '/'
71 if request.GET:
72 new_path_info = '%s?%s' % (
73 new_path_info, urllib.urlencode(request.GET))
74 redirect = exc.HTTPTemporaryRedirect(location=new_path_info)
75 return request.get_response(redirect)(environ, start_response)
76
77 # Okay, no matches. 404 time!
78 return exc.HTTPNotFound()(environ, start_response)
79
cb8ea0fe 80 controller = util.import_component(route_match['controller'])
31a8ff42
CAW
81 request.start_response = start_response
82
582c4d5f 83 ## Attach utilities to the request object
31a8ff42 84 request.matchdict = route_match
0f63a944 85 request.urlgen = routes.URLGenerator(self.routing, environ)
7846e406 86 # Do we really want to load this via middleware? Maybe?
14ba9383 87 request.session = request.environ['beaker.session']
a3fdcf5c 88 util.setup_user_in_request(request)
0dd65945
CAW
89 # Attach self as request.app
90 # Also attach a few utilities from request.app for convenience?
91 request.app = self
92 request.template_env = self.template_env
93 request.db = self.db
94 request.staticdirect = self.staticdirector
31a8ff42
CAW
95
96 return controller(request)(environ, start_response)
97
98
99def paste_app_factory(global_config, **kw):
cb8ea0fe 100 # Get the database connection
2b4e236a
CAW
101 connection = mongokit.Connection(
102 kw.get('db_host'), kw.get('db_port'))
73e0dbcc 103
cb8ea0fe 104 # Set up the storage systems.
5afdd7a1
CAW
105 public_store = storage.storage_system_from_paste_config(
106 kw, 'publicstore')
107 queue_store = storage.storage_system_from_paste_config(
108 kw, 'queuestore')
109
582c4d5f
CAW
110 # Set up the staticdirect system
111 if kw.has_key('direct_remote_path'):
112 staticdirector = staticdirect.RemoteStaticDirect(
113 kw['direct_remote_path'].strip())
114 elif kw.has_key('direct_remote_paths'):
115 staticdirector = staticdirect.MultiRemoteStaticDirect(
116 dict([line.strip().split(' ', 1)
117 for line in kw['direct_remote_paths'].strip().splitlines()]))
118 else:
119 raise ImproperlyConfigured(
120 "One of direct_remote_path or direct_remote_paths must be provided")
121
8e1e744d 122 mgoblin_app = MediaGoblinApp(
2b4e236a 123 connection, kw.get('db_name', 'mediagoblin'),
5afdd7a1 124 public_store=public_store, queue_store=queue_store,
582c4d5f 125 staticdirector=staticdirector,
2b4e236a 126 user_template_path=kw.get('local_templates'))
b61874b2 127
c4d71564 128 return mgoblin_app