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

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

Modifications to show original records

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