23
24
import genshi.template
25
26
from ivle.webapp.media import media_url
27
from ivle.webapp.core import Plugin as CorePlugin
26
28
from ivle.webapp.base.views import BaseView
27
from ivle.webapp.base.plugins import OverlayPlugin
29
from ivle.webapp.base.plugins import ViewPlugin, OverlayPlugin
28
30
from ivle.webapp.errors import HTTPError, Unauthorized
32
32
class XHTMLView(BaseView):
39
39
template = 'template.html'
40
40
plugin_scripts = {}
42
43
overlay_blacklist = []
44
45
def __init__(self, req, **kwargs):
46
47
setattr(self, key, kwargs[key])
49
def filter(self, stream, ctx):
48
52
def render(self, req):
49
53
req.content_type = 'text/html' # TODO: Detect application/xhtml+xml
57
61
app_template = os.path.join(os.path.dirname(
58
62
inspect.getmodule(self).__file__), self.template)
59
req.write_html_head_foot = False
60
63
loader = genshi.template.TemplateLoader(".", auto_reload=True)
61
64
tmpl = loader.load(app_template)
62
app = tmpl.generate(viewctx)
65
app = self.filter(tmpl.generate(viewctx), viewctx)
64
67
for plugin in self.plugin_scripts:
65
68
for path in self.plugin_scripts[plugin]:
73
76
ctx = genshi.template.Context()
74
77
# XXX: Leave this here!! (Before req.styles is read)
75
ctx['overlays'] = self.render_overlays(req)
76
ctx['app_styles'] = req.styles
77
ctx['scripts'] = req.scripts
78
ctx['overlays'] = self.render_overlays(req) if req.user else []
80
ctx['styles'] = [media_url(req, CorePlugin, 'ivle.css')]
81
ctx['styles'] += req.styles
83
ctx['scripts'] = [media_url(req, CorePlugin, path) for path in
84
('util.js', 'json2.js', 'md5.js')]
85
ctx['scripts'].append(media_url(req, '+external/jquery', 'jquery.js'))
86
ctx['scripts'] += req.scripts
78
88
ctx['scripts_init'] = req.scripts_init
79
89
ctx['app_template'] = app
90
ctx['title_img'] = media_url(req, CorePlugin,
91
"images/chrome/title.png")
80
92
self.populate_headings(req, ctx)
81
93
tmpl = loader.load(os.path.join(os.path.dirname(__file__),
82
94
'ivle-headings.html'))
88
100
def populate_headings(self, req, ctx):
89
101
ctx['favicon'] = None
90
ctx['root_dir'] = ivle.conf.root_dir
91
ctx['public_host'] = ivle.conf.public_host
102
ctx['root_dir'] = req.config['urls']['root']
103
ctx['public_host'] = req.config['urls']['public_host']
104
ctx['svn_base'] = req.config['urls']['svn_addr']
92
105
ctx['write_javascript_settings'] = req.write_javascript_settings
94
107
ctx['login'] = req.user.login
98
111
ctx['login'] = None
99
112
ctx['logged_in'] = False
100
113
ctx['publicmode'] = req.publicmode
101
ctx['apps_in_tabs'] = []
102
114
if hasattr(self, 'help'):
103
115
ctx['help_path'] = self.help
104
for urlname in ivle.conf.apps.apps_in_tabs:
106
app = ivle.conf.apps.app_url[urlname]
107
new_app['this_app'] = hasattr(self, 'appname') \
108
and urlname == self.appname
110
new_app['has_icon'] = True
111
icon_dir = ivle.conf.apps.app_icon_dir
112
icon_url = ivle.util.make_path(os.path.join(icon_dir, app.icon))
113
new_app['icon_url'] = icon_url
114
if new_app['this_app']:
115
ctx['favicon'] = icon_url
117
new_app['has_icon'] = False
118
new_app['path'] = ivle.util.make_path(urlname)
119
new_app['desc'] = app.desc
120
new_app['name'] = app.name
121
ctx['apps_in_tabs'].append(new_app)
117
ctx['apps_in_tabs'] = []
118
for plugin in req.config.plugin_index[ViewPlugin]:
119
if not hasattr(plugin, 'tabs'):
122
for tab in plugin.tabs:
123
# tab is a tuple: name, title, desc, icon, path
125
new_app['this_app'] = hasattr(self, 'tab') \
126
and tab[0] == self.tab
129
if tab[3] is not None:
130
new_app['has_icon'] = True
131
icon_url = media_url(req, plugin, tab[3])
132
new_app['icon_url'] = icon_url
133
if new_app['this_app']:
134
ctx['favicon'] = icon_url
136
new_app['has_icon'] = False
137
new_app['path'] = req.make_path(tab[4])
138
new_app['desc'] = tab[2]
139
new_app['name'] = tab[1]
140
new_app['weight'] = tab[5]
141
ctx['apps_in_tabs'].append(new_app)
143
ctx['apps_in_tabs'].sort(key=lambda tab: tab['weight'])
123
145
def render_overlays(self, req):
124
146
"""Generate XML streams for the overlays.
130
for plugin in req.plugin_index[OverlayPlugin]:
152
if not self.allow_overlays:
155
for plugin in req.config.plugin_index[OverlayPlugin]:
131
156
for overclass in plugin.overlays:
132
157
if overclass in self.overlay_blacklist:
169
194
def __init__(self, req, exception):
170
195
super(XHTMLUnauthorizedView, self).__init__(req, exception)
171
197
if req.user is None:
172
198
# Not logged in. Redirect to login page.
173
req.throw_redirect('/') # XXX: Need proper URL.
202
query_string = '?url=' + urllib.quote(req.uri, safe="/~")
203
req.throw_redirect('/+login' + query_string)