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

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

Sundry modifications to get browse working again and to use a
config file to identify the appropriate repositories (for
a given ndg uri, what repository holds the browse info? this
is by way of a temporary expedient).

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=='MOLES-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        if environ['SCRIPT_NAME']=='/browse': browse=1
93       
94        ctype='text/html'   # default content type (since the default
95                            # may be an error return ...) the actual default
96                            # data type for return is xml.
97                           
98        ctype,r=self._present(inputs,ctype)
99       
100        start_response('200 OK', [('Content-Type', ctype),('charset','utf-8')])
101        return [r.encode('utf-8')]
102               
103    def _present(self,inputs,ctype,browse=0):
104        ''' This is the entry point for an  inner retrieval loop for document retrieval '''
105        # we seperate this out for ease of building test cases
106        ori,format=0,None
107       
108        if 'original' in inputs.keys(): ori=1
109        try:
110            outputType=inputs['type']
111        except KeyError:
112            outputType='print'
113       
114        if 'uri' not in inputs.keys():
115            r=self.__prompt()
116            raise ValueError,r
117        else:
118            #this will raise a ValueError if there is a problem
119            uri=ndgObject(inputs['uri'])
120            uri.setConfig(self.config)
121            self.uri=uri
122            if 'repository' in inputs.keys(): 
123                db=inputs['repository']
124            else:
125                db=uri.repository
126            if db in self.WScursors.keys():
127                ws=self.WScursors[db]
128            else:
129                if db.upper()=='NDG':
130                    ws=ndgSearch()
131                else:
132                    ws=DocumentRetrieve(db)
133                self.WScursors[db]=ws
134            ok=1
135            try:
136                if ori:
137                #    r=ws.getOriginal(uri.uri)
138                    if outputType=='html': outputType='print'  # sanity ...   
139                #else:
140                if 'format' not in inputs:
141                    format=self.uri.schema
142                else:
143                    format=inputs['format']
144                if browse:
145                    target='/db/ndg_B_metadata'
146                else:
147                    target='/db/discovery/moles'
148                r=ws.get(uri.repository,uri.schema,uri.localID,format=format,targetCollection=target)
149                if isinstance(r,int):
150                     r='<p> There are %s identifiers matching your request! </p>'%r
151                     ok=0
152            except Exception,e:
153                 r='<p> Unable to retrieve [%s], reason was [%s]</p>'%(uri.uri,e)
154                 ok=0
155       
156        if not ok: return ctype,r
157       
158        if outputType!='xml': 
159            if debug:
160                r=self.shower.get(r,format,otype=outputType,ndgObject=self.uri)
161            else:
162                try:
163                    r=self.shower.get(r,format,otype=outputType,ndgObject=self.uri)
164                except Exception,e:
165                    r='<p> Unable to show document, reason was [%s]<p>'%e
166        else:
167            ctype='text/xml'
168        return ctype,r
169   
170   
171    def __prompt(self):
172        ''' If the URI is not an argument to the request, prompt the user for a URI '''
173        h='''
174        <form method='get' action=''>
175        <p>
176          Enter a Document Identifier to View: 
177            <input type='text' name='uri'/><br/>
178            (uri format: e.g. badc.nerc.ac.uk:DIF:xyz39) <br/>
179            (Querying <input type='text' name='repository' value='gepidae.esc.rl.ac.uk'/>)<br/>
180            Return: <input type="radio" name="type" value="xml"/> XML Raw
181                <input type="radio" name="type" value="html"/> Formatted
182                <input type="radio" name="type" value="print"/> XML Printable
183          <input type='submit'/>
184        </p>
185        </form>
186        '''
187        return h
188   
189import unittest
190#testURI='noc.soton.ac.uk__DIF__NOCSDAT193'
191#testURI='ndg.noc.soton.ac.uk__NDG-B0__NOCSDAT274'
192#testURI='grid.bodc.nerc.ac.uk__DIF__EDMED1048034'
193#testURI='grid.bodc.nerc.ac.uk__DIF__EDMED1048008'
194testURI='bgs.nerc.ac.uk__DIF__GEOP_EAST'
195testURI='neodc.nerc.ac.uk__DIF__NEODC_NEXTMAP'
196retriever=ndgRetrieve('./')
197class TestCase(unittest.TestCase):
198       
199    def AtestOriginal(self):
200        ''' Tests the ability to obtain an original document via xmlrpc '''
201        inputs={'repository':'glue.badc.rl.ac.uk','uri':testURI,'format':'original','type':'html','original':'1'}
202        ctype,r=retriever._present(inputs,'text/html')
203        if r[0:3]=='<p>':raise ValueError,r
204    def AtestSOAPOriginal(self):
205        ''' Tests the ability to obtain an original document via soap '''
206        inputs={'repository':'ndg','uri':testURI,'format':'original','type':'html','original':'1'}
207        ctype,r=retriever._present(inputs,'text/html')
208        if r[0:3]=='<p>':raise ValueError,r
209    def AtestDIF(self):
210        ''' Tests the ability to obtain a DIF document '''
211        inputs={'repository':'glue.badc.rl.ac.uk','uri':testURI,'format':'DIF','type':'html'}
212        ctype,r=retriever._present(inputs,'text/html')
213        if r[0:3]=='<p>':raise ValueError,r
214    def AtestMDIP(self):
215        ''' Tests the ability to obtain an MDIP document '''
216        inputs={'repository':'glue.badc.rl.ac.uk','uri':testURI,'format':'MDIP','type':'html'}
217        ctype,r=retriever._present(inputs,'text/html')
218        if r[0:3]=='<p>':raise ValueError,r
219    def AtestISO(self):
220        ''' Tests the ability to obtain an ISO document '''
221        inputs={'repository':'glue.badc.rl.ac.uk','uri':testURI,'format':'ISO19139','type':'html'}
222        ctype,r=retriever._present(inputs,'text/html')
223        if r[0:3]=='<p>':raise ValueError,r
224    def AtestDC(self):
225        ''' Tests the ability to obtain a DC document '''
226        inputs={'repository':'glue.badc.rl.ac.uk','uri':testURI,'format':'DC','type':'html'}
227        ctype,r=retriever._present(inputs,'text/html')
228        if r[0:3]=='<p>':raise ValueError,r
229    def testCh(self):
230        ''' test link to local repository for NDG-B0'''
231        testURI='badc.nerc.ac.uk__NDG-B0__dataent_chablis'
232        inputs={'repository':'chinook.badc.rl.ac.uk','uri':testURI,'format':'NDG-B0','type':'xml'}
233        ctype,r=retriever._present(inputs,'text/html',browse=1)
234        if r[0:3]=='<p>':raise ValueError,r
235       
236    def testCHstub(self):
237        ''' test link to local repository for NDG-B0'''
238        testURI='badc.nerc.ac.uk__NDG-B0__dataent_chablis'
239        testURI='badc.nerc.ac.uk__NDG-B0__activity_activity_faam'
240        inputs={'repository':'chinook.badc.rl.ac.uk','uri':testURI,'format':'NDG-B1','type':'xml'}
241        ctype,r=retriever._present(inputs,'text/html',browse=1)
242        if r[0:3]=='<p>':raise ValueError,r
243       
244if __name__=="__main__":
245    unittest.main()
246   
Note: See TracBrowser for help on using the repository browser.