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

1099.1.34 by William Grant
Split up ivle.webapp.base.views into ivle.webapp.base.{rest,xhtml}, as it was
1
# IVLE - Informatics Virtual Learning Environment
2
# Copyright (C) 2007-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: Nick Chadwick
19
20
import inspect
21
import os.path
22
23
import genshi.template
24
1099.1.60 by William Grant
Add support in XHTMLView for plugin styles and scripts.
25
from ivle.webapp.media import media_url
1092.1.24 by William Grant
Convince the main XHTML template to use versioned styles/scripts, and move the
26
from ivle.webapp.core import Plugin as CorePlugin
1099.1.34 by William Grant
Split up ivle.webapp.base.views into ivle.webapp.base.{rest,xhtml}, as it was
27
from ivle.webapp.base.views import BaseView
1099.1.74 by Nick Chadwick
Added overlay system and console overlay. Note that the console overlay
28
from ivle.webapp.base.plugins import OverlayPlugin
1099.1.96 by William Grant
Add an XHTMLUnauthorizedView which redirects unauthenticated users to the
29
from ivle.webapp.errors import HTTPError, Unauthorized
1099.1.34 by William Grant
Split up ivle.webapp.base.views into ivle.webapp.base.{rest,xhtml}, as it was
30
import ivle.conf
31
import ivle.util
32
33
class XHTMLView(BaseView):
34
    """
35
    A view which provides a base class for views which need to return XHTML
36
    It is expected that apps which use this view will be written using Genshi
37
    templates.
38
    """
1099.1.60 by William Grant
Add support in XHTMLView for plugin styles and scripts.
39
40
    template = 'template.html'
41
    plugin_scripts = {}
42
    plugin_styles = {}
1099.1.74 by Nick Chadwick
Added overlay system and console overlay. Note that the console overlay
43
    overlay_blacklist = []
1099.1.60 by William Grant
Add support in XHTMLView for plugin styles and scripts.
44
1099.1.34 by William Grant
Split up ivle.webapp.base.views into ivle.webapp.base.{rest,xhtml}, as it was
45
    def __init__(self, req, **kwargs):
46
        for key in kwargs:
1099.1.46 by Nick Chadwick
Fixed a slight issue in the indentation of xhtml.py
47
            setattr(self, key, kwargs[key])
1099.1.38 by William Grant
ivle.webapp.base.xhtml.XHTMLView: Split the global and view contexts.
48
1099.1.34 by William Grant
Split up ivle.webapp.base.views into ivle.webapp.base.{rest,xhtml}, as it was
49
    def render(self, req):
50
        req.content_type = 'text/html' # TODO: Detect application/xhtml+xml
1099.1.38 by William Grant
ivle.webapp.base.xhtml.XHTMLView: Split the global and view contexts.
51
52
        # View template
53
        viewctx = genshi.template.Context()
54
        self.populate(req, viewctx)
55
56
        # The template is found in the directory of the module containing the
57
        # view.
1099.1.34 by William Grant
Split up ivle.webapp.base.views into ivle.webapp.base.{rest,xhtml}, as it was
58
        app_template = os.path.join(os.path.dirname(
1099.1.35 by William Grant
ivle.webapp.base.xhtml#XHTMLView: Rename app_template to template (the things
59
                        inspect.getmodule(self).__file__), self.template) 
1099.1.34 by William Grant
Split up ivle.webapp.base.views into ivle.webapp.base.{rest,xhtml}, as it was
60
        req.write_html_head_foot = False
61
        loader = genshi.template.TemplateLoader(".", auto_reload=True)
62
        tmpl = loader.load(app_template)
1099.1.38 by William Grant
ivle.webapp.base.xhtml.XHTMLView: Split the global and view contexts.
63
        app = tmpl.generate(viewctx)
64
1099.1.60 by William Grant
Add support in XHTMLView for plugin styles and scripts.
65
        for plugin in self.plugin_scripts:
66
            for path in self.plugin_scripts[plugin]:
67
                req.scripts.append(media_url(req, plugin, path))
68
69
        for plugin in self.plugin_styles:
70
            for path in self.plugin_styles[plugin]:
71
                req.styles.append(media_url(req, plugin, path))
72
1099.1.38 by William Grant
ivle.webapp.base.xhtml.XHTMLView: Split the global and view contexts.
73
        # Global template
74
        ctx = genshi.template.Context()
1099.1.74 by Nick Chadwick
Added overlay system and console overlay. Note that the console overlay
75
        # XXX: Leave this here!! (Before req.styles is read)
76
        ctx['overlays'] = self.render_overlays(req)
1092.1.24 by William Grant
Convince the main XHTML template to use versioned styles/scripts, and move the
77
78
        ctx['styles'] = [media_url(req, CorePlugin, 'ivle.css')]
79
        ctx['styles'] += req.styles
80
81
        ctx['scripts'] = [media_url(req, CorePlugin, path) for path in
82
                           ('util.js', 'json2.js', 'md5.js', 'tos.js')]
83
        ctx['scripts'] += req.scripts
84
1099.1.38 by William Grant
ivle.webapp.base.xhtml.XHTMLView: Split the global and view contexts.
85
        ctx['scripts_init'] = req.scripts_init
1099.1.34 by William Grant
Split up ivle.webapp.base.views into ivle.webapp.base.{rest,xhtml}, as it was
86
        ctx['app_template'] = app
1099.1.38 by William Grant
ivle.webapp.base.xhtml.XHTMLView: Split the global and view contexts.
87
        self.populate_headings(req, ctx)
1099.1.34 by William Grant
Split up ivle.webapp.base.views into ivle.webapp.base.{rest,xhtml}, as it was
88
        tmpl = loader.load(os.path.join(os.path.dirname(__file__), 
89
                                                        'ivle-headings.html'))
