source: mauRepo/HPFos/trunk/hpfos/HPFos/osImpl/myimpl.py @ 8523

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

Requests, parse and display a fatcat atom feed

  • Property svn:mime-type set to text/plain
Line 
1'''
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
29Created on 5 May 2012
30
31@author: Maurizio Nagni
32'''
33from datetime import datetime
34from hpfos.libs.postgisutil import create_st_setSRID
35from ceda_markup.opensearch.osquery import OSQuery
36from ceda_markup.atom.atom import createID, createUpdated,\
37    createPublished, createEntry
38from ceda_markup.atom.info import createTitle, HTML_TYPE, createContent
39from ceda_markup.dc.dc import createDate
40from ceda_markup.gml.gml import createPosList, createLinearRing, createExterior,\
41    createPolygon
42from ceda_markup.georss.georss import createWhere
43from ceda_markup.atom.link import REL_SEARCH, REL_ALTERNATE
44from ceda_markup.opensearch import filter_results, COUNT_DEFAULT,\
45    START_INDEX_DEFAULT, START_PAGE_DEFAULT, create_autodiscovery_link
46from ceda_markup.opensearch.template.osresponse import Result, Subresult
47from ceda_markup.opensearch.template.atom import OSAtomResponse
48from ceda_markup.opensearch.template.html import OSHTMLResponse
49from ea_model.ceda_metadatamodel.ceda_observationcollection.ceda_observationcollection import CEDA_ObservationCollection
50from ea_model.ceda_metadatamodel.ceda_observation.ceda_observation import CEDA_Observation
51from ea_model.ceda_metadatamodel.ceda_result.ceda_result import CEDA_Result
52from ceda_markup.opensearch.os_param import OSParam
53from hpfos import __version__, __revision__
54from ceda_markup.atom.atom import ATOM_NAMESPACE
55from hpfos.HPFos.osImpl.commons import get_document, get_xml_document,\
56    return_not_none_text
57from xml.etree.ElementTree import _ElementInterface, ElementTree
58from ceda_markup.opensearch.os_request import OpenSearchDescription, OS_NAMESPACE
59
60GUID = 'guid'
61COLLECTION = 'collection'
62OBSERVATION = 'observation'
63RESULT = 'result'
64BBOX = 'bbox'
65DUMMY_GUID = 'dummy_guid'
66
67FATCAT_HOST = 'citest1.jc.rl.ac.uk'
68FATCAT_ROOT_PATH = 'fatcatOS'
69
70CEDA_TITLE = 'ceda_title'
71HPFOS_VERSION = __version__
72HPFOS_REVISION = __revision__
73
74HPFOS_ID = ''
75if HPFOS_REVISION != 'REVISION':
76    HPFOS_ID = '(v. %s rev. %s)' % (HPFOS_VERSION, HPFOS_REVISION)
77else:
78    HPFOS_ID = '(v. %s rev. %s)' % (HPFOS_VERSION, 'unknown')
79   
80HPFOS_TITLE = 'Discovery feed for Search Services %s' % (HPFOS_ID)
81
82
83
84class MyOSAtomResponse(OSAtomResponse):
85    '''
86    classdocs
87    '''
88
89    def __init__(self):
90        #query_params = {"q": "searchTerms", "pw":"startPage"}
91        super(MyOSAtomResponse, self).__init__()
92       
93        '''
94        Constructor
95        '''
96
97    def _get_tot_results(self, results):
98        if results is None:
99            return 0
100       
101        if isinstance(results, list):
102            return len(results)
103       
104        return 1
105   
106    def _digest_fatcat_atom(self, context, results):
107        count, start_index, start_page = self._importCountAndPage(context)
108        subresults = results.findall('{%s}entry' % (ATOM_NAMESPACE))
109        tot_results = int(results.find('{%s}totalResults' % (OS_NAMESPACE)).text.replace('\n','').strip())
110        return Result(count, start_index, start_page, tot_results, subresult = subresults, title=HPFOS_TITLE)       
111       
112
113    def digest_search_results(self, results, context):
114        count, start_index, start_page = self._importCountAndPage(context)
115       
116        filtered = None
117        tot_results = 0
118       
119        if type(results) == CEDA_ObservationCollection:
120            filtered = filter_results(results.member, count, start_index, start_page)
121            tot_results = self._get_tot_results(results.member)
122        elif type(results) == CEDA_Observation:
123            #to be done
124            filtered = filter_results(results.result, count, start_index, start_page)
125            tot_results = self._get_tot_results(results.result)
126        elif type(results) == CEDA_Result:
127            filtered = filter_results(results.result, count, start_index, start_page)
128            tot_results = 1 
129        elif isinstance(results, _ElementInterface):
130            return self._digest_fatcat_atom(context, results)                                 
131        else:
132            filtered = filter_results(results, count, start_index, start_page)
133            tot_results = self._get_tot_results(results)
134             
135        if filtered is None:
136            return Result(count, start_index, start_page, tot_results, subresult = [])
137             
138        subresults = []
139        for result in filtered:
140            item = None         
141            result_guid = context['moles3EPB'].retrieveGUIDFromInstance(result)
142            if result_guid is None:
143                continue
144            ititle = self._extractTitle(result)
145            item = Subresult(result_guid.id, ititle, datetime.now().isoformat(), description = result.description)               
146            subresults.append(item)
147       
148       
149        return Result(count, start_index, start_page, tot_results, subresult = subresults, title=HPFOS_TITLE)
150       
151    def generateEntryLinks(self, entry, atomroot, path, linkid = None):
152        entry.append(create_autodiscovery_link(atomroot, path, self.extension, linkid, None, rel = REL_ALTERNATE))
153        entry.append(create_autodiscovery_link(atomroot, path, self.extension, linkid, None, rel = REL_SEARCH))               
154
155    def generate_entries(self, atomroot, subresults, path):
156        if isinstance(subresults, list) \
157                and len(subresults) > 0 \
158                and isinstance(subresults[0], _ElementInterface):
159            for entry in subresults:
160                atomroot.append(entry)
161            return
162       
163        entries = []
164       
165        for subresult in subresults:
166            #Here could loop over results
167            atomID = createID(path + subresult.id + '/' + self.extension, root = atomroot)
168            ititle = createTitle(root = atomroot, body = subresult.title, itype = HTML_TYPE)
169            atomContent = createContent(root = atomroot, body = subresult.description, itype = HTML_TYPE)
170            atomUpdated = createUpdated(subresult.updated, root = atomroot)
171            atomPublished = createPublished('TO_BE_DONE_2011-01-21T11:05:29.511Z', root = atomroot)           
172            entry = createEntry(atomID, ititle, atomUpdated,
173                                published=atomPublished,
174                                content=atomContent, root = atomroot)
175            #xmlentry = entry.buildElement()
176           
177            idate = createDate(root = atomroot,
178                               body = 'TO_BE_DONE_2002-10-18T08:07:37.387Z/2012-03-29T07:12:20.735Z')       
179            entry.append(idate)
180           
181            posList = createPosList(root = atomroot, body = '-90 -180 90 -180 90 180 -90 180 -90 -180', srsDimension = '2')
182            linearRing = createLinearRing(root = atomroot, body = posList)
183            exterior = createExterior(root = atomroot, body = linearRing)
184            polygon = createPolygon(root = atomroot, body = exterior)
185            where = createWhere(root = atomroot, body = polygon)
186            entry.append(where)
187            self.generateEntryLinks(entry, atomroot, path, subresult.id)           
188            entries.append(entry)
189
190        for entry in entries:
191            atomroot.append(entry)
192
193    def _importCountAndPage(self, context):       
194        count = COUNT_DEFAULT
195        start_index = START_INDEX_DEFAULT
196        start_page = START_PAGE_DEFAULT
197       
198        try:
199            count = int(context['count'])
200        except:
201            pass       
202       
203        try:
204            start_index = int(context['startIndex'])
205        except:
206            pass
207       
208        try:
209            start_page = int(context['startPage'])
210        except:
211            pass
212       
213        return count, start_index, start_page
214
215    def _extractTitle(self, cedaObj):
216        if hasattr(cedaObj, 'identifier'):
217            for ident in cedaObj.identifier:
218                if ident.authority.title == CEDA_TITLE:
219                    return ident.code 
220
221class MyOSHTMLResponse(OSHTMLResponse):
222    '''
223    classdocs
224    '''
225
226    def __init__(self):
227        '''
228        Constructor
229        '''
230        super(MyOSHTMLResponse, self).__init__()
231       
232    def generateResponse(self, result, queries, ospath, **kwargs):
233        return result + " HTML!"
234       
235class MyOSQuery(OSQuery):
236    '''
237    classdocs
238    '''
239
240    def __init__(self):
241        '''
242            Constructor
243        '''
244        #param_1 = OSParam("q", "searchTerms", namespace = "http://example.com/opensearchextensions/1.0/")       
245        param_1 = OSParam("count", "count")
246        param_2 = OSParam("startPage", "startPage")
247        param_3 = OSParam("startIndex", "startIndex")               
248        param_4 = OSParam("q", "searchTerms")           
249        param_5 = OSParam("uid", "uid", namespace = "http://a9.com/-/opensearch/extensions/geo/1.0/")       
250        param_6 = OSParam(BBOX, BBOX, namespace = "http://a9.com/-/opensearch/extensions/geo/1.0/")       
251        param_7 = OSParam("start", "start", namespace = "http://a9.com/-/opensearch/extensions/geo/1.0/")       
252        param_8 = OSParam("stop", "stop", namespace = "http://a9.com/-/opensearch/extensions/time/1.0/")       
253        params = [param_1, param_2, param_3, param_4, param_5, param_6, param_7, param_8]
254        super(MyOSQuery, self).__init__(params)
255       
256    def do_search(self, context):
257        ibbox = None
258        if context is not None and context.has_key(BBOX) and context[BBOX] is not None:
259            coords = context[BBOX].split(',')
260            try:
261                if len(coords) == 4:
262                    ibbox = create_st_setSRID(int(coords[0]),int(coords[1]),int(coords[2]),int(coords[3]))
263            except:
264                pass
265       
266        if not context.has_key(GUID) or context[GUID] is None:
267            return context['moles3EPB'].getObservationCollections(bbox = ibbox)       
268             
269        obj = context['moles3EPB'].getInstanceFromGUID(context[GUID])   
270        if obj is None:
271            return None
272        if type(obj) == CEDA_ObservationCollection:
273            return context['moles3EPB'].searchSelectiveLoadByInstance(obj, 'member') #need to add bbox & phenomTime
274        elif type(obj) == CEDA_Observation:
275            #return context['moles3EPB'].searchSelectiveLoadByInstance(obj, 'result') #need to add bbox & phenomTime
276            for source in obj.result.source:
277                if source.function == 'search':
278                    return self._extractFatcatEntities(source.description)
279
280       
281    def _extractFatcatEntities(self, fc_resource_id):
282        path = '/%s/search/%s/atom/' % (FATCAT_ROOT_PATH, str(fc_resource_id))
283        return find_fatcat_atom_entity(host = FATCAT_HOST, path = path)
284   
285def find_fatcat_atom_entity(host = 'localhost', path = '', port = 80):   
286    source = get_document(host, path, port)
287    return get_xml_document(source)
Note: See TracBrowser for help on using the repository browser.