source: MILK/trunk/milk_server/milk_server/controllers/browse/retrieve.py @ 5194

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

Remove url escaping in templates, since this is now handled by data
model, and fix typo.

Line 
1'''
2 Class representing pylons controller for the retrieval of metadata records - and
3 records associated with these
4 
5 @author: B Lawrence?, C Byrom, Tessella Sep 2008
6'''
7import logging
8from paste.request import parse_querystring
9from xml.parsers.expat import ExpatError
10from milk_server.lib.base import *
11from milk_server.models.ndgdoc import NDGDoc
12from milk_server.controllers.trackback.trackback import TrackbackController
13from ndg.common.src.models.ndgObject import ndgObject
14from ndg.common.src.models.vocabtermdata import VocabTermData as VTD
15from ndg.common.src.clients.xmldb.eXist.searchclient import SearchClient
16
17class RetrieveController(BaseController):
18    '''
19    Provides the pylons controller for retrieving NDG documents. The simple model
20    is now that an attempt to retrieve/uri will parse the uri, read the config file,
21    and if the local server name is not the same as the uri server name, attempt
22    to retrieve the doc remotely.
23    '''
24    def __before__(self):
25        '''
26        Before anything is done, ensure the browse mode is enabled
27        - unless we're retrieving associated data then we can do this regardless
28        of the mode of operation
29        '''
30        if not g.browseEnabled and not g.atomEditorEnabled:# request.path_info.startswith('/viewAssociatedData'):
31            logging.info("Browse mode not enabled - redirect to default")
32            return h.redirect_to(h.url_for('default'))
33
34
35    def home(self):
36        '''
37        Display the browse home page
38        '''
39        logging.debug("Displaying browse home page")
40        c.title = "Browse"
41       
42        c.doc = "Use the search box above to find data centre metadata records" 
43        return render('genshi', 'browse/home')
44
45   
46    def __setup(self, uri):
47        ''' Common setup stuff for all the actions on this controller '''
48        logging.info("Setting up RetrieveController")
49        self.cf = request.environ['ndgConfig']
50        try:
51            self.uri=ndgObject(uri, config=self.cf)
52        except ValueError,e:
53            return e
54
55        self.inputs=dict(parse_querystring(request.environ))
56
57        # NB: we could have two types of query string argument:
58        #   format= (raw,html) and
59        #   outputSchema=(original, someSchema)
60        self.format=''
61        if 'format' in self.inputs: 
62            self.format = self.inputs['format']
63        self.outputSchema = ''
64        if 'outputSchema' in self.inputs: 
65            self.outputSchema = self.inputs['outputSchema']
66
67        self.ndgDoc = NDGDoc(ndgURI = uri, config = self.cf)
68                             
69        logging.info("RetrieveController set up")
70        return 0
71
72       
73    def index(self,uri):
74        '''
75        Returns the document unadorned in anyway, i.e. the raw xml
76        '''
77        status=self.__setup(uri)
78        if status:
79            c.xml='<p>%s</p>'%status
80            response.status_code = 400
81            return render('error')
82       
83        self.ndgDoc.setupDocumentModel(outputSchema = self.outputSchema,
84                                       format = 'xml')
85
86        if self.ndgDoc.status:
87            response.headers['Content-Type'] = 'application/xml'
88            response.write(self.ndgDoc.xmlString)
89        else:
90            # the error templates should be set up already if there's an error
91            return self.__renderModel(self.ndgDoc)
92
93
94    def viewAssociatedData(self, type, uri):
95        '''
96        Get the specified data associated with the uri
97        @param type: type of associated data to lookup - currently VTD.DEPLOYMENT_TERM
98        or VTD.DE_TERM
99        @param uri: valid ndg uri
100        @return rendered genshi deployments template
101        '''
102        logging.info("Getting %s data for '%s'" %(type, uri))
103        status=self.__setup(uri)
104        if status:
105            c.xml='<p>%s</p>'%status
106            response.status_code = 400
107            return render('error')
108
109        try:
110            # NB, we should have stored the current atom data - so look this up now
111            atom = session.get('currentAtom')
112            if atom:
113                c.atom = atom
114                self.ndgDoc.templateType = "genshi"
115                self.ndgDoc.htmlCode = 200
116            else:
117               
118                self.ndgDoc.setupDocumentModel(outputSchema = self.outputSchema,
119                                               format = self.format)
120                c.atom = self.ndgDoc.docModel
121           
122            # NB, there are two routes through here - if we're viewing a data entity,
123            # the deployment links are available directly from the atom; if not we
124            # need to look them up
125            lookupIndirectReferences = True
126            if c.atom.isDE():
127                lookupIndirectReferences = False
128           
129            searchClient = SearchClient(dbHostName = self.cf.get('NDG_EXIST','local'),
130                                        configFileName = self.cf.get('NDG_EXIST','passwordFile'))
131           
132            c.atom.lookupAssociatedData(type, searchClient, 
133                                        lookupIndirectReferences = lookupIndirectReferences)
134
135            self.ndgDoc.renderTemplate = 'atom_editor/deployments_data'
136            if type == VTD.DE_TERM:
137                self.ndgDoc.renderTemplate = 'atom_editor/data_entities_data'
138
139            # store the atom to retain the looked up info
140            session['currentAtom'] = c.atom
141            session.save()
142               
143            logging.info("- %s data retrieved - now rendering" %type)
144
145            return self.__renderModel(self.ndgDoc)
146        except Exception, e:
147            c.xml = 'Unexpected error [%s] viewing [%s]'%(str(e), self.ndgDoc.ndgUri)
148            c.doc = ''
149            response.status_code = 400
150            logging.error(c.xml)
151            return render('error')
152           
153
154    def view(self, uri):
155        '''
156        Returns either an html marked up version of the xml, or a properly laid
157        out version of the document
158        '''
159        c.doc=None
160        # NB, this sets up self.uri as an ndgObject
161        status=self.__setup(uri)
162        if status:
163            c.xml='<p>%s</p>'%status
164            response.status_code = 400
165            return render('error')
166       
167        c.tab = 'Details'
168        c.title='Viewing [%s]'%self.uri
169       
170        self.ndgDoc.setupDocumentModel(outputSchema = self.outputSchema,
171                                       format = self.format)
172
173        c.xml = self.ndgDoc.xmlString
174
175        if self.format=='raw':
176            response.headers['Content-Type'] = 'application/xml'
177            return response.write(c.xml)
178
179        c.name = self.ndgDoc.name
180        c.xmlh = self.ndgDoc.xmlh    # xml in object form - NB, only used by NumSim docs
181        c.doc = self.ndgDoc.docModel
182
183        if self.ndgDoc.isAtom:
184            c.atom = self.ndgDoc.docModel
185           
186            # store the atom for easy re-use by asynch calls
187            # - primarily for the viewAssociatedData() method here
188            session['currentAtom'] = c.atom
189            session.save()
190               
191        # set up trackback rdf tag
192        c.tbinfo = TrackbackController().getTrackBackInfo(uri, self.ndgDoc.name)
193
194        needed=0
195        if 'lastViewed' not in session: 
196            needed=1
197           
198        session['lastViewed']=h.current_url()
199        session.save()
200
201        # only add the details tab data to the panel tab, if it is not already there
202        if needed: 
203            c.pageTabs.append(('Details',session['lastViewed']))
204
205        return self.__renderModel(self.ndgDoc)
206
207
208    def __renderModel(self, model):
209        '''
210        Render the requested document model - or handle errors appropriately
211        @param model: doc model - of type NDGDoc
212        '''
213        response.status_code = model.htmlCode
214        try:
215            logging.debug("Rendering output from data model")
216            out = render(model.templateType, model.renderTemplate)
217           
218            # if in atom editor mode, replace any browse links with to links to editor
219            if g.atomEditorEnabled:
220                out = out.replace(VTD.BROWSE_SERVER_URL, g.server)
221           
222            logging.debug("- returning rendered data model")
223            return out
224       
225        except ExpatError, e:
226            c.xml = 'XML content is not well formed'
227            c.doc = model.xmlString
228            response.status_code = 400
229            logging.error("Error retrieving [%s]: %s" % (model.ndgUri, e))
230            return render('error')
231
232        except Exception, e:
233            c.xml = 'Unexpected error [%s] viewing [%s]'%(str(e), model.ndgUri)
234            c.doc = ''
235            response.status_code = 400
236            logging.error(c.xml)
237            return render('error')
238       
239
Note: See TracBrowser for help on using the repository browser.