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

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

Fixes for ticket:664

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
16debug=0
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                    print 'Succeeded'
134                    if outputType=='html': outputType='print'  # sanity ...   
135                else:
136                   
137                    if 'format' not in inputs.keys():
138                        format='NDG-B0'
139                    else:
140                        format=inputs['format']
141                    print 'Request for %s format document'%inputs['format']
142                    r=ws.get(uri.repository,uri.schema,uri.localID,format=format)       
143                if isinstance(r,int):
144                     r='<p> There are %s identifiers matching your request! </p>'%r
145                     ok=0
146            except Exception,e:
147                 r='<p> Unable to retrieve [%s], reason was [%s]</p>'%(uri.uri,e)
148                 ok=0
149       
150        if not ok: return ctype,r
151       
152        if outputType!='xml': 
153            if debug:
154                r=self.shower.get(r,format,otype=outputType,ndgObject=self.uri)
155            else:
156                try:
157                    r=self.shower.get(r,format,otype=outputType,ndgObject=self.uri)
158                except Exception,e:
159                    r='<p> Unable to show document, reason was [%s]<p>'%e
160        else:
161            ctype='text/xml'
162        return ctype,r
163   
164   
165    def __prompt(self):
166        ''' If the URI is not an argument to the request, prompt the user for a URI '''
167        h='''
168        <form method='get' action=''>
169        <p>
170          Enter a Document Identifier to View: 
171            <input type='text' name='uri'/><br/>
172            (uri format: e.g. badc.nerc.ac.uk:DIF:xyz39) <br/>
173            (Querying <input type='text' name='repository' value='gepidae.esc.rl.ac.uk'/>)<br/>
174            Return: <input type="radio" name="type" value="xml"/> XML Raw
175                <input type="radio" name="type" value="html"/> Formatted
176                <input type="radio" name="type" value="print"/> XML Printable
177          <input type='submit'/>
178        </p>
179        </form>
180        '''
181        return h
182   
183import unittest
184#testURI='noc.soton.ac.uk__DIF__NOCSDAT193'
185#testURI='ndg.noc.soton.ac.uk__NDG-B0__NOCSDAT274'
186#testURI='grid.bodc.nerc.ac.uk__DIF__EDMED1048034'
187#testURI='grid.bodc.nerc.ac.uk__DIF__EDMED1048008'
188testURI='bgs.nerc.ac.uk__DIF__GEOP_EAST'
189testURI='neodc.nerc.ac.uk__DIF__NEODC_NEXTMAP'
190retriever=ndgRetrieve('./')
191class TestCase(unittest.TestCase):
192       
193    def testOriginal(self):
194        ''' Tests the ability to obtain an original document '''
195        inputs={'repository':'glue.badc.rl.ac.uk','uri':testURI,'format':'original','type':'html','original':'1'}
196        ctype,r=retriever._present(inputs,'text/html')
197        if r[0:3]=='<p>':raise ValueError,r
198    def testDIF(self):
199        ''' Tests the ability to obtain a DIF document '''
200        inputs={'repository':'glue.badc.rl.ac.uk','uri':testURI,'format':'DIF','type':'html'}
201        ctype,r=retriever._present(inputs,'text/html')
202        if r[0:3]=='<p>':raise ValueError,r
203    def testMDIP(self):
204        ''' Tests the ability to obtain an MDIP document '''
205        inputs={'repository':'glue.badc.rl.ac.uk','uri':testURI,'format':'MDIP','type':'html'}
206        ctype,r=retriever._present(inputs,'text/html')
207        if r[0:3]=='<p>':raise ValueError,r
208    def testISO(self):
209        ''' Tests the ability to obtain an ISO document '''
210        inputs={'repository':'glue.badc.rl.ac.uk','uri':testURI,'format':'ISO19139','type':'html'}
211        ctype,r=retriever._present(inputs,'text/html')
212        if r[0:3]=='<p>':raise ValueError,r
213    def testDC(self):
214        ''' Tests the ability to obtain a DC document '''
215        inputs={'repository':'glue.badc.rl.ac.uk','uri':testURI,'format':'DC','type':'html'}
216        ctype,r=retriever._present(inputs,'text/html')
217        if r[0:3]=='<p>':raise ValueError,r
218       
219       
220       
221if __name__=="__main__":
222    unittest.main()
223   
Note: See TracBrowser for help on using the repository browser.