source: TI05-delivery/ows_framework/trunk/ows_server/ows_server/controllers/retrieve.py @ 4665

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI05-delivery/ows_framework/trunk/ows_server/ows_server/controllers/retrieve.py@4665
Revision 4665, 10.8 KB checked in by cbyrom, 13 years ago (diff)

Update code to reflect refactoring of ndgUtils.

Line 
1
2from ows_server.lib.base import *
3from ows_server.models import Utilities
4from ndgUtils import ndgObject
5from paste.request import parse_querystring
6from ows_server.models import stubB,DIF
7from ows_server.lib import mailer
8from ows_server.lib.ndgInterface import interface
9from xml.parsers.expat import ExpatError
10import logging
11from ndgUtils.models.Atom import Atom
12from ndgUtils.models.vocabtermdata import VocabTermData as VTD
13from ndgUtils import DocumentRetrieve
14
15class RetrieveController(BaseController):
16    ''' Provides the pylons controller for retrieving NDG documents. The simple model
17    is now that an attempt to retrieve/uri will parse the uri, read the config file,
18    and if the local server name is not the same as the uri server name. '''
19   
20    def __setup(self,uri):
21        ''' Common setup stuff for all the actions on this controller '''
22        logging.info("Setting up RetrieveController")
23        self.cf=request.environ['ndgConfig']
24        try:
25            self.uri=ndgObject(uri, config=self.cf.config)
26        except ValueError,e:
27            return e
28
29        self.inputs=dict(parse_querystring(request.environ))
30
31        # NB: we could have two types of query string argument:
32        #   format= (raw,html) and
33        #   outputSchema=(original, someSchema)
34        self.format=''
35        if 'format' in self.inputs: 
36            self.format=self.inputs['format']
37        self.outputSchema=''
38        if 'outputSchema' in self.inputs: 
39            self.outputSchema=self.inputs['outputSchema']
40
41        # Add selected granules to context
42        #c.selectedGranules = [g_uri for g_uri, g_name in session.get('selection', [])]
43                             
44        logging.info("RetrieveController set up")
45        return 0
46       
47    def index(self,uri):
48        ''' Returns the document unadorned in anyway, i.e. the raw xml'''
49        status=self.__setup(uri)
50        if status:
51            c.xml='<p>%s</p>'%status
52            response.status_code = 400
53            return render('error')
54       
55        status,x=interface.GetXML(uri,outputSchema=self.outputSchema)
56        if status:
57            #(the return object x is an xmlHandler object)
58            c.xml=x.xmls
59            response.headers['Content-Type'] = 'application/xml'
60            response.write(c.xml)
61        else:
62            e=404
63            if x.startswith('<p> Access'): e=401
64            response.status_code = e
65            return render('error')
66
67    def viewDeployments(self, uri):
68        '''
69        Get the deployments data associated with the uri
70        @param uri: valid ndg uri
71        @return rendered genshi deployments template
72        '''
73        logging.info("Getting deployments data for '%s'" %uri)
74        status=self.__setup(uri)
75        if status:
76            c.xml='<p>%s</p>'%status
77            response.status_code = 400
78            return render('error')
79
80        try:
81            # NB, we should have stored the current atom data - so look this up now
82            atom = session.get('currentAtom')
83            if atom:
84                c.atom = atom
85            else:
86                status,x=interface.GetXML(uri,outputSchema=self.outputSchema, useCache=False)
87                c.xmlh=x
88                c.atom = Atom(xmlString=str(x), ndgObject = self.uri)
89           
90            # NB, there are two routes through here - if we're viewing a data entity,
91            # the deployment links are available directly from the atom; if not we
92            # need to look them up
93            lookupIndirectReferences = False
94            if c.atom.isDeployable():
95                lookupIndirectReferences = True
96           
97            dr = DocumentRetrieve(self.cf.get('NDG_EXIST','local'),
98                      pwfile=self.cf.get('NDG_EXIST','passwordFile'))
99            c.atom.lookupDeploymentsInfo(dr, lookupIndirectReferences = \
100                                         lookupIndirectReferences)
101            return render('genshi', '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'
161                c.xmlh=x
162                c.atom = Atom(xmlString=str(x), ndgObject = self.uri)
163                c.r = info = self.__mytb('')
164                c.title = 'Viewing [%s]'%self.uri
165                c.deploymentsURL = h.url_for(controller='retrieve', \
166                                             action='viewDeployments', \
167                                             uri = self.uri)
168                templateType = "genshi"
169                # store the atom for easy re-use by asynch calls
170                # - primarily for the viewDeployments() method here
171                session['currentAtom'] = c.atom
172                session.save()
173
174            elif viewFormat == ndgObject.MOLES_DOC_TYPE:
175                renderTemplate = 'stubB'
176                c.doc=stubB.stubB(x.tree,self.cf.config)
177                c.tbinfo=self.__mytb(c.doc.name)
178                name=c.doc.abbreviation
179               
180            elif viewFormat == ndgObject.NDGA0_DOC_TYPE:
181                #renderTemplate = 'csml'
182                renderTemplate = 'content'
183                name=self.uri.localID
184                #for now we'll handle as pretty print xml
185                c.xml=x.tohtml()
186                c.tab='Details'
187               
188            elif viewFormat == ndgObject.DIF_DOC_TYPE:
189                renderTemplate = 'dif'
190                c.doc=DIF.DIF(x.tree,et=1,ndgObj=self.uri)
191                name=c.doc.name
192               
193            elif viewFormat == ndgObject.NUMSIM_DOC_TYPE:
194                renderTemplate = 'numsim'
195                c.xmlh=x
196                c.r = info = self.__mytb('')
197                name=x.getText('NS_Name')
198                c.name=name
199               
200            else:
201                c.xml=x.tohtml()
202                renderTemplate = 'content'
203           
204            needed=0
205            if 'lastViewed' not in session: 
206                needed=1
207               
208            session['lastViewed']=h.current_url()
209            if needed: 
210                c.pageTabs.append(('Details',session['lastViewed']))
211           
212            session.save()
213            code=200
214        else:
215            renderTemplate = 'error'
216            if x.startswith('<p> Access Denied'):
217                code=401
218            else: code=400
219            c.xml='%s'%x
220            logging.error(x)
221           
222        response.status_code = code
223        try:
224            return render(templateType, renderTemplate)
225       
226        except ExpatError, e:
227            c.xml='XML content is not well formed'
228            c.doc=str(x)
229            response.status_code = 400
230            logging.error("Error retrieving [%s] - XML content: %s" % (uri, e))
231            return render('error')
232
233        except Exception, e:
234            #we may be showing an xml document ... but it could go wrong if
235            #we have crap content ...
236            c.xml='Unexpected error [%s] viewing [%s]'%(str(e), uri)
237            c.doc=''
238            response.status_code = 400
239            logging.error(c.xml)
240            return render('error')
241   
242    def askCorrect(self,uri):
243        ''' Provide a form (ajaxaciously) so that a user can correct a metadata record'''
244        status=self.__setup(uri)
245        c.uri=self.uri
246        if status: return response.write(status)
247        return render('correct',fragment=True)
248
249   
250    def correct(self,uri):
251        ''' Receive a correction form to update a record and post it to the holder '''
252        status=self.__setup(uri)
253        if 'ndgSec' not in session:
254            return response.write('Not Logged In')
255        body='Metadata Change Request for %s'%uri
256        payload='<Change><uri>%s</uri><from>%s</from><Contents>%s</Contents></Change>'%(
257            self.inputs['Identifier'],self.inputs['Submitter'],self.inputs['Comment'])
258        name='ChangeRequestFor_%s.xml'%uri
259        status,message=mailer.mailHandler([self.cf.get('DEFAULT','metadataMaintainer'),],
260                       body,body,xmlAttachments=[(payload,name),],
261                       server=self.cf.get('DEFAULT','mailserver'))
262        if status:
263            c.xml='<p>Success: Mail sent to metadata maintainer</p>'
264        else:
265            c.xml=message
266        return render('content')
267       
268
269    def __mytb(self,name):
270        ''' Get the trackback info for this page
271        (can't do it in Kid because it doesn't do substitutions in comments) '''
272        s='''<!--
273        <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
274             xmlns:dc="http://purl.org/dc/elements/1.1/"
275             xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
276        <rdf:Description
277            rdf:about="%s"
278            dc:identifier="%s"
279            dc:title="%s"
280            trackback:ping="%s" />
281        </rdf:RDF>
282        -->'''%(self.uri,g.server+h.url_for(),name,g.server+h.url_for(controller="trackback"))
283        return s
Note: See TracBrowser for help on using the repository browser.