source: TI07-MOLES/trunk/PythonCode/wsgi/ndgRetrieve.py @ 2345

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI07-MOLES/trunk/PythonCode/wsgi/ndgRetrieve.py@2345
Revision 2345, 8.5 KB checked in by lawrence, 12 years ago (diff)

Now using the SOAP call for all discovery D calls, rather than XMLRPC
for discovery portability ...

Line 
1from Utilities import myConfig
2from paste.request import parse_querystring
3from renderEntity import renderEntity
4import xmlHandler
5from DC import DC
6from DIF import DIF
7from stubB import stubB
8from ndgObject import ndgObject
9from MDIP import MDIP
10from ndgSearch import ndgSearch
11
12# any class with a get method can be used here, and then only
13# the instantiation within ndgRetrieve would need
14# modification to use it ...
15
16from DocumentRetrieve import DocumentRetrieve
17debug=1
18def retrieveFactory(global_config,**local_conf):
19   
20    ''' This factory is intended to be used by paste-deploy to return
21    the ndgRetrieve wsgi application, configured to use the configDir
22    to find local configuration information '''
23   
24    if 'configDir' in local_conf.keys():
25        configDir=local_conf[configDir]
26    else:
27        try:
28            configDir=global_config['configDir']
29        except:
30            configDir=None
31    ndg=ndgRetrieve(configDir)
32    return ndg
33
34class showDoc:
35    ''' Given an xml document (xml), of format ('DIF','DC','NDG-B1'), return
36    either the document rendered as "pretty" xml for printing, or as html
37    rendered by an appropriate application'''
38   
39    def __init__(self,config):
40        self.config=config
41        self.renderer=renderEntity(self.config)
42       
43    def get(self,xml,format,otype='html',ndgObject=None):
44        if otype=='html':
45            if format=='DIF':
46                r=DIF(xml,ndgObject=ndgObject)
47            elif format=='NDG-B1':
48                r=stubB(xml,self.config)
49            elif format=='DC':
50                r=DC(xml)
51            elif format=='MDIP':
52                r=MDIP(xml)
53            else:
54                raise ValueError,'Unknown format [%s] for rendering'%format
55            r=self.renderer.render(r)
56        elif otype=='print':
57            x=xmlHandler.xmlHandler(xml,string=1)
58            r=x.html
59        elif otype=='xml':
60            return xml
61        else:
62            raise TypeError('Invalid output type [%s]'%otype)
63        return r
64
65class ndgRetrieve:
66   
67    ''' This is the ndgRetrieve application which simply allows one to enter a uri
68    of a document held in a LOCAL exist repository and return one of
69       - the raw document (type=xml),
70       - an html version fully rendered (type=html, which is the default), or
71       - a pretty printed version suitable for printing (type=print)
72    Note that this WSGI application SHOULD be wrapped by an ndgGatekeeper MIDDLEWARE application and
73    not exposed directly to users (except in testing of course :-) '''
74   
75    def __init__(self,configDir):
76       
77        ''' Instantiate the wsgi document retrieval application '''
78        self.configDir=configDir
79        self.config=myConfig(configDir+'ndgDiscovery.config')
80        self.shower=showDoc(self.config)
81        # nb ... we don't instantiate the retrieval web service, since
82        # we expect to potentially have multiple web services pointing
83        # at multiple databases (eg. BADC + NEODC + NDG ) ...
84        self.retrieveWS=DocumentRetrieve
85        self.WScursors={}
86   
87    def __call__(self,environ,start_response):
88       
89        ''' This is the function which implements the document retrieval '''
90       
91        inputs=dict(parse_querystring(environ))
92       
93        ctype='text/html'   # default content type (since the default
94                            # may be an error return ...) the actual default
95                            # data type for return is xml.
96                           
97        ctype,r=self._present(inputs,ctype)
98       
99        start_response('200 OK', [('Content-Type', ctype),('charset','utf-8')])
100        return [r.encode('utf-8')]
101               
102    def _present(self,inputs,ctype):
103        ''' This is the entry point for an  inner retrieval loop for document retrieval '''
104        # we seperate this out for ease of building test cases
105        ori,format=0,None
106       
107        if 'original' in inputs.keys(): ori=1
108        try:
109            outputType=inputs['type']
110        except KeyError:
111            outputType='print'
112       
113        if 'uri' not in inputs.keys():
114            r=self.__prompt()
115            raise ValueError,r
116        else:
117            #this will raise a ValueError if there is a problem
118            uri=ndgObject(inputs['uri'])
119            uri.setConfig(self.config)
120            self.uri=uri
121            if 'repository' in inputs.keys(): 
122                db=inputs['repository']
123            else:
124                db=uri.repository
125            if db in self.WScursors.keys():
126                ws=self.WScursors[db]
127            else:
128                if db.upper()=='NDG':
129                    ws=ndgSearch()
130                else:
131                    ws=DocumentRetrieve(db)
132                self.WScursors[db]=ws
133            ok=1
134            try:
135                if ori:
136                #    r=ws.getOriginal(uri.uri)
137                    if outputType=='html': outputType='print'  # sanity ...   
138                #else:
139                if 'format' not in inputs.keys():
140                    format='NDG-B0'
141                else:
142                    format=inputs['format']
143                print 'Request for %s format document'%inputs['format']
144                r=ws.get(uri.repository,uri.schema,uri.localID,format=format)   
145                if isinstance(r,int):
146                     r='<p> There are %s identifiers matching your request! </p>'%r
147                     ok=0
148            except Exception,e:
149                 r='<p> Unable to retrieve [%s], reason was [%s]</p>'%(uri.uri,e)
150                 ok=0
151       
152        if not ok: return ctype,r
153       
154        if outputType!='xml': 
155            if debug:
156                r=self.shower.get(r,format,otype=outputType,ndgObject=self.uri)
157            else:
158                try:
159                    r=self.shower.get(r,format,otype=outputType,ndgObject=self.uri)
160                except Exception,e:
161                    r='<p> Unable to show document, reason was [%s]<p>'%e
162        else:
163            ctype='text/xml'
164        return ctype,r
165   
166   
167    def __prompt(self):
168        ''' If the URI is not an argument to the request, prompt the user for a URI '''
169        h='''
170        <form method='get' action=''>
171        <p>
172          Enter a Document Identifier to View: 
173            <input type='text' name='uri'/><br/>
174            (uri format: e.g. badc.nerc.ac.uk:DIF:xyz39) <br/>
175            (Querying <input type='text' name='repository' value='gepidae.esc.rl.ac.uk'/>)<br/>
176            Return: <input type="radio" name="type" value="xml"/> XML Raw
177                <input type="radio" name="type" value="html"/> Formatted
178                <input type="radio" name="type" value="print"/> XML Printable
179          <input type='submit'/>
180        </p>
181        </form>
182        '''
183        return h
184   
185import unittest
186#testURI='noc.soton.ac.uk__DIF__NOCSDAT193'
187#testURI='ndg.noc.soton.ac.uk__NDG-B0__NOCSDAT274'
188#testURI='grid.bodc.nerc.ac.uk__DIF__EDMED1048034'
189#testURI='grid.bodc.nerc.ac.uk__DIF__EDMED1048008'
190testURI='bgs.nerc.ac.uk__DIF__GEOP_EAST'
191testURI='neodc.nerc.ac.uk__DIF__NEODC_NEXTMAP'
192retriever=ndgRetrieve('./')
193class TestCase(unittest.TestCase):
194       
195    def AtestOriginal(self):
196        ''' Tests the ability to obtain an original document via xmlrpc '''
197        inputs={'repository':'glue.badc.rl.ac.uk','uri':testURI,'format':'original','type':'html','original':'1'}
198        ctype,r=retriever._present(inputs,'text/html')
199        if r[0:3]=='<p>':raise ValueError,r
200    def testSOAPOriginal(self):
201        ''' Tests the ability to obtain an original document via soap '''
202        inputs={'repository':'ndg','uri':testURI,'format':'original','type':'html','original':'1'}
203        ctype,r=retriever._present(inputs,'text/html')
204        if r[0:3]=='<p>':raise ValueError,r
205    def AtestDIF(self):
206        ''' Tests the ability to obtain a DIF document '''
207        inputs={'repository':'glue.badc.rl.ac.uk','uri':testURI,'format':'DIF','type':'html'}
208        ctype,r=retriever._present(inputs,'text/html')
209        if r[0:3]=='<p>':raise ValueError,r
210    def AtestMDIP(self):
211        ''' Tests the ability to obtain an MDIP document '''
212        inputs={'repository':'glue.badc.rl.ac.uk','uri':testURI,'format':'MDIP','type':'html'}
213        ctype,r=retriever._present(inputs,'text/html')
214        if r[0:3]=='<p>':raise ValueError,r
215    def AtestISO(self):
216        ''' Tests the ability to obtain an ISO document '''
217        inputs={'repository':'glue.badc.rl.ac.uk','uri':testURI,'format':'ISO19139','type':'html'}
218        ctype,r=retriever._present(inputs,'text/html')
219        if r[0:3]=='<p>':raise ValueError,r
220    def AtestDC(self):
221        ''' Tests the ability to obtain a DC document '''
222        inputs={'repository':'glue.badc.rl.ac.uk','uri':testURI,'format':'DC','type':'html'}
223        ctype,r=retriever._present(inputs,'text/html')
224        if r[0:3]=='<p>':raise ValueError,r
225       
226if __name__=="__main__":
227    unittest.main()
228   
Note: See TracBrowser for help on using the repository browser.