source: TI07-MOLES/trunk/PythonCode/wsgi/DiscoveryGUI.py @ 2522

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

Sundry minor improvements in layout etc.

Line 
1import DiscoveryTemplate
2from paste.request import parse_querystring
3import ndgSearch as NS
4from DIF import DIF
5from renderDiscoverySet import renderDiscoverySet
6from DiscoveryState import DiscoveryState
7from Utilities import myConfig,mailError
8from ndgObject import ndgObject
9from Date import *
10debug=0
11class DiscoveryGUI:
12    ''' This class handles the NDG gui search interface, and is intimately related to the
13    template.py code which provides the gui interface and the variables which need to be populated '''
14   
15    #The key options are either there is content in the inputdictionary, in which case we have a
16    #search to do, and then some results to present, or there is none, in which case we present
17    #an appropriate interface back to the user (remembering that we only produce part of a page,
18    #this can all be embedded in anything else.
19   
20    def __init__(self,environ,config,logger):
21        ''' Takes a dictionary of variables which have been populated by the cgi (or whatever)
22        handler, and tests them for sanity before handing queries off to the NDG backend xqquery
23        web service '''
24       
25        inputs=dict(parse_querystring(environ))
26        self.inputs=inputs
27        self.environ=environ
28        self.config=config
29        self.logger=environ['wsgilog.logger']
30        self.mailServer=self.config.get('DEFAULT','mailServer','outbox.rl.ac.uk')
31        self.message=''
32        self.html=''
33       
34        #is this simply a blank request for an interface?
35        if self.inputs.keys()==[]:
36            self.html+='<div id="superPad">'
37            self.standardInterface()
38            self.html+='</div>'
39            return
40        elif self.inputs.keys()==['advanced']:
41            self.advancedInterface()
42            return
43        elif self.inputs.keys()==['help']:
44            self.helpInterface(0)
45            return
46        elif self.inputs.keys()==['help','advanced']:
47            self.helpInterface(1)
48            return
49       
50        #check simplest text issues common to both simple and advanced search
51        expected=['advanced','textTarget','searchString']
52        self.__checkform(expected)
53        if self.message!='': return
54       
55        #the following may also be present
56        continuations={'start':1,'howmany':10}
57        for i in continuations:
58            if i not in self.inputs: self.inputs[i]=continuations[i]
59           
60        advanced=int(self.inputs['advanced'])
61        self.advanced=advanced
62       
63        self.html=''
64        if not advanced:
65            self.doText(self.inputs['searchString'],self.inputs['textTarget'],
66                        self.inputs['start'],self.inputs['howmany'])
67        else:
68            #check content
69            expected=['timeLimit','startDateDay','startDateMon','startDateYear',
70                        'endDateDay','endDateMon','endDateYear','spaceLimit',
71                        'bboxN','bboxE','bboxS','bboxW',
72                        'sourceLimit']
73            self.__checkform(expected)
74            if self.message!='': return self.error()
75             
76            if int(self.inputs['sourceLimit']):
77                scope=[]
78                if 'sourceMDIP' in self.inputs:
79                    if self.inputs['sourceMDIP']: scope.append('MDIP')
80                if 'sourceNERC' in self.inputs:
81                    if self.inputs['sourceNERC']: scope.append('NERC_DDC')
82            else:
83                scope=None
84               
85            if int(self.inputs['spaceLimit']):
86                bbox=[self.inputs['bboxN'],self.inputs['bboxS'],self.inputs['bboxW'],self.inputs['bboxE']]
87                self.__checkbox(bbox)
88                if self.message!='': return self.error()
89            else:
90                bbox=None
91               
92            if int(self.inputs['timeLimit']):
93                dateRange=[(self.inputs['startDateDay'],self.inputs['startDateMon'],self.inputs['startDateYear']),
94                           (self.inputs['endDateDay'],self.inputs['endDateMon'],self.inputs['endDateYear'])]
95                self.__checkdates(dateRange)                 
96                if self.message!='': return self.error()
97                       
98            else:
99                dateRange=None
100 
101            self.doText(self.inputs['searchString'],self.inputs['textTarget'],
102                        self.inputs['start'],self.inputs['howmany'],scope=scope,dateRange=dateRange,bbox=bbox)
103           
104        return
105           
106           
107    def __checkbox(self,bbox):
108        if float(bbox[0])>90.0 or float(bbox[1])<-90. or float(bbox[2])<-180. or float(bbox[3])>180.:
109            self.message='Invalid bounding box dimensions entered (limits 90,-90,-180,180)'
110           
111    def __checkform(self,expected):
112        ''' Simply checks the inputs to make sure the elements in expected are present '''
113        message="An incomplete NDG search form was received: "
114        for i in expected:
115            if i not in self.inputs: 
116                self.message=message+i
117                self.html='<p>%s</p>'%self.message
118               
119    def __checkdates(self,dateRange):
120        ''' Check input dates for sanity '''
121        print dateRange,ValidDate(dateRange[0]),ValidDate(dateRange[1])
122        if not ValidDate(dateRange[0])*ValidDate(dateRange[1]):
123            self.message='Input dates are not valid'
124        elif JulDay(dateRange[0])>=JulDay(dateRange[1]):
125            self.message='Second date must be after first date'
126               
127    def __setState(self,id,searchString,hits,offset,stride):
128        ''' Sets the discovery state to be used by external routines '''
129        if hits<stride:stride=hits
130        return DiscoveryState(id,searchString,self.environ,hits,offset,stride)
131       
132   
133    def error(self):
134        ''' Return a useful error message '''
135        self.html='<div class="error"><p>%s</p></div>'%self.message
136        if self.advanced:
137            self.advancedInterface()
138        else:
139            self.standardInterface()
140       
141   
142    def doText(self,searchString,textTarget,start,howmany,scope=None,dateRange=None,bbox=None):
143        ''' Carry out a text search for <searchString>
144        in the <textTarget> where the accepted text target values are controlled
145        by the DiscoveryTemplate GUI, and are: All, Authors, Parameters '''
146       
147        start,howmany=int(start),int(howmany)  # url arguments need conversion ...
148       
149        ws=NS.ndgSearch(logger=self.logger)
150        documents=ws.search(searchString,start=start,howmany=howmany,target=textTarget,
151                            scope=scope,dateRange=dateRange,bbox=bbox)
152        if ws.error !=None:
153            for i in ws.error:
154                self.html+='<p>%s</p>'%i
155            return
156       
157        hits=ws.hits
158        id=ws.serverSessionID
159        state=self.__setState(id,searchString,hits,start,howmany)
160        if hits==0: 
161            self.html+='<p> No records found </p>'
162        else:
163            try:
164                results=ws.getLabelledDocs(format='DIF')
165                difs=[]
166                errors=[]
167                for result in results: 
168                    obj=ndgObject(result[0])
169                    obj.setConfig(self.config)
170                    try:
171                        difs.append(DIF(result[1],ndgObj=obj))
172                    except ValueError,e:
173                        errors.append((result[0],str(e)))
174                if results==[]:
175                    self.html+='<p>No results for "%s"!</p>'%searchString
176                elif difs==[]:
177                    self.html+='<p>No usable results for "%s"!'%searchString
178                else:
179                    if errors<>[]:
180                        self.html+='<p>Search results for "%s"'%searchString
181                        dp=[]
182                        for e in errors:
183                            n=ndgObject(e[0])
184                            if n.repository not in dp: dp.append(n.repository)
185                        if len(dp)<>1: 
186                            dp='[Various Data Providers]'
187                        else:
188                            dp='[%s]'%dp[0] 
189                        self.html+=' (unfortunately %s hits matched unformattable documents from %s, an internal error has been logged):</p>'%(len(errors),dp)
190                        mailError('b.n.lawrence@rl.ac.uk','DIF errors',str(errors),server=self.mailServer)
191                    self.html+=renderDiscoverySet(difs,state,config=self.config,
192                               summary=1,spatial=1,temporal=1,services=1)
193            except ValueError,e:
194                if debug: 
195                    raise ValueError,str(e)
196                else:
197                    self.html='<p> Error retrieving documents for %s hits is [%s]</p>'%(hits,e)
198                               
199        self.standardInterface()
200        return
201
202    def standardInterface(self):
203       
204        try:
205            helpAddress=self.config.get('SEARCH','helpURL')
206            discoveryURL=self.config.get('SEARCH','discoveryURL')
207            advancedURL=self.config.get('SEARCH','advancedURL')
208        except:
209            self.message='Error, invalid configuration for search interface'
210            self.html+=''
211            return
212       
213        self.html+=DiscoveryTemplate.main%locals()
214        return
215   
216    def advancedInterface(self):
217       
218        try:
219            helpAddress=self.config.get('SEARCH','helpURL')
220            discoveryURL=self.config.get('SEARCH','discoveryURL')
221            advancedURL=self.config.get('SEARCH','advancedURL')
222        except:
223            self.message='Error, invalid configuration for search interface'
224            self.html=''
225            return
226        advancedSubmit=DiscoveryTemplate.advancedSubmit%locals()
227        searchText=DiscoveryTemplate.searchText
228        searchTime=DiscoveryTemplate.searchTime
229        searchArea=DiscoveryTemplate.searchArea
230        searchSource=DiscoveryTemplate.searchSource
231        self.html+=DiscoveryTemplate.advanced%locals()
232        return
233   
234    def helpInterface(self,advanced):
235        if advanced:
236            self.advancedInterface()
237        else:
238            self.standardInterface()
239        helpFile=self.config.get('HELP','helpFile')
240        f=file(helpFile,'r')
241        self.html+=f.read()
242        return
243       
244       
Note: See TracBrowser for help on using the repository browser.