source: mauRepo/HPFos/trunk/src/HPFos/osImpl/myimpl.py @ 8354

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/mauRepo/HPFos/trunk/src/HPFos/osImpl/myimpl.py@8354
Revision 8354, 16.2 KB checked in by mnagni, 7 years ago (diff)

Implemented the bbox query URL (at least for the CEDA_ObservationCollection)

  • Property svn:mime-type set to text/plain
RevLine 
[8346]1'''
[8354]2BSD Licence
3Copyright (c) 2012, Science & Technology Facilities Council (STFC)
4All rights reserved.
5
6Redistribution and use in source and binary forms, with or without modification,
7are permitted provided that the following conditions are met:
8
9    * Redistributions of source code must retain the above copyright notice,
10        this list of conditions and the following disclaimer.
11    * Redistributions in binary form must reproduce the above copyright notice,
12        this list of conditions and the following disclaimer in the documentation
13        and/or other materials provided with the distribution.
14    * Neither the name of the Science & Technology Facilities Council (STFC)
15        nor the names of its contributors may be used to endorse or promote
16        products derived from this software without specific prior written permission.
17
18THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
23OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
[8346]29Created on 5 May 2012
30
[8354]31@author: Maurizio Nagni
[8346]32'''
33from xml.etree.ElementTree import tostring, ElementTree
34from xml.dom import minidom
35from markup.atom.atom import Atom
36from markup.opensearch.os_response import OpenSearchResponse
37from markup.opensearch.osParam import OSParam
38from markup.atom.link import Link
39from markup.opensearch.os_engine import get_mimetype
40from markup.atom.info import Title, Info, Content
41from markup.atom.entry import Entry
42from markup.dc.dc import Date
43from markup.gml.gml import PosList, LinearRing, Exterior, Polygon
44from markup.georss.georss import Where
45from markup.template.html import OSHTMLResponse
46from markup.template.atom import OSAtomResponse
47from datetime import datetime
48from markup.opensearch.osquery import OSQuery
[8354]49from libs.postgisutil import create_st_setSRID
[8346]50 
51COLLECTION = 'collection'
52OBSERVATION = 'observation'
53RESULT = 'result'
[8354]54BBOX = 'box'
[8346]55
[8352]56def calculateStep(**kwargs):
57    step = 20
58    if kwargs['params_values'].has_key('count'):
59        step = int(kwargs['params_values']['count'])
60    return step
61
[8346]62class MyOSAtomResponse(OSAtomResponse):
63    '''
64    classdocs
65    '''
66
67    def __init__(self):
68        #query_params = {"q": "searchTerms", "pw":"startPage"}
69        super(MyOSAtomResponse, self).__init__()
70       
71        '''
72        Constructor
73        '''
74       
75                       
[8352]76    def generateResponse(self, result, queries, ospath, **kwargs):
[8346]77        """
78            @param result: a Result instance
79            @param queries:
80            @param ospath: 
[8354]81            @param kwargs:
[8346]82        """
83        id = ""
84        ospath = self.generateLinkHref(ospath, result.id, self.extension, rel = None)
85       
86        #Generates the ATOM document
87        atomdoc = Atom.createDocument(ospath + "atom", \
88                                      result.title, \
89                                      result.updated)
90       
91        #configuration level
[8352]92        step = calculateStep(**kwargs)
93        root = ElementTree(atomdoc).getroot()
94
[8346]95        #Generate feed's links
[8352]96        self.generateFeedLinks(root, ospath, None, result.totalResult, step)
[8346]97   
98       
99        #Inserts the OpenSearchResponse elements
[8352]100        osdoc = OpenSearchResponse(root)
101        os_totalResults = str(result.totalResult)
[8346]102        os_startIndex = str(0)
103        os_itemsPerPage = str(step)
[8352]104        osdoc.createDocument(totalResults = os_totalResults, startIndex = os_startIndex, itemsPerPage = os_itemsPerPage)
105        for query in queries:                       
106            root.append(query)
[8346]107
[8352]108        self.generateEntries(root, result.subresult, ospath)
[8346]109       
110        reparsed = minidom.parseString(tostring(atomdoc))
111        return reparsed.toprettyxml(indent="  ")
112
113    def generateFeedLinks(self, atomroot, path, linkid = None, total_results = None, step = 0):
114        self.appendAtomLink(atomroot, path, linkid, startIndex = None, rel = Link.REL_SEARCH)
115        self.appendAtomLink(atomroot, path, linkid, 0, Link.REL_SELF)
116        self.appendAtomLink(atomroot, path, linkid, 0, Link.REL_FIRST)
117       
118        if total_results > 2*step:
119            self.appendAtomLink(atomroot, path, linkid, step, Link.REL_NEXT)
120            self.appendAtomLink(atomroot, path, linkid, total_results - (total_results % step), Link.REL_LAST)
121        else:
122            if total_results > step:
123                self.appendAtomLink(atomroot, path, linkid, step, Link.REL_NEXT)                   
124                self.appendAtomLink(atomroot, path, linkid, step, Link.REL_LAST)
125            else:
126                self.appendAtomLink(atomroot, path, linkid, 0, Link.REL_NEXT)                   
127                self.appendAtomLink(atomroot, path, linkid, 0, Link.REL_LAST)                               
128       
129    def generateEntryLinks(self, atomroot, path, linkid = None):
130        self.appendAtomLink(atomroot, path, linkid, startIndex = None, rel = Link.REL_ALTERNATE)
131        self.appendAtomLink(atomroot, path, linkid, startIndex = None, rel = Link.REL_SEARCH)               
132               
133    def appendAtomLink(self, atomroot, path, linkid = None, startIndex = 0, rel = Link.REL_SELF):
134        href = self.generateLinkHref(path, linkid, startIndex, rel)
135        type = get_mimetype(self.extension)
136        if rel == Link.REL_SEARCH:
137            type = get_mimetype('opensearchdescription')           
138        link = Link(href, rel, type)                   
139        atomroot.append(link.buildElement())
140
141    def generateLinkHref(self, path, linkid, startIndex = None, rel = Link.REL_SELF):
142        """
143            @param path: the host URL
144            @param linkid: the search id
145            @param startIndex: the starting index
146            @param rel: a Link type identificator. If None returns a generic ID   
147        """
148        if rel == None:
149            if linkid:
150                return "%s/search/%s/" % (path, linkid)
151            else:
152                return "%s/search/" % (path)
153   
154        if rel == Link.REL_SEARCH:
155            if linkid:
156                return "%s%s/description" % (path, linkid)   
157            else:
158                return "%sdescription" % (path)
159       
160        if rel == Link.REL_ALTERNATE:
161            if linkid:
162                return "%s%s/%s" % (path, linkid, self.extension)
163            else:
164                return "%s%s" % (path, self.extension)
165   
166        if linkid:
167            return "%s%s/%s/?startIndex=%d" % (path, linkid, self.extension, startIndex)
168        else:
169            return "%s%s/?startIndex=%d" % (path, self.extension, startIndex)       
170
171    def generateEntries(self, atomroot, subresults, path):
172        entries = []
173       
174        for subresult in subresults:
175            #Here could loop over results
176            ititle = Title(Info.TEXT_TYPE, subresult.title)
177            icontent = Content(Info.HTML_TYPE, '<b> Search Feed  </b>  \
178                <ul> <li> Title: ASAR Image Mode source packets Level 0 (ASA_IM__0P) </li> \
179             The ASAR Image Mode source packets Level 0 data product offers Level 0 data for possible images processing on an other processing site. It includes some mandatory information for SAR processing. The Image Mode Level 0 product consists of time-ordered Annotated Instrument Source Packets (AISPs) collected while the instrument is in Image Mode. The echo samples contained in the AISPs are compressed to 4 bits/sample using Flexible Block Adaptive Quantisation (FBAQ). This is a high-rate, narrow swath mode so data is only acquired for partial orbit segments and may be from one of seven possible image swaths. The Level 0 product is produced systematically for all data acquired within this mode. This product provides a continuation of the ERS-SAR_RAW product.<li> Abstract: The ASAR Image Mode source packets Level 0 data product offers Level 0 data for possible images processing on an other processing site. It includes some mandatory information for SAR processing. The Image Mode Level 0 product consists of time-ordered Annotated Instrument Source Packets (AISPs) collected while the instrument is in Image Mode. The echo samples contained in the AISPs are compressed to 4 bits/sample using Flexible Block Adaptive Quantisation (FBAQ). This is a high-rate, narrow swath mode so data is only acquired for partial orbit segments and may be from one of seven possible image swaths. The Level 0 product is produced systematically for all data acquired within this mode. This product provides a continuation of the ERS-SAR_RAW product. </li><li> Subject: Radar Imagery, Solid Earth (Tectonics/Seismic Activity), Water (Water Management), Natural Disasters (Oil Slick), Land (Topography/Mapping,Soil,Vegetation) Ocean and Coast (Ocean Currents and Topography,Ocean Waves,Coastal Geomorphology) </li>  \
180               <li> Date: 2002-10-18 to 2012-03-29  \
181                </li> <li> Number of Records: 15945 </ul>')
182            entry = Entry(path + subresult.id + '/' + self.extension, \
183                          ititle.buildElement(), \
184                          subresult.updated, \
185                          published = '2011-01-21T11:05:29.511Z', \
186                           link = [], \
187                           content = icontent.buildElement())
188            xmlentry = entry.buildElement()
189           
190            idate = Date(atomroot, '2002-10-18T08:07:37.387Z/2012-03-29T07:12:20.735Z')       
191            xmlentry.append(idate.buildElement())
192           
193            posList = PosList(atomroot, body = '-90 -180 90 -180 90 180 -90 180 -90 -180', srsDimension = '2')
194            linearRing = LinearRing(atomroot, posList)
195            exterior = Exterior(atomroot, linearRing)
196            polygon = Polygon(atomroot, exterior)
197            where = Where(atomroot, polygon)
198            xmlentry.append(where.buildElement())
199            self.generateEntryLinks(xmlentry, path, subresult.id)
200           
201            entries.append(xmlentry)
202
[8352]203        for entry in entries:
204            atomroot.append(entry)
[8346]205
206class MyOSHTMLResponse(OSHTMLResponse):
207    '''
208    classdocs
209    '''
210
211    def __init__(self):
212        '''
213        Constructor
214        '''
215        super(MyOSHTMLResponse, self).__init__()
216       
[8352]217    def generateResponse(self, result, queries, ospath, **kwargs):
[8346]218        return result + " HTML!"
219       
220class MyOSQuery(OSQuery):
221    '''
222    classdocs
223    '''
224
225    def __init__(self):
226        '''
227            Constructor
228        '''
229        #param_1 = OSParam("q", "searchTerms", namespace = "http://example.com/opensearchextensions/1.0/")       
230        param_1 = OSParam("count", "count")
231        param_2 = OSParam("startPage", "startPage")
232        param_3 = OSParam("startIndex", "startIndex")               
233        param_4 = OSParam("q", "searchTerms")           
234        param_5 = OSParam("uid", "uid", namespace = "http://a9.com/-/opensearch/extensions/geo/1.0/")       
[8354]235        param_6 = OSParam(BBOX, BBOX, namespace = "http://a9.com/-/opensearch/extensions/geo/1.0/")       
[8346]236        param_7 = OSParam("start", "start", namespace = "http://a9.com/-/opensearch/extensions/geo/1.0/")       
237        param_8 = OSParam("stop", "stop", namespace = "http://a9.com/-/opensearch/extensions/time/1.0/")       
238        params = [param_1, param_2, param_3, param_4, param_5, param_6, param_7, param_8]
239        super(MyOSQuery, self).__init__(params)
[8352]240
241    def _packResult(self, results, id = None, **kwargs):
242        subresults = []
243
244        step = calculateStep(**kwargs)
245
246        startIndex = self.indexOffset
247        if kwargs['params_values'].has_key('startIndex'):
248            if int(kwargs['params_values']['startIndex']) < len(results):
249                startIndex = int(kwargs['params_values']['startIndex'])
[8346]250       
[8352]251        startPage = self.pageOffset
252        if kwargs['params_values'].has_key('startPage'):
253            if int(kwargs['params_values']['startPage']) * step < len(results):
254                startPage = int(kwargs['params_values']['startPage'])
255               
256        firstResult = startIndex
257        lastResult = firstResult + step
258
[8353]259        if startPage > 1 and (firstResult + (startPage - 1)*step) <= len(results):
260            firstResult = firstResult + (startPage - 1)*step
[8352]261            if firstResult + step <= len(results):           
262                lastResult = firstResult + step
263            else:
264                lastResult = len(results)
265
266        for result in results[firstResult:lastResult]:
267            result_guid = kwargs['moles3EPB'].retrieveGUIDFromInstance(result)
268            item = Subresult(result_guid.id, "title", datetime.now().isoformat())
269            subresults.append(item)
270       
271        return Result(len(results), subresult = subresults)
272       
273       
[8346]274    def doSearch(self, **kwargs):
[8354]275        ibbox = None
276        if kwargs['params_values'] and kwargs['params_values'].has_key(BBOX):
277            coords = kwargs['params_values'][BBOX].split(',')
278            try:
279                if len(coords) == 4:
280                    ibbox = create_st_setSRID(int(coords[0]),int(coords[1]),int(coords[2]),int(coords[3]))
281            except Exception as e:
282                pass
283       
[8347]284        if kwargs['params_values'] and kwargs['params_values'].has_key(COLLECTION) and kwargs['params_values'].has_key(OBSERVATION):
[8346]285            return self.searchObservation(**kwargs)       
286       
[8347]287        if kwargs['params_values'] and kwargs['params_values'].has_key(COLLECTION):
[8346]288            return self.searchCollection(**kwargs)       
289           
[8354]290        results = kwargs['moles3EPB'].getObservationCollections(bbox = ibbox)
291
292                                 
293               
294       
[8352]295        return self._packResult(results, **kwargs)
[8346]296
297    def searchCollection(self, **kwargs):       
298        obs_coll = kwargs['moles3EPB'].getInstanceFromGUID(kwargs['params_values'][COLLECTION])
299        if obs_coll:
300            obs_coll = kwargs['moles3EPB'].searchSelectiveLoadByInstance(obs_coll, 'member')
301                       
[8352]302        return self._packResult(obs_coll.member, id = kwargs['params_values'][COLLECTION], **kwargs)
[8346]303
304    def searchObservation(self, **kwargs):       
305        observation = kwargs['moles3EPB'].getInstanceFromGUID(kwargs['params_values'][OBSERVATION])
306        if observation:
307            observation = kwargs['moles3EPB'].searchSelectiveLoadByInstance(observation, 'result')
308           
309        print observation
310        '''                       
311        subresults = []
312        for result in obs_coll.member:
313            result_guid = kwargs['moles3EPB'].retrieveGUIDFromInstance(result)
314            item = Subresult(result_guid.id, "title", datetime.now().isoformat())
315            subresults.append(item)
316           
317        result = Result(id = kwargs['params_values'][COLLECTION], subresult = subresults)
318        return result
319        '''
320        return None
321
322class Result(object):
[8352]323    def __init__(self, totalResults, id = None, title = "Discovery feed for Search Services", updated = datetime.now().isoformat(), subresult = []):
[8346]324        '''
325            Constructor
326            @param id: a unique identifier, eventually an URI
327            @param title: an atom.Entry instance
328            @param updated: the last time the record was updated
329            @param subresult: a Subresults array                       
330        '''
[8352]331        self.totalResult = totalResults
[8346]332        self.id = id
333        self.title = title
334        self.updated = updated
335        self.subresult = subresult       
336       
337
338class Subresult(object):
339    def __init__(self, id, title, updated):
340        '''
341            Constructor
342            @param id: a unique identifier, eventually an URI
343            @param title: an atom.Entry instance
344            @param updated: the last time the record was updated                       
345        '''
346        self.id = id
347        self.title = title
348        self.updated = updated
Note: See TracBrowser for help on using the repository browser.