90
        req.write(tmpl.generate(ctx).render('xhtml', doctype='xhtml'))
1099.1.74 by Nick Chadwick
Added overlay system and console overlay. Note that the console overlay
91
        
92
    def populate(self, req, ctx):
93
        raise NotImplementedError()
1099.1.34 by William Grant
Split up ivle.webapp.base.views into ivle.webapp.base.{rest,xhtml}, as it was
94
95
    def populate_headings(self, req, ctx):
96
        ctx['favicon'] = None
97
        ctx['root_dir'] = ivle.conf.root_dir
98
        ctx['public_host'] = ivle.conf.public_host
99
        ctx['write_javascript_settings'] = req.write_javascript_settings
100
        if req.user:
101
            ctx['login'] = req.user.login
102
            ctx['logged_in'] = True
103
            ctx['nick'] = req.user.nick
104
        else:
105
            ctx['login'] = None
1099.1.92 by William Grant
Fix the XHTML base template to not crash when not logged in.
106
            ctx['logged_in'] = False
1099.1.34 by William Grant
Split up ivle.webapp.base.views into ivle.webapp.base.{rest,xhtml}, as it was
107
        ctx['publicmode'] = req.publicmode
108
        ctx['apps_in_tabs'] = []
1099.1.100 by Nick Chadwick
Created a new help system.
109
        if hasattr(self, 'help'):
110
            ctx['help_path'] = self.help
1099.1.34 by William Grant
Split up ivle.webapp.base.views into ivle.webapp.base.{rest,xhtml}, as it was
111
        for urlname in ivle.conf.apps.apps_in_tabs:
112
            new_app = {}
113
            app = ivle.conf.apps.app_url[urlname]
1099.1.35 by William Grant
ivle.webapp.base.xhtml#XHTMLView: Rename app_template to template (the things
114
            new_app['this_app'] = hasattr(self, 'appname') \
115
                                  and urlname == self.appname
1099.1.34 by William Grant
Split up ivle.webapp.base.views into ivle.webapp.base.{rest,xhtml}, as it was
116
            if app.icon:
117
                new_app['has_icon'] = True
118
                icon_dir = ivle.conf.apps.app_icon_dir
119
                icon_url = ivle.util.make_path(os.path.join(icon_dir, app.icon))
120
                new_app['icon_url'] = icon_url
121
                if new_app['this_app']:
122
                    ctx['favicon'] = icon_url
123
            else:
124
                new_app['has_icon'] = False
125
            new_app['path'] = ivle.util.make_path(urlname)
126
            new_app['desc'] = app.desc
127
            new_app['name'] = app.name
128
            ctx['apps_in_tabs'].append(new_app)
1099.1.74 by Nick Chadwick
Added overlay system and console overlay. Note that the console overlay
129
            
130
    def render_overlays(self, req):
131
        """Generate XML streams for the overlays.
132
        
133
        Returns a list of streams. Populates the scripts, styles, and 
134
        scripts_init.
135
        """
136
        overlays = []
137
        for plugin in req.plugin_index[OverlayPlugin]:
138
            for overclass in plugin.overlays:
139
                if overclass in self.overlay_blacklist:
140
                    continue
141
                overlay = overclass(req)
142
                #TODO: Re-factor this to look nicer
143
                for mplugin in overlay.plugin_scripts:
144
                    for path in overlay.plugin_scripts[mplugin]:
145
                        req.scripts.append(media_url(req, mplugin, path))
146
147
                for mplugin in overlay.plugin_styles:
148
                    for path in overlay.plugin_styles[mplugin]:
149
                        req.styles.append(media_url(req, mplugin, path))
1099.1.91 by William Grant
Add support for custom error views. Plugins can now declare that errors
150
1099.1.74 by Nick Chadwick
Added overlay system and console overlay. Note that the console overlay
151
                req.scripts_init += overlay.plugin_scripts_init
1099.1.91 by William Grant
Add support for custom error views. Plugins can now declare that errors
152
1099.1.74 by Nick Chadwick
Added overlay system and console overlay. Note that the console overlay
153
                overlays.append(overlay.render(req))
154
        return overlays
1099.1.91 by William Grant
Add support for custom error views. Plugins can now declare that errors
155
1099.1.95 by William Grant
Error views are now retrieved from a class method of the view, not the plugin
156
    @classmethod
157
    def get_error_view(cls, e):
1099.1.96 by William Grant
Add an XHTMLUnauthorizedView which redirects unauthenticated users to the
158
        view_map = {HTTPError:    XHTMLErrorView,
159
                    Unauthorized: XHTMLUnauthorizedView}
1099.1.95 by William Grant
Error views are now retrieved from a class method of the view, not the plugin
160
        for exccls in inspect.getmro(type(e)):
161
            if exccls in view_map:
162
                return view_map[exccls]
163
1099.1.91 by William Grant
Add support for custom error views. Plugins can now declare that errors
164
class XHTMLErrorView(XHTMLView):
165
    template = 'xhtmlerror.html'
166
167
    def __init__(self, req, exception):
168
        self.context = exception
169
170
    def populate(self, req, ctx):
171
        ctx['exception'] = self.context
1099.1.96 by William Grant
Add an XHTMLUnauthorizedView which redirects unauthenticated users to the
172
173
class XHTMLUnauthorizedView(XHTMLErrorView):
174
    template = 'xhtmlunauthorized.html'
175
176
    def __init__(self, req, exception):
177
        super(XHTMLUnauthorizedView, self).__init__(req, exception)
178
        if req.user is None:
179
            # Not logged in. Redirect to login page.
180
            req.throw_redirect('/') # XXX: Need proper URL.
181
182
        req.status = 403