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

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

Improve look and feel of UI with tweaks to css + fix radio button
on search panel - set this explicitly as an input since htmlfill
doesn't handle the radio button defaults well + simplify template
logic for semantic search results + fix constraint summary string.

Line 
1from paste.request import parse_querystring
2from milk_server.lib.Utilities import getURLConstraints
3import cgi,urllib
4
5   
6def getURLFormattedConstraints(environ, **kw):
7    '''
8    Get the constraints in a url friendly string - modified by the keyword arguments
9    offset and stride which are to be part of the querystring
10    @param environ: wsgi environ object
11    @return constraints in a url friendly string
12    '''
13    args = dict(parse_querystring(environ))
14
15    constrained = kw.get('constrained')
16    if not constrained:
17        offset, stride = kw.get('offset'), kw.get('stride')
18        if offset:
19            args['start'] = offset
20        if stride:
21            args['howmany'] = stride
22
23    q = ''
24    for i in args:
25        # NB, the constraints may already be encoded as a hidden variable
26        if i != 'constraints':
27            q+='%s=%s&'%(i,args[i])
28
29    # add constraints last to avoid duplicate params - NB, constraint params
30    # can be overridden by direct inputs to the page
31    if 'constraints' in args:
32        constraints = getURLConstraints(args['constraints'])
33        for key, val in constraints.items():
34            if key not in args:
35                q+='%s=%s&'%(key, val)
36
37    return q[0:-1]
38
39
40def getURL(environ, **kw):
41    '''
42    Get a url from the wsgi environment
43    @param environ: wsgi environ object
44    @return url with constraints added from wsgi environ
45    '''
46    constraints = getURLFormattedConstraints(environ, **kw)
47    return urllib.quote(environ.get('SCRIPT_NAME','')) + \
48        urllib.quote(environ.get('PATH_INFO','')) + '?' + constraints
49
50
51class constraints:
52    '''
53    A container object for constraints on a search
54    '''
55    def __init__(self, **kw):
56        self.values={}
57        keys=['dateRange','bbox','scope','textTarget','searchString','geoSearchType']
58        for key in keys:
59            self.values[key]=None
60        for k in kw: 
61            self[k]=kw[k]
62           
63           
64    def __setitem__(self, key, value):
65        if key in self.values:
66            self.values[key]=value
67        else:
68            raise ValueError('Unknown key [%s] in constraints')
69
70   
71    def __getitem__(self,key):
72        if key in self.values: 
73            return self.values[key]
74        else:
75            raise ValueError('Unknown key [%s] in constraints'%key)
76
77   
78    def __str__(self):
79        c=''
80        if self.values['dateRange'] is not None:
81            dr = self.values['dateRange'] 
82            c += 'Date range: %s to %s'%('%s/%s/%s'%dr[0],'%s/%s/%s'%dr[1])
83        bbox=self.values['bbox']
84        if c:
85            c += ', '
86
87        c += 'Bounding box: '
88        if bbox is None or bbox==['90.0','-180.0','180.0','-90.0']:
89            c+='Global'
90        else:
91            overlaps = self.values['geoSearchType'] or 'overlaps'
92            c+='%s latitude %s to %sN and longitude %s to %sE' \
93                %(overlaps,bbox[3],bbox[0],bbox[1],bbox[2])
94               
95        if self.values['scope']:
96            if c:
97                c += ', ' 
98            c += 'Scope: %s'%self.values['scope']
99        if self.values['textTarget']:
100            if c:
101                c += ', ' 
102            c += 'Target: %s'%self.values['textTarget']
103        return c
104
105
106class PagerState:
107    '''
108    Object to hold the current page state of the displayed results - e.g. which
109    page number and how many records, before and after those displayed, are available
110    '''
111   
112    def __init__(self, hits, environ, offset=1, stride=10, defaultStride = 10):
113        '''
114        Initialise PagerState object
115        @param hits: total number of records available to view
116        @param environ: wsgi environ object   
117        @keyword offset: offset being used in the currently displayed record set
118        - i.e. the array number of the topmost record displayed. Default = 1
119        @keyword stride: Number of records currently visible.  Default = 10
120        @keyword defaultStride: Standard number of records to display on a page.
121        Default = 10
122        '''
123        self.hits = hits
124        self.offset = offset
125        self.stride = stride
126
127        self.previousPageURL = None
128        self.previousNumber = None
129        self.startPageURL = None
130        self.nextPageURL = None
131        self.nextNumber = None
132        self.lastPageURL = None
133       
134        self.defaultStride = defaultStride
135       
136        n, p = self.getNext()
137        start, end = "", ""
138        if p:
139            self.previousPageURL = getURL(environ, offset = p[0], stride = p[1])
140            self.previousNumber = p[1]
141            self.startPageURL = getURL(environ, offset = 1, stride = self.defaultStride)
142        if n:
143            self.nextPageURL = getURL(environ, offset = n[0], stride = n[1])
144            self.nextNumber = n[1]
145            off = self.hits - self.defaultStride + 1
146            if off < 1:
147                off = 1
148            self.lastPageURL = getURL(environ, offset = off, stride = self.defaultStride)
149           
150        self.upperRange = self.offset + self.stride - 1
151        self.lowerRange = self.offset
152       
153   
154    def getNext(self):
155        '''
156        Get info on what number of records are available on current page
157        @return result - list with format [[offSetForNextPage, numberOfRecordsOnNextPage],
158                                           [offSetForLastPage, numberOfRecordsOnLastPage]]
159        '''
160        result=[]
161        if self.offset+self.stride < self.hits:
162            #there are more to look at
163            r = [self.offset+self.stride, self.stride]
164            if r[0]+r[1]-1 > self.hits: 
165                r[1] = self.hits+1-r[0]
166            result.append(r)
167        else:
168            result.append([])
169           
170        if self.offset > 1:
171            #there are previous records
172            b = max(self.stride, self.defaultStride)
173            r = [self.offset-b,b]
174            if r[0] < 1: 
175                r[0] = 1
176            if r[1] > self.hits: 
177                r[1] = self.hits
178            result.append(r)
179        else: 
180            result.append([])
181        return result
182       
183   
184
185class DiscoveryState:
186    ''' This class holds the state associated with a search (including presenting multiple slices
187    of a large result set) '''
188    def __init__(self,sessionID,searchString,environ,hits,constraints,offset=1,stride=10):
189        ''' On instantiation, provide
190                the backend sessionID
191                the application URL that produced this query
192                the stride through the result set '''
193        self.environ=environ # the wsgi environment
194        self.constraintsInstance=constraints
195        self.constraints=str(constraints) # some text to show constraints on search
196        self.urlformattedconstraints = getURLFormattedConstraints(self.environ)
197        self.sessID=sessionID
198        self.hits=hits
199
200        self.searchString=searchString
201        self.alternatives=None
202        self.constrainedurl = getURL(self.environ, constrained=1)+'&constrained'
203        self.pager = PagerState(hits, self.environ, offset=offset, stride=stride)
204       
205    def __str__(self):
206        return '''
207___ Discovery State ___
208searchString: %s
209constraints: %s
210sessionID: %s
211hits: %s
212offset,stride: %s,%s
213environment: %s
214========================
215'''%(self.searchString,self.constraints,self.sessID,self.hits,self.offset,self.stride,self.environ)
Note: See TracBrowser for help on using the repository browser.