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