Modified logo to change on :hover
[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
571198c9 17import os
31a8ff42
CAW
18import urllib
19
31a8ff42 20import routes
86f9b473 21from paste.deploy.converters import asbool
b61874b2 22from webob import Request, exc
31a8ff42 23
0f18ed8f 24from mediagoblin import routing, util, storage, staticdirect
a67fec81 25from mediagoblin.db.open import setup_connection_and_db_from_config
df9809c2 26from mediagoblin.globals import setup_globals
5784c4e9 27from mediagoblin.celery_setup import setup_celery_from_config
31a8ff42
CAW
28
29
30class Error(Exception): pass
31class ImproperlyConfigured(Error): pass
32
33
8e1e744d 34class MediaGoblinApp(object):
31a8ff42
CAW
35 """
36 Really basic wsgi app using routes and WebOb.
37 """
a67fec81 38 def __init__(self, connection, db,
5afdd7a1 39 public_store, queue_store,
582c4d5f 40 staticdirector,
29f3fb70 41 email_sender_address, email_debug_mode,
5afdd7a1
CAW
42 user_template_path=None):
43 # Get the template environment
0e0e3d9a 44 self.template_loader = util.get_jinja_loader(user_template_path)
5afdd7a1
CAW
45
46 # Set up storage systems
47 self.public_store = public_store
48 self.queue_store = queue_store
49
50 # Set up database
2b4e236a 51 self.connection = connection
a67fec81 52 self.db = db
5afdd7a1
CAW
53
54 # set up routing
0f63a944 55 self.routing = routing.get_mapper()
31a8ff42 56
582c4d5f
CAW
57 # set up staticdirector tool
58 self.staticdirector = staticdirector
2b4e236a 59
df9809c2
CAW
60 # certain properties need to be accessed globally eg from
61 # validators, etc, which might not access to the request
62 # object.
63 setup_globals(
4c093e85 64 email_sender_address=email_sender_address,
29f3fb70 65 email_debug_mode=email_debug_mode,
df9809c2
CAW
66 db_connection=connection,
67 database=self.db,
68 public_store=self.public_store,
69 queue_store=self.queue_store)
70
31a8ff42
CAW
71 def __call__(self, environ, start_response):
72 request = Request(environ)
73 path_info = request.path_info
582c4d5f
CAW
74
75 ## Routing / controller loading stuff
0f63a944 76 route_match = self.routing.match(path_info)
31a8ff42
CAW
77
78 # No matching page?
79 if route_match is None:
80 # Try to do see if we have a match with a trailing slash
81 # added and if so, redirect
82 if not path_info.endswith('/') \
83 and request.method == 'GET' \
0f63a944 84 and self.routing.match(path_info + '/'):
31a8ff42
CAW
85 new_path_info = path_info + '/'
86 if request.GET:
87 new_path_info = '%s?%s' % (
88 new_path_info, urllib.urlencode(request.GET))
1bb0fdf2 89 redirect = exc.HTTPFound(location=new_path_info)
31a8ff42
CAW
90 return request.get_response(redirect)(environ, start_response)
91
92 # Okay, no matches. 404 time!
93 return exc.HTTPNotFound()(environ, start_response)
94
cb8ea0fe 95 controller = util.import_component(route_match['controller'])
31a8ff42
CAW
96 request.start_response = start_response
97
582c4d5f 98 ## Attach utilities to the request object
31a8ff42 99 request.matchdict = route_match
0f63a944 100 request.urlgen = routes.URLGenerator(self.routing, environ)
7846e406 101 # Do we really want to load this via middleware? Maybe?
14ba9383 102 request.session = request.environ['beaker.session']
0dd65945
CAW
103 # Attach self as request.app
104 # Also attach a few utilities from request.app for convenience?
105 request.app = self
0e0e3d9a
CAW
106 request.locale = util.get_locale_from_request(request)
107
108 request.template_env = util.get_jinja_env(
109 self.template_loader, request.locale)
0dd65945
CAW
110 request.db = self.db
111 request.staticdirect = self.staticdirector
31a8ff42 112
ddff7cce
CAW
113 util.setup_user_in_request(request)
114
31a8ff42
CAW
115 return controller(request)(environ, start_response)
116
117
5784c4e9 118def paste_app_factory(global_config, **app_config):
cb8ea0fe 119 # Get the database connection
a67fec81 120 connection, db = setup_connection_and_db_from_config(app_config)
73e0dbcc 121
cb8ea0fe 122 # Set up the storage systems.
5afdd7a1 123 public_store = storage.storage_system_from_paste_config(
5784c4e9 124 app_config, 'publicstore')
5afdd7a1 125 queue_store = storage.storage_system_from_paste_config(
5784c4e9 126 app_config, 'queuestore')
5afdd7a1 127
582c4d5f 128 # Set up the staticdirect system
5784c4e9 129 if app_config.has_key('direct_remote_path'):
582c4d5f 130 staticdirector = staticdirect.RemoteStaticDirect(
5784c4e9
CAW
131 app_config['direct_remote_path'].strip())
132 elif app_config.has_key('direct_remote_paths'):
133 direct_remote_path_lines = app_config[
134 'direct_remote_paths'].strip().splitlines()
582c4d5f
CAW
135 staticdirector = staticdirect.MultiRemoteStaticDirect(
136 dict([line.strip().split(' ', 1)
5784c4e9 137 for line in direct_remote_path_lines]))
582c4d5f
CAW
138 else:
139 raise ImproperlyConfigured(
140 "One of direct_remote_path or direct_remote_paths must be provided")
141
571198c9
CAW
142 if asbool(os.environ.get('CELERY_ALWAYS_EAGER')):
143 setup_celery_from_config(
144 app_config, global_config,
145 force_celery_always_eager=True)
146 else:
147 setup_celery_from_config(app_config, global_config)
5784c4e9 148
8e1e744d 149 mgoblin_app = MediaGoblinApp(
a67fec81 150 connection, db,
5afdd7a1 151 public_store=public_store, queue_store=queue_store,
582c4d5f 152 staticdirector=staticdirector,
29f3fb70
CAW
153 email_sender_address=app_config.get(
154 'email_sender_address', 'notice@mediagoblin.example.org'),
cd847fd3 155 email_debug_mode=asbool(app_config.get('email_debug_mode')),
5784c4e9 156 user_template_path=app_config.get('local_templates'))
b61874b2 157
c4d71564 158 return mgoblin_app