~azzar1/unity/add-show-desktop-key

1099.1.59 by William Grant
Provide a media file framework in ivle.webapp.media.
1
# IVLE - Informatics Virtual Learning Environment
2
# Copyright (C) 2009 The University of Melbourne
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 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 General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18
# Author: William Grant
19
20
'''Media file support for the framework.'''
21
22
import os
23
import inspect
24
import mimetypes
25
26
import ivle.conf
27
from ivle.webapp.base.views import BaseView
1099.1.99 by William Grant
Require that plugins providing media subclass MediaPlugin.
28
from ivle.webapp.base.plugins import ViewPlugin, MediaPlugin
1099.1.85 by William Grant
Fix some missing error imports in the webapp.
29
from ivle.webapp.errors import NotFound, Forbidden
1099.1.59 by William Grant
Provide a media file framework in ivle.webapp.media.
30
31
def media_url(req, plugin, path):
1099.1.74 by Nick Chadwick
Added overlay system and console overlay. Note that the console overlay
32
    '''Generates a URL to a media file.
33
    
34
    Plugin can be a string, in which case it is put into the path literally,
35
    or a plugin object, in which case its name is looked up.'''
36
    if not isinstance(plugin, basestring):
37
        plugin = req.reverse_plugins[plugin]
1099.1.99 by William Grant
Require that plugins providing media subclass MediaPlugin.
38
1099.1.74 by Nick Chadwick
Added overlay system and console overlay. Note that the console overlay
39
    return os.path.join(ivle.conf.root_dir, '+media', plugin, path)
1099.1.59 by William Grant
Provide a media file framework in ivle.webapp.media.
40
1099.1.110 by William Grant
Implement an authorization system in the new framework. This breaks the REST
41
class BaseMediaFileView(BaseView):
1099.1.59 by William Grant
Provide a media file framework in ivle.webapp.media.
42
    '''A view for media files.
43
44
    This serves static files from directories registered by plugins.
45
46
    Plugins wishing to export media should declare a 'media' attribute,
47
    pointing to the directory to serve (relative to the module's directory).
48
    The contents of that directory will then be available under
49
    /+media/python.path.to.module.
50
    '''
51
    def __init__(self, req, ns, path):
52
        self.ns = ns
53
        self.path = path
54
55
    def _make_filename(self, req):
1099.1.110 by William Grant
Implement an authorization system in the new framework. This breaks the REST
56
        raise NotImplementedError()
1099.1.59 by William Grant
Provide a media file framework in ivle.webapp.media.
57
58
    def render(self, req):
59
        # If it begins with ".." or separator, it's illegal. Die.
60
        if self.path.startswith("..") or self.path.startswith('/'):
61
            raise Forbidden()
62
63
        filename = self._make_filename(req)
64
65
        # Find an appropriate MIME type.
66
        (type, _) = mimetypes.guess_type(filename)
67
        if type is None:
68
            type = 'application/octet-stream'
69
70
        # Get out if it is unreadable or a directory.
71
        if not os.access(filename, os.F_OK):
1099.1.62 by William Grant
Remove a bit of debugging cruft from ivle.webapp.media.
72
            raise NotFound()
1099.1.59 by William Grant
Provide a media file framework in ivle.webapp.media.
73
        if not os.access(filename, os.R_OK) or os.path.isdir(filename):
74
            raise Forbidden()
75
76
        req.content_type = type
77
        req.sendfile(filename)
78
1099.1.110 by William Grant
Implement an authorization system in the new framework. This breaks the REST
79
80
class MediaFileView(BaseMediaFileView):
81
    '''A view for media files.
82
83
    This serves static files from directories registered by plugins.
84
85
    Plugins wishing to export media should declare a 'media' attribute,
86
    pointing to the directory to serve (relative to the module's directory).
87
    The contents of that directory will then be available under
88
    /+media/python.path.to.module.
89
    '''
90
    permission = None
91
92
    def _make_filename(self, req):
93
        try:
94
            plugin = req.plugins[self.ns]
95
        except KeyError:
96
            raise NotFound()
97
98
        if not issubclass(plugin, MediaPlugin):
99
            raise NotFound()
100
101
        mediadir = plugin.media
102
        plugindir = os.path.dirname(inspect.getmodule(plugin).__file__)
103
104
        return os.path.join(plugindir, mediadir, self.path)
105
106
    def get_permissions(self, user):
107
        return set()
108
1099.1.72 by Nick Chadwick
Dispatch now generates an index for each plugin type, allowing plugins to
109
class Plugin(ViewPlugin):
1099.1.59 by William Grant
Provide a media file framework in ivle.webapp.media.
110
    urls = [
111
        ('+media/:ns/*path', MediaFileView),
112
    ]