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

« back to all changes in this revision

Viewing changes to ivle/webapp/base/xhtml.py

  • Committer: William Grant
  • Date: 2009-04-02 07:08:27 UTC
  • mto: (1165.3.1 submissions)
  • mto: This revision was merged to the branch mainline in revision 1174.
  • Revision ID: grantw@unimelb.edu.au-20090402070827-1lxkwhpni15ucmdm
Expose the IVLE SVN base URL to JS.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 
20
20
import inspect
21
21
import os.path
 
22
import urllib
22
23
 
23
24
import genshi.template
24
25
 
 
26
from ivle.webapp.media import media_url
 
27
from ivle.webapp.core import Plugin as CorePlugin
25
28
from ivle.webapp.base.views import BaseView
 
29
from ivle.webapp.base.plugins import ViewPlugin, OverlayPlugin
 
30
from ivle.webapp.errors import HTTPError, Unauthorized
26
31
import ivle.conf
27
32
import ivle.util
28
33
 
32
37
    It is expected that apps which use this view will be written using Genshi
33
38
    templates.
34
39
    """
 
40
 
 
41
    template = 'template.html'
 
42
    plugin_scripts = {}
 
43
    plugin_styles = {}
 
44
    allow_overlays = True
 
45
    overlay_blacklist = []
 
46
 
35
47
    def __init__(self, req, **kwargs):
36
48
        for key in kwargs:
37
 
          setattr(self, key, kwargs[key])
 
49
            setattr(self, key, kwargs[key])
 
50
 
 
51
    def filter(self, stream, ctx):
 
52
        return stream
38
53
 
39
54
    def render(self, req):
40
55
        req.content_type = 'text/html' # TODO: Detect application/xhtml+xml
47
62
        # view.
48
63
        app_template = os.path.join(os.path.dirname(
49
64
                        inspect.getmodule(self).__file__), self.template) 
50
 
        req.write_html_head_foot = False
51
65
        loader = genshi.template.TemplateLoader(".", auto_reload=True)
52
66
        tmpl = loader.load(app_template)
53
 
        app = tmpl.generate(viewctx)
 
67
        app = self.filter(tmpl.generate(viewctx), viewctx)
 
68
 
 
69
        for plugin in self.plugin_scripts:
 
70
            for path in self.plugin_scripts[plugin]:
 
71
                req.scripts.append(media_url(req, plugin, path))
 
72
 
 
73
        for plugin in self.plugin_styles:
 
74
            for path in self.plugin_styles[plugin]:
 
75
                req.styles.append(media_url(req, plugin, path))
54
76
 
55
77
        # Global template
56
78
        ctx = genshi.template.Context()
57
 
        ctx['app_styles'] = req.styles
58
 
        ctx['scripts'] = req.scripts
 
79
        # XXX: Leave this here!! (Before req.styles is read)
 
80
        ctx['overlays'] = self.render_overlays(req) if req.user else []
 
81
 
 
82
        ctx['styles'] = [media_url(req, CorePlugin, 'ivle.css')]
 
83
        ctx['styles'] += req.styles
 
84
 
 
85
        ctx['scripts'] = [media_url(req, CorePlugin, path) for path in
 
86
                           ('util.js', 'json2.js', 'md5.js')]
 
87
        ctx['scripts'].append(media_url(req, '+external/jquery', 'jquery.js'))
 
88
        ctx['scripts'] += req.scripts
 
89
 
59
90
        ctx['scripts_init'] = req.scripts_init
60
91
        ctx['app_template'] = app
 
92
        ctx['title_img'] = media_url(req, CorePlugin,
 
93
                                     "images/chrome/title.png")
61
94
        self.populate_headings(req, ctx)
62
95
        tmpl = loader.load(os.path.join(os.path.dirname(__file__), 
63
96
                                                        'ivle-headings.html'))
64
97
        req.write(tmpl.generate(ctx).render('xhtml', doctype='xhtml'))
 
98
        
 
99
    def populate(self, req, ctx):
 
100
        raise NotImplementedError()
65
101
 
66
102
    def populate_headings(self, req, ctx):
67
103
        ctx['favicon'] = None
68
104
        ctx['root_dir'] = ivle.conf.root_dir
69
105
        ctx['public_host'] = ivle.conf.public_host
 
106
        ctx['svn_base'] = ivle.conf.svn_addr
70
107
        ctx['write_javascript_settings'] = req.write_javascript_settings
71
108
        if req.user:
72
109
            ctx['login'] = req.user.login
74
111
            ctx['nick'] = req.user.nick
75
112
        else:
76
113
            ctx['login'] = None
 
114
            ctx['logged_in'] = False
77
115
        ctx['publicmode'] = req.publicmode
 
116
        if hasattr(self, 'help'):
 
117
            ctx['help_path'] = self.help
 
118
 
78
119
        ctx['apps_in_tabs'] = []
79
 
        for urlname in ivle.conf.apps.apps_in_tabs:
80
 
            new_app = {}
81
 
            app = ivle.conf.apps.app_url[urlname]
82
 
            new_app['this_app'] = hasattr(self, 'appname') \
83
 
                                  and urlname == self.appname
84
 
            if app.icon:
85
 
                new_app['has_icon'] = True
86
 
                icon_dir = ivle.conf.apps.app_icon_dir
87
 
                icon_url = ivle.util.make_path(os.path.join(icon_dir, app.icon))
88
 
                new_app['icon_url'] = icon_url
89
 
                if new_app['this_app']:
90
 
                    ctx['favicon'] = icon_url
 
120
        for plugin in req.config.plugin_index[ViewPlugin]:
 
121
            if not hasattr(plugin, 'tabs'):
 
122
                continue
 
123
 
 
124
            for tab in plugin.tabs:
 
125
                # tab is a tuple: name, title, desc, icon, path
 
126
                new_app = {}
 
127
                new_app['this_app'] = hasattr(self, 'tab') \
 
128
                                      and tab[0] == self.tab
 
129
 
 
130
                # Icon name
 
131
                if tab[3] is not None:
 
132
                    new_app['has_icon'] = True
 
133
                    icon_url = media_url(req, plugin, tab[3])
 
134
                    new_app['icon_url'] = icon_url
 
135
                    if new_app['this_app']:
 
136
                        ctx['favicon'] = icon_url
 
137
                else:
 
138
                    new_app['has_icon'] = False
 
139
                new_app['path'] = ivle.util.make_path(tab[4])
 
140
                new_app['desc'] = tab[2]
 
141
                new_app['name'] = tab[1]
 
142
                new_app['weight'] = tab[5]
 
143
                ctx['apps_in_tabs'].append(new_app)
 
144
 
 
145
        ctx['apps_in_tabs'].sort(key=lambda tab: tab['weight'])
 
146
 
 
147
    def render_overlays(self, req):
 
148
        """Generate XML streams for the overlays.
 
