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

« back to all changes in this revision

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

Move ivle.webapp.groups' media to the new framework.

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