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

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

Modifications to support unicode properly, and handle MDIP a bit better

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            try:
153                r=self.shower.get(r,format,otype=outputType,ndgObject=self.uri)
154            except Exception,e:
155                r='<p> Unable to show document, reason was [%s]<p>'%e
156        else:
157            ctype='text/xml'
158        return ctype,r
159   
160   
161    def __prompt(self):
162        ''' If the URI is not an argument to the request, prompt the user for a URI '''
163        h='''
164        <form method='get' action=''>
165        <p>
166          Enter a Document Identifier to View: 
167            <input type='text' name='uri'/><br/>
168            (uri format: e.g. badc.nerc.ac.uk:DIF:xyz39) <br/>
169            (Querying <input type='text' name='repository' value='gepidae.esc.rl.ac.uk'/>)<br/>
170            Return: <input type="radio" name="type" value="xml"/> XML Raw
171                <input type="radio" name="type" value="html"/> Formatted
172                <input type="radio" name="type" value="print"/> XML Printable
173          <input type='submit'/>
174        </p>
175        </form>
176        '''
177        return h
178   
179import unittest
180testURI='noc.soton.ac.uk__DIF__NOCSDAT193'
181retriever=ndgRetrieve('./')
182class TestCase(unittest.TestCase):
183       
184    def testOriginal(self):
185        ''' Tests the ability to obtain an original document '''
186        inputs={'repository':'glue.badc.rl.ac.uk','uri':testURI,'format':'original','type':'html','original':'1'}
187        ctype,r=retriever._present(inputs,'text/html')
188        if r[0:3]=='<p>':raise ValueError,r
189    def testDIF(self):
190        ''' Tests the ability to obtain a DIF document '''
191        inputs={'repository':'glue.badc.rl.ac.uk','uri':testURI,'format':'DIF','type':'html'}
192        ctype,r=retriever._present(inputs,'text/html')
193        if r[0:3]=='<p>':raise ValueError,r
194    def testMDIP(self):
195        ''' Tests the ability to obtain an MDIP document '''
196        inputs={'repository':'glue.badc.rl.ac.uk','uri':testURI,'format':'MDIP','type':'html'}
197        ctype,r=retriever._present(inputs,'text/html')
198        if r[0:3]=='<p>':raise ValueError,r
199    def testISO(self):
200        ''' Tests the ability to obtain an ISO document '''
201        inputs={'repository':'glue.badc.rl.ac.uk','uri':testURI,'format':'ISO19139','type':'html'}
202        ctype,r=retriever._present(inputs,'text/html')
203        if r[0:3]=='<p>':raise ValueError,r
204    def testDC(self):
205        ''' Tests the ability to obtain a DC document '''
206        inputs={'repository':'glue.badc.rl.ac.uk','uri':testURI,'format':'DC','type':'html'}
207        ctype,r=retriever._present(inputs,'text/html')
208        if r[0:3]=='<p>':raise ValueError,r
209       
210       
211if __name__=="__main__":
212    unittest.main()
213   
Note: See TracBrowser for help on using the repository browser.