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

« back to all changes in this revision

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

ivle.dispatch: Throw the routes mapper into req.mapper, and make it explicit.
    This removes the need to manually remove the default 'action' and
    'controller' items.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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: Matt Giuca, Will Grant
 
19
 
 
20
import inspect
 
21
import os.path
 
22
 
 
23
import cjson
 
24
import genshi.template
 
25
 
 
26
import ivle.conf
 
27
import ivle.util
 
28
 
 
29
from ivle.webapp.errors import BadRequest
 
30
 
 
31
class BaseView(object):
 
32
    """
 
33
    Abstract base class for all view objects.
 
34
    """
 
35
    def __init__(self, req, **kwargs):
 
36
        pass
 
37
    def render(self, req):
 
38
        pass
 
39
 
 
40
class RESTView(BaseView):
 
41
    """
 
42
    A view which provides a RESTful interface. The content type is
 
43
    unspecified (see JSONRESTView for a specific content type).
 
44
    """
 
45
    content_type = "application/octet-stream"
 
46
 
 
47
    def __init__(self, req, *args, **kwargs):
 
48
        pass
 
49
 
 
50
    def render(self, req):
 
51
        if req.method == 'GET':
 
52
            outstr = self.GET(req)
 
53
        # XXX PATCH hack
 
54
        if req.method == 'PUT':
 
55
            outstr = self.PATCH(req, req.read())
 
56
        req.content_type = self.content_type
 
57
        req.write(outstr)
 
58
 
 
59
class JSONRESTView(RESTView):
 
60
    """
 
61
    A special case of RESTView which deals entirely in JSON.
 
62
    """
 
63
    content_type = "application/json"
 
64
 
 
65
    def render(self, req):
 
66
        if req.method == 'GET':
 
67
            outjson = self.GET(req)
 
68
        elif req.method == 'PATCH' or (req.method == 'PUT' and
 
69
              'X-IVLE-Patch-Semantics' in req.headers_in and
 
70
              req.headers_in['X-IVLE-Patch-Semantics'].lower() == 'yes'):
 
71
            outjson = self.PATCH(req, cjson.decode(req.read()))
 
72
        elif req.method == 'PUT':
 
73
            outjson = self.PUT(req, cjson.decode(req.read()))
 
74
        else:
 
75
            raise BadRequest
 
76
        req.content_type = self.content_type
 
77
        if outjson is not None:
 
78
            req.write(cjson.encode(outjson))
 
79
            req.write("\n")
 
80
            
 
81
class XHTMLView(BaseView):
 
82
    """
 
83
    A view which provides a base class for views which need to return XHTML
 
84
    It is expected that apps which use this view will be written using Genshi
 
85
    templates.
 
86
    """
 
87
    def __init__(self, req, **kwargs):
 
88
        for key in kwargs:
 
89
          setattr(self, key, kwargs[key])
 
90
        
 
91
    def render(self, req):
 
92
        ctx = genshi.template.Context()
 
93
        self.populate(req, ctx)
 
94
        self.populate_headings(req, ctx)
 
95
        
 
96
        ctx['app_styles'] = req.styles
 
97
        ctx['scripts'] = req.scripts
 
98
        ctx['scripts_init'] = req.scripts_init
 
99
        app_template = os.path.join(os.path.dirname(
 
100
                        inspect.getmodule(self).__file__), self.app_template) 
 
101
        req.write_html_head_foot = False
 
102
        loader = genshi.template.TemplateLoader(".", auto_reload=True)
 
103
        tmpl = loader.load(app_template)
 
104
        app = tmpl.generate(ctx)
 
105
        ctx['app_template'] = app
 
106
        tmpl = loader.load(os.path.join(os.path.dirname(__file__), 
 
107
                                                        'ivle-headings.html'))
 
108
        req.write(tmpl.generate(ctx).render('xhtml', doctype='xhtml'))
 
109
 
 
110
    def populate_headings(self, req, ctx):
 
111
        ctx['favicon'] = None
 
112
        ctx['root_dir'] = ivle.conf.root_dir
 
113
        ctx['public_host'] = ivle.conf.public_host
 
114
        if req.user:
 
115
            ctx['login'] = req.user.login
 
116
            ctx['logged_in'] = True
 
117
            ctx['nick'] = req.user.nick
 
118
        else:
 
119
            ctx['login'] = None
 
120
        ctx['publicmode'] = req.publicmode
 
121
        ctx['apps_in_tabs'] = []
 
122
        for urlname in ivle.conf.apps.apps_in_tabs:
 
123
            new_app = {}
 
124
            app = ivle.conf.apps.app_url[urlname]
 
125
            new_app['this_app'] = urlname == self.appname
 
126
            if app.icon:
 
127
                new_app['has_icon'] = True
 
128
                icon_dir = ivle.conf.apps.app_icon_dir
 
129
                icon_url = ivle.util.make_path(os.path.join(icon_dir, app.icon))
 
130
                new_app['icon_url'] = icon_url
 
131
                if new_app['this_app']:
 
132
                    ctx['favicon'] = icon_url
 
133
            else:
 
134
                new_app['has_icon'] = False
 
135
            new_app['path'] = ivle.util.make_path(urlname)
 
136
            new_app['desc'] = app.desc
 
137
            new_app['name'] = app.name
 
138
            ctx['apps_in_tabs'].append(new_app)