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

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

Strip out code not relevant to MILK - mainly WCS and WMS stuff - also including the CSML server code + trackback code
Also tidy up structure of 'public' dir - setting up new 'style' dir and
centralising icons in icons dir + remove all unused icons, javascript and stylesheets.
Also strip out testcase code and populate new test directory structure.

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 = 'csml'
180                renderTemplate = 'content'
181                name=self.uri.localID
182                #for now we'll handle as pretty print xml
183                c.xml=x.tohtml()
184                c.tab='Details'
185               
186            elif viewFormat == ndgObject.DIF_DOC_TYPE:
187                renderTemplate = 'dif'
188                c.doc=DIF.DIF(x.tree,et=1,ndgObj=self.uri)
189                name=c.doc.name
190               
191            elif viewFormat == ndgObject.NUMSIM_DOC_TYPE:
192                renderTemplate = 'numsim'
193                c.xmlh=x
194                name=x.getText('NS_Name')
195                c.name=name
196               
197            else:
198                c.xml=x.tohtml()
199                renderTemplate = 'content'
200           
201            needed=0
202            if 'lastViewed' not in session: 
203                needed=1
204               
205            session['lastViewed']=h.current_url()
206            if needed: 
207                c.pageTabs.append(('Details',session['lastViewed']))
208           
209            session.save()
210            code=200
211        else:
212            renderTemplate = 'error'
213            if x.startswith('<p> Access Denied'):
214                code=401
215            else: code=400
216            c.xml='%s'%x
217            logging.error(x)
218           
219        response.status_code = code
220        try:
221            return render(templateType, renderTemplate)
222       
223        except ExpatError, e:
224            c.xml='XML content is not well formed'
225            c.doc=str(x)
226            response.status_code = 400
227            logging.error("Error retrieving [%s] - XML content: %s" % (uri, e))
228            return render('error')
229
230        except Exception, e:
231            #we may be showing an xml document ... but it could go wrong if
232            #we have crap content ...
233            c.xml='Unexpected error [%s] viewing [%s]'%(str(e), uri)
234            c.doc=''
235            response.status_code = 400
236            logging.error(c.xml)
237            return render('error')
238   
239    def askCorrect(self,uri):
240        ''' Provide a form (ajaxaciously) so that a user can correct a metadata record'''
241        status=self.__setup(uri)
242        c.uri=self.uri
243        if status: return response.write(status)
244        return render('correct',fragment=True)
245
246   
247    def correct(self,uri):
248        ''' Receive a correction form to update a record and post it to the holder '''
249        status=self.__setup(uri)
250        if 'ndgSec' not in session:
251            return response.write('Not Logged In')
252        body='Metadata Change Request for %s'%uri
253        payload='<Change><uri>%s</uri><from>%s</from><Contents>%s</Contents></Change>'%(
254            self.inputs['Identifier'],self.inputs['Submitter'],self.inputs['Comment'])
255        name='ChangeRequestFor_%s.xml'%uri
256        status,message=mailer.mailHandler([self.cf.get('DEFAULT','metadataMaintainer'),],
257                       body,body,xmlAttachments=[(payload,name),],
258                       server=self.cf.get('DEFAULT','mailserver'))
259        if status:
260            c.xml='<p>Success: Mail sent to metadata maintainer</p>'
261        else:
262            c.xml=message
263        return render('content')
Note: See TracBrowser for help on using the repository browser.