source: MILK/trunk/milk_server/milk_server/controllers/home.py @ 5314

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/MILK/trunk/milk_server/milk_server/controllers/home.py@5314
Revision 5314, 4.9 KB checked in by cbyrom, 11 years ago (diff)

Improve look and feel of UI with tweaks to css + fix radio button
on search panel - set this explicitly as an input since htmlfill
doesn't handle the radio button defaults well + simplify template
logic for semantic search results + fix constraint summary string.

Line 
1'''
2 Base controller for MILK controllers, providing common functionality - including
3 fall back index method, to render a home page for the service depending on what
4 mode it is running in - NB, if multiple modes are enabled, the order of preference,
5 from highest to lowest, is editor, discovery, browser
6 
7 @author: C Byrom, Tessella Apr 2009
8'''
9import logging, traceback, xmlrpclib
10from formencode import htmlfill
11from milk_server.lib.base import *
12from ndg.common.src.lib.utilities import escapeSpecialCharacters
13from ndg.common.src.models.vocabtermdata import VocabTermData as VTD
14
15class HomeController(BaseController):
16    '''
17    Sets up appropriate home page for fall through urls
18    '''
19    def index(self):
20        '''
21        Redirect to the appropriate home page - or display error
22        '''
23        if g.atomEditorEnabled:
24            h.redirect_to(h.url_for('atomHome'))
25        elif g.discoveryEnabled:
26            h.redirect_to(h.url_for('discovery'))
27        elif g.browseEnabled:
28            h.redirect_to(h.url_for('browseHome'))
29        else:
30            c.title = "No service enabled"
31            c.xml = "The server should be configured to provide one or more of the followings client services: editor, discovery or browse."
32            return render("genshi", 'error')
33           
34
35    def savePageAndRender(self, template, **inputs):
36        '''
37        Save the current path info - to provide a memory function when changing
38        tabs + render the given template with the specified inputs filled in
39        automatically
40        @param template: name of template to render
41        @param inputs: dict of inputs with keynames matching input names in template
42        form 
43        '''
44        logging.debug("Saving current page url - to keep track of atom editor state")
45        if hasattr(self, 'pathInfo'):
46            logging.debug(" - page: %s" %self.pathInfo)
47            session['currentEditor'] = self.pathInfo
48            session.save()
49           
50        logging.debug("Now rendering current template (%s)" %template)
51        try:
52            html = render("genshi", template)
53            # replace any browse links with to links to editor
54            html = html.replace(VTD.BROWSE_SERVER_URL, g.server)
55
56            # NB, need html in unicode for for htmlfill.render
57            html = unicode(html, 'utf-8', 'xmlcharrefreplace')
58            for key, val in inputs.items():
59                inputs[key] = str(val)
60   
61            return htmlfill.render(html, inputs, errors = c.errors)
62
63        except Exception, e:
64            c.xml = 'Unexpected error [%s] whilst rendering page' %str(e)
65            if str(e).find('malformed start tag') >-1:
66                c.xml += " - NB, this is probably due to illegal HTML being entered"
67            c.doc = ''
68            response.status_code = 400
69            logging.error(c.xml)
70            return render('error')
71
72
73    def _unpackErrors(self, e):
74        '''
75        Add exception errors to the common error structures - for use
76        in templates
77        @param e: Exception to add
78        @return errors: dict of errors
79        '''
80        if not c.errors:
81            c.errors = {}
82
83        errorMessage = e.message
84        if g.debugModeOn == 'True':
85            errorMessage = traceback.format_exc()
86
87        c.xml = escapeSpecialCharacters('Unexpected error loading page [%s]' \
88                                        %str(errorMessage))
89        c.doc = ''
90       
91        # unpack errors, if possible - NB, the c.errors value is used by the template
92        # function, displayErrors, which is used by most of the editor templates
93        if isinstance(e, xmlrpclib.Fault):
94            # strip out the exception type - NB, this is usually native library code
95            # and is of no real interest - and will just confuse viewers
96            c.errors['Unexpected error'] = e.faultString.split(':')[-1] 
97
98        if hasattr(e, 'unpack_errors'):
99            c.errors.update(e.unpack_errors())
100           
101        else:
102            c.errors['Unexpected error'] = [c.xml]
103
104        # tidy up errors - escaping any xml tags, if necessary
105        for key, errors in c.errors.items():
106            newErrors = []
107            for error in errors:
108                for err in error.split('<br/>'):
109                    newErrors.append(escapeSpecialCharacters(err))
110            c.errors[key] = newErrors
111       
112        return c.errors
113
114
115    def _handleError(self, e, template='error'):
116        '''
117        Handle exceptions thrown; if debug mode on, display full stack trace
118        in output, otherwise just show basic error message in error template
119        @param e: Exception to process
120        @keyword template: template to render - 'error' is the default - NB, if
121        an alternative is specified it should have a div with class set to 'error'
122        containing the variable, c.xml to display properly
123        '''
124        self._unpackErrors(e)
125        logging.error(c.xml)
126        response.status_code = 400
127        return render("genshi", template)
128
Note: See TracBrowser for help on using the repository browser.