Changeset 8505


Ignore:
Timestamp:
10/08/12 14:00:34 (7 years ago)
Author:
mnagni
Message:

Incomplete - # 22540: The pagination links provided in the feed do not appear to be working correctly
 http://team.ceda.ac.uk/trac/ceda/ticket/22540

Location:
mauRepo/HPFos/trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • mauRepo/HPFos/trunk/.pydevproject

    r8500 r8505  
    1111<value>hpfos.HPFos.settings</value> 
    1212</pydev_variables_property> 
     13 
    1314<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH"> 
    1415<path>/HPFos</path> 
  • mauRepo/HPFos/trunk/hpfos/HPFos/moles3epb.py

    r8500 r8505  
    3434from ea_model.ceda_metadatamodel.ceda_observationcollection.ceda_observationcollection import CEDA_ObservationCollection 
    3535from ea_model.ceda_metadatamodel.ceda_observation.ceda_observation import CEDA_Observation 
    36 from ea_model.iso_19115_2006_metadata_corrigendum.reference_system_information.md_identifier import MD_Identifier 
    37 from ea_model.iso_19115_2006_metadata_corrigendum.citation_and_responsible_party_information.ci_citation import CI_Citation 
    3836from ea_model.moles3_4.observationcollection.mo_observationcollection import MO_ObservationCollection 
    3937from ea_model.moles3_4.observation.mo_observation import MO_Observation 
    40 from ea_model.ceda_metadatamodel.ceda_project.ceda_project import CEDA_Project 
    4138from sqlalchemy import Table, Column, ForeignKey, Integer, String 
    4239from sqlalchemy.orm import mapper 
     
    6966        self._dbManager.metadata.create_all() 
    7067 
    71     def _initSearchIndexes(self): 
    72         #To Be Done - CHECK IF THE COLUMN ALREADY EXISTS! 
    73         # We don't want sqlalchemy to know about this column so we add it externally. 
    74         try: 
    75             self._dbManager.engine.execute("alter table md_identifier add column code_search_vector tsvector")                  
    76  
    77             # This indexes the tsvector column 
    78  
    79             self._dbManager.engine.execute("create index md_identifier_code_search_index on md_identifier using gin(code_search_vector)") 
    80  
    81             # This sets up the trigger that keeps the tsvector column up to date. 
    82             self._dbManager.engine.execute("create trigger md_identifier_code_search_update before update or insert on md_identifier \ 
    83                 for each row execute procedure tsvector_update_trigger('code_search_vector', 'pg_catalog.english', code)")                         
    84         except Exception as e: 
    85             pass 
    86  
    8768    def _getSession(self): 
    8869        if self._dbManager is not None: 
     
    10283         
    10384    def close(self): 
    104         return self._session.close()         
    105          
    106     def getObjectsByGE(self, class_type): 
    107         """ 
    108             Checks if a CEDA_Collection contains a given CEDA_Observation. 
    109             @param obs_coll_id: the CEDA_ObservationColleciton id 
    110             @param obs_id: the CEDA_Observation id 
    111             @return: True if the collection contains the given observation, False otherwise   
    112         """ 
    113         if isinstance(class_type, type(CEDA_ObservationCollection)) or isinstance(class_type, type(CEDA_Observation)): 
    114             return self._session.query(class_type).all() 
    115         return None                      
    116          
    117     def getObservationCollections(self, bbox = None): 
     85        return self._session.close()                           
     86         
     87    def getObservationCollections(self, bbox = None, keywords = '*'): 
    11888        """ 
    11989            Returns the stored CEDA_ObservationCollection eventually filtering them against a postgis goemetry 
     
    12292        """ 
    12393         
    124         collections = self._session.query(CEDA_ObservationCollection)     
     94        collections = self._session.query(CEDA_ObservationCollection) 
     95        res = []  
     96        #collections = self._extract_observation_collection_by_title_keywords(keywords) 
     97        if collections is None: 
     98            return res    
    12599        if bbox == None: 
    126100            return collections.all() 
    127101         
    128         res = [] 
     102 
    129103        for collection in collections: 
    130104            if len(collection.geographicExtent) > 0: 
     
    161135                return self.search(CEDA_ObservationCollection, ceda_guid.ceda_observationcollection) 
    162136        return None 
    163      
    164      
    165     def getObservationFromObservationCollection(self, obs_coll_id): 
    166         """ 
    167             Checks if a CEDA_Collection contains a given CEDA_Observation. 
    168             @param obs_coll_id: the CEDA_ObservationColleciton id 
    169             @return: the associated CEDA_Observation   
    170         """ 
    171         return self._session.query(CEDA_ObservationCollection, CEDA_Observation).filter(CEDA_ObservationCollection.id==obs_coll_id).all() 
    172  
    173     def extractObservationByTitleKeywords(self, keywords): 
    174         """ 
    175             Loooks for CEDA_Observation containing a specific title (observation.identifier.code) 
    176             @param keywords: a space separated terms string 
    177             @return: a tuple containing a CEDA_Observation satisfying the queryllection.idenfitier element having the title   
     137 
     138    def _extract_observation_collection_by_title_keywords(self, keywords): 
     139        """ 
     140            Loooks for CEDA_ObservationCollection containing a specific title (observationCollection.identifier.code) 
     141            @param keywords: a space separated terms string   
    178142        """                 
    179143        # search_vector is a ts_vector column. To search for terms, you use the  
     
    181145        # used with @@. So this adds a where clause like "WHERE search_vector  
    182146        # @@ plaint_tsquery(<search string>)" 
    183         q = self._session.query(CEDA_Observation). \ 
    184             join(MO_Observation).join(MO_ObservationCollection.identifier). \ 
     147        q = self._session.query(CEDA_ObservationCollection). \ 
     148            join(MO_ObservationCollection).join(MO_Observation.identifier). \ 
    185149            filter('md_identifier.code_search_vector @@ to_tsquery(:terms)') 
    186150        # This binds the :terms placeholder to the searchterms string. User input  
    187151        # should always be put into queries this way to prevent SQL injection. 
    188152        q = q.params(terms=keywords) 
    189         return q 
    190153 
    191154    def search(self, clazz, inst_key): 
  • mauRepo/HPFos/trunk/hpfos/HPFos/osImpl/myimpl.py

    r8500 r8505  
    3131@author: Maurizio Nagni 
    3232''' 
    33 from xml.dom import minidom 
    3433from datetime import datetime 
    3534from hpfos.libs.postgisutil import create_st_setSRID 
    3635from ceda_markup.opensearch.osquery import OSQuery 
    37 from ceda_markup.opensearch.osParam import OSParam 
    3836from ceda_markup.atom.atom import createID, createUpdated,\ 
    39     createPublished, createAtomDocument, createEntry 
     37    createPublished, createEntry 
    4038from ceda_markup.atom.info import createTitle, HTML_TYPE, createContent 
    4139from ceda_markup.dc.dc import createDate 
     
    4341    createPolygon 
    4442from ceda_markup.georss.georss import createWhere 
    45 from ceda_markup.atom.link import REL_SEARCH, REL_SELF, REL_FIRST, REL_NEXT,\ 
    46     REL_LAST, REL_ALTERNATE 
    47 from ceda_markup.opensearch.os_response import createOpenSearchRespose 
    48 from ceda_markup.opensearch import filterResults, COUNT_DEFAULT,\ 
    49     START_INDEX_DEFAULT, START_PAGE_DEFAULT, createAutodiscoveryLink,\ 
    50     generateAutodiscoveryPath 
    51 from ceda_markup.opensearch.template.osresponse import Result 
    52 from xml.etree.ElementTree import tostring 
     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 
    5347from ceda_markup.opensearch.template.atom import OSAtomResponse 
    5448from ceda_markup.opensearch.template.html import OSHTMLResponse 
     
    5650from ea_model.ceda_metadatamodel.ceda_observation.ceda_observation import CEDA_Observation 
    5751from ea_model.ceda_metadatamodel.ceda_result.ceda_result import CEDA_Result 
     52from ceda_markup.opensearch.os_param import OSParam 
    5853 
    5954GUID = 'guid' 
     
    9085        return 1 
    9186 
    92     def digestSearchResults(self, results, context):  
    93         count, startIndex, startPage = self._importCountAndPage(context) 
     87    def digest_search_results(self, results, context):  
     88        count, start_index, start_page = self._importCountAndPage(context) 
    9489         
    9590        filtered = None 
     
    9792         
    9893        if type(results) == CEDA_ObservationCollection: 
    99             filtered = filterResults(results.member, count, startIndex, startPage) 
     94            filtered = filter_results(results.member, count, start_index, start_page) 
    10095            tot_results = self._get_tot_results(results.member) 
    10196        elif type(results) == CEDA_Observation: 
    10297            #to be done 
    103             filtered = filterResults(results.result, count, startIndex, startPage) 
     98            filtered = filter_results(results.result, count, start_index, start_page) 
    10499            tot_results = self._get_tot_results(results.result)         
    105100        else: 
    106             filtered = filterResults(results, count, startIndex, startPage) 
     101            filtered = filter_results(results, count, start_index, start_page) 
    107102            tot_results = self._get_tot_results(results) 
    108103               
    109104        if filtered is None: 
    110             return Result(count, startIndex, startPage, tot_results, subresult = [])  
     105            return Result(count, start_index, start_page, tot_results, subresult = [])  
    111106               
    112107        subresults = [] 
     
    118113                    continue 
    119114                ititle = self._extractTitle(result) 
    120                 item = Subresult(result_guid.id, ititle, result.description,  datetime.now().isoformat()) 
     115                item = Subresult(result_guid.id, ititle, datetime.now().isoformat(), description = result.description) 
    121116            else:     
    122                 item = Subresult(DUMMY_GUID, 'dummy_resultTitle', 'dummy_resultDescription',  datetime.now().isoformat()) 
     117                item = Subresult(DUMMY_GUID, 'dummy_resultTitle', datetime.now().isoformat(), description = 'dummy_resultDescription') 
    123118            subresults.append(item) 
    124119         
    125         return Result(count, startIndex, startPage, tot_results, subresult = subresults) 
    126                          
    127     def generateResponse(self, results, queries, osHostURL, context): 
    128         ospath = generateAutodiscoveryPath(osHostURL, None, self.extension, rel = None) 
    129          
    130         #Generates the ATOM document 
    131         atomdoc = createAtomDocument(ospath + "atom", results.title, results.updated) 
    132  
    133         #Generate feed's links 
    134         self.generateFeedLinks(atomdoc, ospath, None, results.totalResult, results.count) 
    135          
    136         #Inserts the OpenSearchResponse elements 
    137         createOpenSearchRespose(atomdoc, results.totalResult, results.startIndex, results.count, queries) 
    138         self.generateEntries(atomdoc, results.subresult, ospath) 
    139          
    140         reparsed = minidom.parseString(tostring(atomdoc)) 
    141         return reparsed.toprettyxml(indent="  ") 
    142  
    143     def generateFeedLinks(self, atomroot, path, linkid = None, total_results = None, step = 0): 
    144         atomroot.append(createAutodiscoveryLink(atomroot, path, self.extension, \ 
    145                                                 linkid, startIndex = None, rel = REL_SEARCH))         
    146         atomroot.append(createAutodiscoveryLink(atomroot, path, self.extension, \ 
    147                                                 linkid, startIndex = 0, rel = REL_SELF))         
    148         atomroot.append(createAutodiscoveryLink(atomroot, path, self.extension, \ 
    149                                                 linkid, startIndex = 0, rel = REL_FIRST)) 
    150          
    151         if total_results > 2*step: 
    152             atomroot.append(createAutodiscoveryLink(atomroot, path, self.extension, \ 
    153                                                     linkid, step, rel = REL_NEXT)) 
    154             atomroot.append(createAutodiscoveryLink(atomroot, path, self.extension, \ 
    155                                                     linkid, total_results - (total_results % step), rel = REL_LAST)) 
    156         else: 
    157             if total_results > step: 
    158                 atomroot.append(createAutodiscoveryLink(atomroot, path, self.extension, \ 
    159                                                         linkid, step, rel = REL_NEXT))                     
    160                 atomroot.append(createAutodiscoveryLink(atomroot, path, self.extension, \ 
    161                                                         linkid, step, rel = REL_LAST)) 
    162             else: 
    163                 atomroot.append(createAutodiscoveryLink(atomroot, path, self.extension, \ 
    164                                                         linkid, 0, rel = REL_NEXT))                                   
    165                 atomroot.append(createAutodiscoveryLink(atomroot, path, self.extension, \ 
    166                                                         linkid, step, rel = REL_LAST))                                  
     120        return Result(count, start_index, start_page, tot_results, subresult = subresults) 
    167121         
    168122    def generateEntryLinks(self, entry, atomroot, path, linkid = None): 
    169         entry.append(createAutodiscoveryLink(atomroot, path, self.extension, linkid, None, rel = REL_ALTERNATE)) 
    170         entry.append(createAutodiscoveryLink(atomroot, path, self.extension, linkid, None, rel = REL_SEARCH))                 
    171  
    172     def generateEntries(self, atomroot, subresults, path): 
     123        entry.append(create_autodiscovery_link(atomroot, path, self.extension, linkid, None, rel = REL_ALTERNATE)) 
     124        entry.append(create_autodiscovery_link(atomroot, path, self.extension, linkid, None, rel = REL_SEARCH))                 
     125 
     126    def generate_entries(self, atomroot, subresults, path): 
    173127        entries = [] 
    174128         
     
    203157    def _importCountAndPage(self, context):         
    204158        count = COUNT_DEFAULT 
    205         startIndex = START_INDEX_DEFAULT 
    206         startPage = START_PAGE_DEFAULT 
     159        start_index = START_INDEX_DEFAULT 
     160        start_page = START_PAGE_DEFAULT 
    207161         
    208162        try:  
     
    212166         
    213167        try:  
    214             startIndex = int(context['startIndex']) 
     168            start_index = int(context['startIndex']) 
    215169        except: 
    216170            pass 
    217171         
    218172        try:  
    219             startPage = int(context['startPage']) 
     173            start_page = int(context['startPage']) 
    220174        except: 
    221175            pass 
    222176         
    223         return count, startIndex, startPage 
     177        return count, start_index, start_page 
    224178 
    225179    def _extractTitle(self, cedaObj): 
     
    264218        super(MyOSQuery, self).__init__(params) 
    265219         
    266     def doSearch(self, context): 
     220    def do_search(self, context): 
    267221        ibbox = None 
    268222        if context is not None and context.has_key(BBOX) and context[BBOX] is not None: 
     
    284238        elif type(obj) == CEDA_Observation: 
    285239            return context['moles3EPB'].searchSelectiveLoadByInstance(obj, 'result') #need to add bbox & phenomTime 
    286          
    287  
    288 class Subresult(object): 
    289     def __init__(self, iid, title, description, updated): 
    290         ''' 
    291             Constructor 
    292             @param id: a unique identifier, eventually an URI 
    293             @param title: an atom.Entry instance  
    294             @param updated: the last time the record was updated                         
    295         ''' 
    296         self.id = iid 
    297         self.title = title 
    298         self.description = description         
    299         self.updated = updated 
  • mauRepo/HPFos/trunk/hpfos/HPFos/view/view.py

    r8500 r8505  
    6262    hostURL = _buildHostURL(request) 
    6363    ospath = _buildDescriptionOsPath(hostURL, collection_guid, observation_guid, result_guid) 
    64     response = os_engine.getDescription(ospath) 
     64    response = os_engine.get_description(ospath) 
    6565    context = {} 
    6666    context['response'] = mark_safe(response) 
     
    6969def _doSearch(request, iformat, guid = None, result_guid = None): 
    7070    hostURL = _buildHostURL(request)    
    71     context = os_engine.createQueryDictionary() 
     71    context = os_engine.create_query_dictionary() 
    7272    if request.GET is not None: 
    7373        for param in request.GET.iteritems(): 
     
    8080    context['moles3EPB'] = request.moles3EPB 
    8181 
    82     response = os_engine.doSearch(hostURL, iformat, context) 
     82    response = os_engine.do_search(hostURL, iformat, context) 
    8383     
    8484    context = {} 
  • mauRepo/HPFos/trunk/hpfos/tests/__init__.py

    r8354 r8505  
     1from unittest import TestSuite 
     2from hpfos.tests.testos import TestOS 
     3 
     4def suite(): 
     5    suite = TestSuite() 
     6    suite.addTest(TestOS)        
     7             
     8    return suite 
  • mauRepo/HPFos/trunk/hpfos/tests/testos.py

    r8500 r8505  
    3333from hpfos.HPFos.view.view import getDescription, doSearchL0 
    3434from hpfos.tests.testsetup import HPFosTest 
     35from hpfos.HPFos.osImpl.myimpl import MyOSAtomResponse 
     36from ceda_markup.opensearch.template.osresponse import Subresult, Result 
     37from ceda_markup.opensearch.query import create_query 
    3538 
    3639 
    3740class TestOS(HPFosTest): 
    3841 
    39     def testDescription(self): 
     42    def description_test(self): 
    4043        get_request = self.reqFactory.get('/description/') 
    4144        res = getDescription(request = get_request) 
    4245        print res         
    4346 
    44     def testSearch(self): 
     47    def search_test(self): 
    4548        iformat = 'atom' 
    4649        get_request = self.reqFactory.get('/atom/search', {'count': '3'}) 
     
    4952        print res 
    5053 
    51     def testOS(self):         
    52         self.testDescription() 
    53         self.testSearch() 
     54    def create_query_test(self): 
     55        context = self._generate_context()   
     56        query = create_query('atom', self.os_engine.os_query.params_model, context) 
     57        print query 
     58        return query 
     59     
     60    def generate_reponse_test(self): 
     61        ar = MyOSAtomResponse() 
     62        context = self._generate_context()         
     63        queries = self.create_query_test() 
     64         
     65        result = self._generate_results(count=7, start_index=3, start_page=1, tot_results=40) 
     66        response = ar.generate_response(result, queries, '', context) 
     67        self.assertTrue('<link href="/search/atom/?startIndex=3" rel="self" type="application/atom+xml"/>' in response, "Error") 
     68        self.assertTrue('<link href="/search/atom/?startIndex=1" rel="first" type="application/atom+xml"/>' in response, "Error") 
     69        self.assertTrue('<link href="/search/atom/?startIndex=10" rel="next" type="application/atom+xml"/>' in response, "Error") 
     70        self.assertTrue('<link href="/search/atom/?startIndex=38" rel="last" type="application/atom+xml"/>' in response, "Error") 
     71         
     72        result = self._generate_results(count=10, start_index=5, start_page=1, tot_results=20) 
     73        response = ar.generate_response(result, queries, '', context) 
     74        self.assertTrue('<link href="/search/atom/?startIndex=5" rel="self" type="application/atom+xml"/>' in response, "Error") 
     75        self.assertTrue('<link href="/search/atom/?startIndex=1" rel="first" type="application/atom+xml"/>' in response, "Error") 
     76        self.assertTrue('<link href="/search/atom/?startIndex=15" rel="next" type="application/atom+xml"/>' in response, "Error") 
     77        self.assertTrue('<link href="/search/atom/?startIndex=15" rel="last" type="application/atom+xml"/>' in response, "Error") 
    5478 
     79        result = self._generate_results(count=2, start_index=2, start_page=1, tot_results=5)                 
     80        response = ar.generate_response(result, queries, '', context) 
     81        self.assertTrue('<link href="/search/atom/?startIndex=2" rel="self" type="application/atom+xml"/>' in response, "Error") 
     82        self.assertTrue('<link href="/search/atom/?startIndex=1" rel="first" type="application/atom+xml"/>' in response, "Error") 
     83        self.assertTrue('<link href="/search/atom/?startIndex=4" rel="next" type="application/atom+xml"/>' in response, "Error") 
     84        self.assertTrue('<link href="/search/atom/?startIndex=4" rel="last" type="application/atom+xml"/>' in response, "Error") 
     85 
     86        result = self._generate_results(count=1, start_index=18, start_page=1, tot_results=20)                 
     87        response = ar.generate_response(result, queries, '', context) 
     88        self.assertTrue('<link href="/search/atom/?startIndex=18" rel="self" type="application/atom+xml"/>' in response, "Error") 
     89        self.assertTrue('<link href="/search/atom/?startIndex=1" rel="first" type="application/atom+xml"/>' in response, "Error") 
     90        self.assertTrue('<link href="/search/atom/?startIndex=19" rel="next" type="application/atom+xml"/>' in response, "Error") 
     91        self.assertTrue('<link href="/search/atom/?startIndex=20" rel="last" type="application/atom+xml"/>' in response, "Error")         
     92 
     93 
     94    def _generate_results(self, count=1, start_index=0, start_page=1, tot_results=20):             
     95        subresults = []     
     96        for index in range(tot_results): 
     97            subresults.append(Subresult('id_%s' % (str(index)), \ 
     98                      'title_%s' % (str(index)) , \ 
     99                      description = 'description_%s' % (str(index))))          
     100        return Result(count, start_index, start_page, tot_results, subresult = subresults) 
     101     
     102     
     103    def _generate_context(self, count='1', start_index='0', start_page='1'): 
     104        context = {} 
     105        context['count'] = count 
     106        context['startIndex'] = start_index 
     107        context['startPage'] = start_page 
     108        return context  
  • mauRepo/HPFos/trunk/hpfos/tests/testsetup.py

    r8500 r8505  
    2525                             
    2626        self.epbRepo = HPFosTest.epbRepo 
    27         HPFosTest.osEngine = setUp() 
     27        self.os_engine = setUp() 
    2828        environ = { 
    2929            'SERVER_NAME': 'fatcat.badc.rl.ac.uk', 
  • mauRepo/HPFos/trunk/resources/requirements.txt

    r8466 r8505  
    77# --extra-index-url http://ciprod1.cems.rl.ac.uk/pip 
    88# to your pip install  
    9 ceda-markup==0.0.6 
     9ceda-markup==0.0.7 
    1010ceda-moles-model==0.1.5 
    1111 
Note: See TracChangeset for help on using the changeset viewer.