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

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

Better error handling, better parameter showing. Shell example
javascript as an initial step to using the Vocabserver.

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