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

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

Add genshi support to ows server code + add genshi templates for
atom rendering + add code to allow use of both kid and genshi templates
+ extend logging.

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
11
12class RetrieveController(BaseController):
13    ''' Provides the pylons controller for retrieving NDG documents. The simple model
14    is now that an attempt to retrieve/uri will parse the uri, read the config file,
15    and if the local server name is not the same as the uri server name. '''
16   
17    def __setup(self,uri):
18        ''' Common setup stuff for all the actions on this controller '''
19        logging.info("Setting up RetrieveController")
20        self.cf=request.environ['ndgConfig']
21        try:
22            self.uri=ndgObject(uri, config=self.cf.config)
23        except ValueError,e:
24            return e
25
26        self.inputs=dict(parse_querystring(request.environ))
27
28        # NB: we could have two types of query string argument:
29        #   format= (raw,html) and
30        #   outputSchema=(original, someSchema)
31        self.format=''
32        if 'format' in self.inputs: 
33            self.format=self.inputs['format']
34        self.outputSchema=''
35        if 'outputSchema' in self.inputs: 
36            self.outputSchema=self.inputs['outputSchema']
37
38        # Add selected granules to context
39        #c.selectedGranules = [g_uri for g_uri, g_name in session.get('selection', [])]
40                             
41        logging.info("RetrieveController set up")
42        return 0
43       
44    def index(self,uri):
45        ''' Returns the document unadorned in anyway, i.e. the raw xml'''
46        status=self.__setup(uri)
47        if status:
48            c.xml='<p>%s</p>'%status
49            response.status_code = 400
50            return render('error')
51       
52        status,x=interface.GetXML(uri,outputSchema=self.outputSchema)
53        if status:
54            #(the return object x is an xmlHandler object)
55            c.xml=x.xmls
56            response.headers['Content-Type'] = 'application/xml'
57            response.write(c.xml)
58        else:
59            e=404
60            if x.startswith('<p> Access'): e=401
61            response.status_code = e
62            return render('error')
63       
64    def view(self,uri):
65        ''' Returns either an html marked up version of the xml, or a properly laid
66        out version of the document '''
67        c.doc=None
68        status=self.__setup(uri)
69        if status:
70            c.xml='<p>%s</p>'%status
71            response.status_code = 400
72            return render('error')
73
74        logging.info("Retrieving document to view")
75        status,x=interface.GetXML(uri,outputSchema=self.outputSchema)
76        c.title='Viewing [%s]'%self.uri
77       
78        # NB, legacy code uses kid templates - newer stuff should use genshi
79        templateType = "kid"
80        if status:
81            logging.debug("Document retrieved ok - now processing results")
82            #(the return object x is an xmlHandler object)
83            viewFormat=self.uri.schema
84            if self.outputSchema!='': 
85                viewFormat=self.outputSchema
86
87            logging.debug("Doc format: %s, View format: %s" \
88                           %(self.format, viewFormat))
89
90            name=str(self.uri)
91            if self.format=='xml':
92                c.xml=x.tohtml()
93                renderTemplate = 'content'
94                c.tab='Details'
95
96            elif self.format=='raw':
97                c.xml=x.xmls
98                response.headers['Content-Type'] = 'application/xml'
99                return response.write(c.xml)
100               
101            elif viewFormat == ndgObject.ATOM_DOC_TYPE or \
102                viewFormat ==  ndgObject.ATOM_BACKUP_DOC_TYPE:
103                renderTemplate = 'atom'
104                c.xmlh=x
105                c.r = info = self.__mytb('')
106                c.title=x.getText('title')
107                templateType = "genshi"
108
109            elif viewFormat == ndgObject.MOLES_DOC_TYPE:
110                renderTemplate = 'stubB'
111                c.doc=stubB.stubB(x.tree,self.cf)
112                c.tbinfo=self.__mytb(c.doc.name)
113                name=c.doc.abbreviation
114               
115            elif viewFormat == ndgObject.NDGA0_DOC_TYPE:
116                #renderTemplate = 'csml'
117                renderTemplate = 'content'
118                name=self.uri.localID
119                #for now we'll handle as pretty print xml
120                c.xml=x.tohtml()
121                c.tab='Details'
122               
123            elif viewFormat == ndgObject.DIF_DOC_TYPE:
124                renderTemplate = 'dif'
125                c.doc=DIF.DIF(x.tree,et=1,ndgObj=self.uri)
126                name=c.doc.name
127               
128            elif viewFormat == ndgObject.NUMSIM_DOC_TYPE:
129                renderTemplate = 'numsim'
130                c.xmlh=x
131                c.r = info = self.__mytb('')
132                name=x.getText('NS_Name')
133                c.name=name
134               
135            else:
136                c.xml=x.tohtml()
137                renderTemplate = 'content'
138           
139            needed=0
140            if 'lastViewed' not in session: 
141                needed=1
142               
143            session['lastViewed']=h.current_url()
144            if needed: 
145                c.pageTabs.append(('Details',session['lastViewed']))
146           
147            session.save()
148            code=200
149        else:
150            renderTemplate = 'error'
151            if x.startswith('<p> Access Denied'):
152                code=401
153            else: code=400
154            c.xml='%s'%x
155            logging.error(x)
156           
157        response.status_code = code
158        try:
159            return render(templateType, renderTemplate)
160       
161        except ExpatError, e:
162            c.xml='XML content is not well formed'
163            c.doc=str(x)
164            response.status_code = 400
165            logging.error("Error retrieving [%s] - XML content: %s" % (uri, e))
166            return render('error')
167
168        except Exception, e:
169            #we may be showing an xml document ... but it could go wrong if
170            #we have crap content ...
171            c.xml='Unexpected error [%s] viewing [%s]'%(str(e), uri)
172            c.doc=''
173            response.status_code = 400
174            logging.error(c.xml)
175            return render('error')
176   
177    def askCorrect(self,uri):
178        ''' Provide a form (ajaxaciously) so that a user can correct a metadata record'''
179        status=self.__setup(uri)
180        c.uri=self.uri
181        if status: return response.write(status)
182        return render('correct',fragment=True)
183
184   
185    def correct(self,uri):
186        ''' Receive a correction form to update a record and post it to the holder '''
187        status=self.__setup(uri)
188        if 'ndgSec' not in session:
189            return response.write('Not Logged In')
190        body='Metadata Change Request for %s'%uri
191        payload='<Change><uri>%s</uri><from>%s</from><Contents>%s</Contents></Change>'%(
192            self.inputs['Identifier'],self.inputs['Submitter'],self.inputs['Comment'])
193        name='ChangeRequestFor_%s.xml'%uri
194        status,message=mailer.mailHandler([self.cf.get('DEFAULT','metadataMaintainer'),],
195                       body,body,xmlAttachments=[(payload,name),],
196                       server=self.cf.get('DEFAULT','mailserver'))
197        if status:
198            c.xml='<p>Success: Mail sent to metadata maintainer</p>'
199        else:
200            c.xml=message
201        return render('content')
202       
203
204    def __mytb(self,name):
205        ''' Get the trackback info for this page
206        (can't do it in Kid because it doesn't do substitutions in comments) '''
207        s='''<!--
208        <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
209             xmlns:dc="http://purl.org/dc/elements/1.1/"
210             xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
211        <rdf:Description
212            rdf:about="%s"
213            dc:identifier="%s"
214            dc:title="%s"
215            trackback:ping="%s" />
216        </rdf:RDF>
217        -->'''%(self.uri,g.server+h.url_for(),name,g.server+h.url_for(controller="trackback"))
218        return s
Note: See TracBrowser for help on using the repository browser.