source: TI05-delivery/ows_framework/trunk/ows_server/ows_server/models/DiscoveryState.py @ 3093

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI05-delivery/ows_framework/trunk/ows_server/ows_server/models/DiscoveryState.py@3093
Revision 3093, 5.5 KB checked in by lawrence, 12 years ago (diff)

Most of the coding for geospatial operators. Improvements
to results display for multiple bounding boxes.

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