source: MILK/trunk/milk_server/milk_server/controllers/retrieve.py @ 4482

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

Replace 'viewItems' controller and flesh out selected Items controller - to allow user to plot results out in Google Earth and conTerra +
add wmc client section to config file to allow this to be specified as
an alternative service + tidy up some logging and unused code + update
prototype version to avoid IE problems.

Line 
1
2from milk_server.lib.base import *
3from ndgUtils import ndgObject
4from paste.request import parse_querystring
5from milk_server.models import stubB,DIF
6from milk_server.lib import mailer
7from milk_server.lib.ndgInterface import interface
8from xml.parsers.expat import ExpatError
9import logging
10from ndgUtils.models.Atom import Atom
11from ndgUtils.vocabtermdata import VocabTermData as VTD
12from ndgUtils import DocumentRetrieve
13
14class RetrieveController(BaseController):
15    ''' Provides the pylons controller for retrieving NDG documents. The simple model
16    is now that an attempt to retrieve/uri will parse the uri, read the config file,
17    and if the local server name is not the same as the uri server name. '''
18   
19    def __setup(self,uri):
20        ''' Common setup stuff for all the actions on this controller '''
21        logging.info("Setting up RetrieveController")
22        self.cf=request.environ['ndgConfig']
23        try:
24            self.uri=ndgObject(uri, config=self.cf.config)
25        except ValueError,e:
26            return e
27
28        self.inputs=dict(parse_querystring(request.environ))
29
30        # NB: we could have two types of query string argument:
31        #   format= (raw,html) and
32        #   outputSchema=(original, someSchema)
33        self.format=''
34        if 'format' in self.inputs: 
35            self.format=self.inputs['format']
36        self.outputSchema=''
37        if 'outputSchema' in self.inputs: 
38            self.outputSchema=self.inputs['outputSchema']
39
40        # Add selected granules to context
41        #c.selectedGranules = [g_uri for g_uri, g_name in session.get('selection', [])]
42                             
43        logging.info("RetrieveController set up")
44        return 0
45       
46    def index(self,uri):
47        ''' Returns the document unadorned in anyway, i.e. the raw xml'''
48        status=self.__setup(uri)
49        if status:
50            c.xml='<p>%s</p>'%status
51            response.status_code = 400
52            return render('error')
53       
54        status,x=interface.GetXML(uri,outputSchema=self.outputSchema)
55        if status:
56            #(the return object x is an xmlHandler object)
57            c.xml=x.xmls
58            response.headers['Content-Type'] = 'application/xml'
59            response.write(c.xml)
60        else:
61            e=404
62            if x.startswith('<p> Access'): e=401
63            response.status_code = e
64            return render('error')
65
66    def viewDeployments(self, uri):
67        '''
68        Get the deployments data associated with the uri
69        @param uri: valid ndg uri
70        @return rendered genshi deployments template
71        '''
72        logging.info("Getting deployments data for '%s'" %uri)
73        status=self.__setup(uri)
74        if status:
75            c.xml='<p>%s</p>'%status
76            response.status_code = 400
77            return render('error')
78
79        try:
80            # NB, we should have stored the current atom data - so look this up now
81            atom = session.get('currentAtom')
82            if atom:
83                c.atom = atom
84            else:
85                status,x=interface.GetXML(uri,outputSchema=self.outputSchema, useCache=False)
86                c.xmlh=x
87                c.atom = Atom(xmlString=str(x), ndgObject = self.uri)
88           
89            # NB, there are two routes through here - if we're viewing a data entity,
90            # the deployment links are available directly from the atom; if not we
91            # need to look them up
92            lookupIndirectReferences = False
93            if c.atom.isDeployable():
94                lookupIndirectReferences = True
95           
96            dr = DocumentRetrieve(self.cf.get('NDG_EXIST','local'),
97                      pwfile=self.cf.get('NDG_EXIST','passwordFile'))
98            c.atom.lookupDeploymentsInfo(dr, lookupIndirectReferences = \
99                                         lookupIndirectReferences)
100            logging.info("- deployments data retrieved - now rendering")
101            return render('genshi', 'atom_editor/deployments_data')
102       
103        except ExpatError, e:
104            c.xml='XML content is not well formed'
105            c.doc=str(x)
106            response.status_code = 400
107            logging.error("Error retrieving [%s] - XML content: %s" % (uri, e))
108            return render('error')
109
110        except Exception, e:
111            #we may be showing an xml document ... but it could go wrong if
112            #we have crap content ...
113            c.xml='Unexpected error [%s] viewing [%s]'%(str(e), uri)
114            c.doc=''
115            response.status_code = 400
116            logging.error(c.xml)
117            return render('error')
118
119       
120       
121    def view(self,uri):
122        ''' Returns either an html marked up version of the xml, or a properly laid
123        out version of the document '''
124        c.doc=None
125        status=self.__setup(uri)
126        if status:
127            c.xml='<p>%s</p>'%status
128            response.status_code = 400
129            return render('error')
130
131        logging.info("Retrieving document to view")
132        status,x=interface.GetXML(uri,outputSchema=self.outputSchema)
133        c.title='Viewing [%s]'%self.uri
134       
135        # NB, legacy code uses kid templates - newer stuff should use genshi
136        templateType = "kid"
137        if status:
138            logging.debug("Document retrieved ok - now processing results")
139            #(the return object x is an xmlHandler object)
140            viewFormat=self.uri.schema
141            if self.outputSchema!='': 
142                viewFormat=self.outputSchema
143
144            logging.debug("Doc format: %s, View format: %s" \
145                           %(self.format, viewFormat))
146
147            name=str(self.uri)
148            if self.format=='xml':
149                c.xml=x.tohtml()
150                renderTemplate = 'content'
151                c.tab='Details'
152
153            elif self.format=='raw':
154                c.xml=x.xmls
155                response.headers['Content-Type'] = 'application/xml'
156                return response.write(c.xml)
157               
158            elif viewFormat == ndgObject.ATOM_DOC_TYPE or \
159                viewFormat ==  ndgObject.ATOM_BACKUP_DOC_TYPE:
160                renderTemplate = 'atom_editor/atom_editor'
161                c.xmlh=x
162                c.atom = Atom(xmlString=str(x), ndgObject = self.uri)
163                c.title = 'Viewing [%s]'%self.uri
164                c.deploymentsURL = h.url_for(controller='retrieve', \
165                                             action='viewDeployments', \
166                                             uri = self.uri)
167                templateType = "genshi"
168                # store the atom for easy re-use by asynch calls
169                # - primarily for the viewDeployments() method here
170                session['currentAtom'] = c.atom
171                session.save()
172
173            elif viewFormat == ndgObject.MOLES_DOC_TYPE:
174                renderTemplate = 'stubB'
175                c.doc=stubB.stubB(x.tree,self.cf.config)
176                name=c.doc.abbreviation
177               
178            elif viewFormat == ndgObject.NDGA0_DOC_TYPE:
179                renderTemplate = 'content'
180                name=self.uri.localID
181                #for now we'll handle as pretty print xml
182                c.xml=x.tohtml()
183                c.tab='Details'
184               
185            elif viewFormat == ndgObject.DIF_DOC_TYPE:
186                renderTemplate = 'dif'
187                c.doc=DIF.DIF(x.tree,et=1,ndgObj=self.uri)
188                name=c.doc.name
189               
190            elif viewFormat == ndgObject.NUMSIM_DOC_TYPE:
191                renderTemplate = 'numsim'
192                c.xmlh=x
193                name=x.getText('NS_Name')
194                c.name=name
195               
196            else:
197                c.xml=x.tohtml()
198                renderTemplate = 'content'
199           
200            needed=0
201            if 'lastViewed' not in session: 
202                needed=1
203               
204            session['lastViewed']=h.current_url()
205            if needed: 
206                c.pageTabs.append(('Details',session['lastViewed']))
207           
208            session.save()
209            code=200
210        else:
211            renderTemplate = 'error'
212            if x.startswith('<p> Access Denied'):
213                code=401
214            else: code=400
215            c.xml='%s'%x
216            logging.error(x)
217           
218        response.status_code = code
219        try:
220            return render(templateType, renderTemplate)
221       
222        except ExpatError, e:
223            c.xml='XML content is not well formed'
224            c.doc=str(x)
225            response.status_code = 400
226            logging.error("Error retrieving [%s] - XML content: %s" % (uri, e))
227            return render('error')
228
229        except Exception, e:
230            #we may be showing an xml document ... but it could go wrong if
231            #we have crap content ...
232            c.xml='Unexpected error [%s] viewing [%s]'%(str(e), uri)
233            c.doc=''
234            response.status_code = 400
235            logging.error(c.xml)
236            return render('error')
237   
238    def askCorrect(self,uri):
239        ''' Provide a form (ajaxaciously) so that a user can correct a metadata record'''
240        status=self.__setup(uri)
241        c.uri=self.uri
242        if status: return response.write(status)
243        return render('correct',fragment=True)
244
245   
246    def correct(self,uri):
247        ''' Receive a correction form to update a record and post it to the holder '''
248        status=self.__setup(uri)
249        if 'ndgSec' not in session:
250            return response.write('Not Logged In')
251        body='Metadata Change Request for %s'%uri
252        payload='<Change><uri>%s</uri><from>%s</from><Contents>%s</Contents></Change>'%(
253            self.inputs['Identifier'],self.inputs['Submitter'],self.inputs['Comment'])
254        name='ChangeRequestFor_%s.xml'%uri
255        status,message=mailer.mailHandler([self.cf.get('DEFAULT','metadataMaintainer'),],
256                       body,body,xmlAttachments=[(payload,name),],
257                       server=self.cf.get('DEFAULT','mailserver'))
258        if status:
259            c.xml='<p>Success: Mail sent to metadata maintainer</p>'
260        else:
261            c.xml=message
262        return render('content')
Note: See TracBrowser for help on using the repository browser.