source: MILK/trunk/milk_server/milk_server/models/DiscoveryState.py @ 5261

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/MILK/trunk/milk_server/milk_server/models/DiscoveryState.py@5261
Revision 5261, 4.2 KB checked in by cbyrom, 11 years ago (diff)

Lots of tidy ups to MILK codebase:

Implement new input search filters - with javascript datapickers to
pick the date ranges + add the vocab search ahead text input and
combine this with the text input.

Refactor discovery controller to tidy it up significantly - making more
structured and improving error handling and logging. Improve
templates for the search filter, splitting into multiple files to
organise better.

Various tidying up and tweaks of other codebase - e.g. standardising
use of global variables across app.

Line 
1from paste.request import parse_querystring
2import cgi,urllib
3class constraints:
4    '''
5    A container object for constraints on a search
6    '''
7    def __init__(self, **kw):
8        self.values={}
9        keys=['dateRange','bbox','scope','textTarget','searchString','geoSearchType']
10        for key in keys:
11            self.values[key]=None
12        for k in kw: 
13            self[k]=kw[k]
14           
15           
16    def __setitem__(self, key, value):
17        if key in self.values:
18            self.values[key]=value
19        else:
20            raise ValueError('Unknown key [%s] in constraints')
21
22   
23    def __getitem__(self,key):
24        if key in self.values: 
25            return self.values[key]
26        else:
27            raise ValueError('Unknown key [%s] in constraints'%key)
28
29   
30    def __str__(self):
31        c=''
32        if self.values['dateRange'] is not None:
33            dr = self.values['dateRange'] 
34            c += 'Date range: %s to %s'%('%s/%s/%s'%dr[0],'%s/%s/%s'%dr[1])
35        bbox=self.values['bbox']
36        if c:
37            c += ', '
38        c += 'Bounding box: '
39        if bbox is None or bbox==['90.0','-180.0','180.0','-90.0']:
40            c+='Global'
41        else:
42            overlaps = self.values['geoSearchType'] or 'overlaps'
43            c+='%s latitude %s to %sN and longitude %s to %sE' \
44                %(overlaps,bbox[3],bbox[0],bbox[1],bbox[2])
45        if self.values['scope']: 
46            c += 'Scope: %s'%self.values['scope']
47        if self.values['textTarget']:
48            c += 'Target: %s'%self.values['textTarget']
49        return c
50
51
52class DiscoveryState:
53    ''' This class holds the state associated with a search (including presenting multiple slices
54    of a large result set) '''
55    def __init__(self,sessionID,searchString,environ,hits,constraints,offset=1,stride=10):
56        ''' On instantiation, provide
57                the backend sessionID
58                the application URL that produced this query
59                the stride through the result set '''
60        self.environ=environ # the wsgi environment
61        self.constraintsInstance=constraints
62        self.constraints=str(constraints) # some text to show constraints on search
63        self.constrainedurl=self.geturl(constrained=1)+'&constrained'
64        self.sessID=sessionID
65        self.hits=hits
66        self.offset=offset
67        self.stride=stride
68        self.searchString=searchString
69        self.alternatives=None
70
71   
72    def geturl(self,**kw):
73        '''
74        Get a url from the wsgi environment, modified by the keyword arguments
75        offset and stride which are to be part of the querystring
76        '''
77        args=dict(parse_querystring(self.environ))
78        offset,stride=kw.get('offset'),kw.get('stride')
79        if offset is not None:args['start']=offset
80        if stride is not None:args['howmany']=stride
81        constrained=kw.get('constrained')
82        if constrained is not None:
83            if 'start' in args: del args['start']
84            if 'howmany' in args: del args['howmany']
85        q='?'
86        for i in args: q+='%s=%s&'%(i,args[i])
87        q=q[0:-1]
88        url=urllib.quote(self.environ.get('SCRIPT_NAME','')) + \
89            urllib.quote(self.environ.get('PATH_INFO','')) + q
90        #url=cgi.escape(url)
91        return url
92
93   
94    def getNext(self):
95        ''' Get the next slice '''
96        result=[]
97        defStride=10
98        if self.offset+self.stride<self.hits:
99            #there are more to look at
100            r=[self.offset+self.stride,self.stride]
101            if r[0]+r[1]-1>self.hits: r[1]=self.hits+1-r[0]
102            result.append(r)
103        else:result.append([])
104        if self.offset>1:
105            #there are previous records
106            b=max(self.stride,defStride)
107            r=[self.offset-b,b]
108            if r[0]<1: r[0]=1
109            if r[1]>self.hits: r[1]=self.hits
110            result.append(r)
111        else: result.append([])
112        return result
113       
114    def __str__(self):
115        return '''
116___ Discovery State ___
117searchString: %s
118constraints: %s
119sessionID: %s
120hits: %s
121offset,stride: %s,%s
122environment: %s
123========================
124'''%(self.searchString,self.constraints,self.sessID,self.hits,self.offset,self.stride,self.environ)
Note: See TracBrowser for help on using the repository browser.