149
        
 
150
        Returns a list of streams. Populates the scripts, styles, and 
 
151
        scripts_init.
 
152
        """
 
153
        overlays = []
 
154
        if not self.allow_overlays:
 
155
            return overlays
 
156
 
 
157
        for plugin in req.config.plugin_index[OverlayPlugin]:
 
158
            for overclass in plugin.overlays:
 
159
                if overclass in self.overlay_blacklist:
 
160
                    continue
 
161
                overlay = overclass(req)
 
162
                #TODO: Re-factor this to look nicer
 
163
                for mplugin in overlay.plugin_scripts:
 
164
                    for path in overlay.plugin_scripts[mplugin]:
 
165
                        req.scripts.append(media_url(req, mplugin, path))
 
166
 
 
167
                for mplugin in overlay.plugin_styles:
 
168
                    for path in overlay.plugin_styles[mplugin]:
 
169
                        req.styles.append(media_url(req, mplugin, path))
 
170
 
 
171
                req.scripts_init += overlay.plugin_scripts_init
 
172
 
 
173
                overlays.append(overlay.render(req))
 
174
        return overlays
 
175
 
 
176
    @classmethod
 
177
    def get_error_view(cls, e):
 
178
        view_map = {HTTPError:    XHTMLErrorView,
 
179
                    Unauthorized: XHTMLUnauthorizedView}
 
180
        for exccls in inspect.getmro(type(e)):
 
181
            if exccls in view_map:
 
182
                return view_map[exccls]
 
183
 
 
184
class XHTMLErrorView(XHTMLView):
 
185
    template = 'xhtmlerror.html'
 
186
 
 
187
    def __init__(self, req, exception):
 
188
        self.context = exception
 
189
 
 
190
    def populate(self, req, ctx):
 
191
        ctx['exception'] = self.context
 
192
 
 
193
class XHTMLUnauthorizedView(XHTMLErrorView):
 
194
    template = 'xhtmlunauthorized.html'
 
195
 
 
196
    def __init__(self, req, exception):
 
197
        super(XHTMLUnauthorizedView, self).__init__(req, exception)
 
198
 
 
199
        if req.user is None:
 
200
            # Not logged in. Redirect to login page.
 
201
            if req.uri == '/':
 
202
                query_string = ''
91
203
            else:
92
 
                new_app['has_icon'] = False
93
 
            new_app['path'] = ivle.util.make_path(urlname)
94
 
            new_app['desc'] = app.desc
95
 
            new_app['name'] = app.name
96
 
            ctx['apps_in_tabs'].append(new_app)
 
204
                query_string = '?url=' + urllib.quote(req.uri, safe="/~")
 
205
            req.throw_redirect('/+login' + query_string)
 
206
 
 
207
        req.status = 403