29
from ivle.config import Config
30
28
from ivle.webapp.base.views import BaseView
31
from ivle.webapp.base.plugins import ViewPlugin, MediaPlugin
29
from ivle.webapp.base.plugins import PublicViewPlugin, ViewPlugin, MediaPlugin
32
30
from ivle.webapp.errors import NotFound, Forbidden
34
32
def media_url(req, plugin, path):
43
41
if not isinstance(plugin, basestring):
44
42
plugin = req.config.reverse_plugins[plugin]
48
media_path = os.path.join('+media', '+' + config['media']['version']) if \
49
config['media']['version'] else '+media'
51
return os.path.join(ivle.conf.root_dir, media_path, plugin, path)
44
media_path = os.path.join('+media', '+' + req.config['media']['version']) \
45
if req.config['media']['version'] else '+media'
47
return req.make_path(os.path.join(media_path, plugin, path))
53
49
class BaseMediaFileView(BaseView):
54
50
'''A view for media files.
141
137
return super(VersionedMediaFileView, self)._make_filename(req)
143
class Plugin(ViewPlugin):
140
# This maps a media namespace to an external dependency directory (in this
141
# case specified by the configuration option media/externals/jquery) and a
142
# list of permitted subpaths.
143
EXTERNAL_MEDIA_MAP = {'jquery': ('jquery', ['jquery.js'])}
145
class ExternalMediaFileView(BaseMediaFileView):
146
'''A view for media files from external dependencies.
148
This serves specific static files from external dependencies as defined in
149
the IVLE configuration.
153
def _make_filename(self, req):
155
extern = EXTERNAL_MEDIA_MAP[self.ns]
159
# Unless it's a whitelisted path, we don't want to hear about it.
160
if self.path not in extern[1]:
163
# Grab the admin-configured path for this particular external dep.
164
externdir = req.config['media']['externals'][extern[0]]
166
assert isinstance(externdir, basestring)
168
return os.path.join(externdir, self.path)
170
def get_permissions(self, user):
173
class ExternalVersionedMediaFileView(ExternalMediaFileView):
174
'''A view for versioned media files from external dependencies, with
177
This serves specific static media files from external dependencies with a
178
version string, and requests that browsers cache them for a long time.
181
def __init__(self, req, ns, path, version):
182
super(ExternalVersionedMediaFileView, self).__init__(req, ns, path)
183
self.version = version
185
def _make_filename(self, req):
186
if self.version != req.config['media']['version']:
189
# Don't expire for a year.
190
req.headers_out['Expires'] = email.utils.formatdate(
191
timeval=time.time() + (60*60*24*365),
194
return super(ExternalVersionedMediaFileView, self)._make_filename(req)
197
class Plugin(ViewPlugin, PublicViewPlugin):
199
('+media/+:version/+external/:ns/*path', ExternalVersionedMediaFileView),
200
('+media/+external/:ns/*path', ExternalMediaFileView),
145
201
('+media/+:version/:ns/*path', VersionedMediaFileView),
146
202
('+media/:ns/*path', MediaFileView),