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

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

Fixes for ticket:818

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