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

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

Sundry ticket fixes.

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','-180.0','180.0','-90.0']:
31            c+='Global; '
32        else: c+='Bounding Box: %sN,%sW,%sE,%sS; '%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=1)+'&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        constrained=kw.get('constrained')
65        if constrained is not None:
66            if 'start' in args: del args['start']
67            if 'howmany' in args: del args['howmany']
68        q=''
69        for i in args: q+='%s=%s&'%(i,args[i])
70        q=q[0:-1]
71        url=construct_url(self.environ, with_query_string=True, with_path_info=True, querystring=q)
72        #url=cgi.escape(url)
73        return url
74    def getNext(self):
75        ''' Get the next slice '''
76        result=[]
77        defStride=10
78        if self.offset+self.stride<self.hits:
79            #there are more to look at
80            r=[self.offset+self.stride,self.stride]
81            if r[0]+r[1]-1>self.hits: r[1]=self.hits+1-r[0]
82            result.append(r)
83        else:result.append([])
84        if self.offset>1:
85            #there are previous records
86            b=max(self.stride,defStride)
87            r=[self.offset-b,b]
88            if r[0]<1: r[0]=1
89            if r[1]>self.hits: r[1]=self.hits
90            result.append(r)
91        else: result.append([])
92        return result
93       
94    def __str__(self):
95        return '''
96___ Discovery State ___
97searchString: %s
98constraints: %s
99sessionID: %s
100hits: %s
101offset,stride: %s,%s
102environment: %s
103========================
104'''%(self.searchString,self.constraints,self.sessID,self.hits,self.offset,self.stride,self.environ)
105       
106if __name__=="__main__":
107   
108    import unittest
109    DummyEnviron={'QUERY_STRING':'start=10&howmany=10','HTTP_HOST':'example.ndg',
110                      'PATH_INFO':'/discovery','wsgi.url_scheme':'http','SERVER_PORT':'80'}
111
112    class TestCase(unittest.TestCase):
113       
114        def testDiscoveryState(self):
115            ''' Test creation of a discovery state variable '''
116            d=DiscoveryState('123','blah',DummyEnviron,12,'(none)')
117            self.assertEqual(d.geturl(offset='11',stride='20'),
118                            'http://example.ndg/discovery?start=11&amp;howmany=20')
119            print d
120   
121        def testStrideself(self):
122            ''' Test striding through a dataset '''
123           
124            s=DiscoveryState('123','blah',DummyEnviron,15,'(none)',1,10)
125            res=s.getNext()
126            self.assertEqual([[11,5],[]],res)
127           
128            s=DiscoveryState('123','blah',DummyEnviron,15,'(none)',11,5)
129            res=s.getNext()
130            self.assertEqual([[],[1,10]],res)
131           
132            s=DiscoveryState('123','blah',DummyEnviron,50,'(none)',11,10)
133            res=s.getNext()
134            self.assertEqual([[21,10],[1,10]],res) 
135
136               
137    unittest.main()
138                     
139       
Note: See TracBrowser for help on using the repository browser.