Changeset 1955 for TI07-MOLES/trunk


Ignore:
Timestamp:
04/01/07 21:33:04 (13 years ago)
Author:
lawrence
Message:

More improvements to wsgi discovery, some unit tests, improved
namespace handling in DIF.py ...

Location:
TI07-MOLES/trunk/PythonCode/wsgi
Files:
4 added
1 deleted
10 edited

Legend:

Unmodified
Added
Removed
  • TI07-MOLES/trunk/PythonCode/wsgi/DIF.py

    r1905 r1955  
    1111from ETxmlView import loadET, nsdumb 
    1212 
    13  
    1413class DIF: 
    1514    ''' Supports the NASA GCMD DIF format for python operations, 
     
    2120        self.metadataType='DIF' 
    2221        self.debug=1 
     22        self.config=config 
    2323        if et: 
    2424            self.tree=xml 
     
    3636        helper=nsdumb(self.tree) 
    3737        self.type='DIF' 
    38         if self.tree.tag!=self.type: self.tree=self.tree.find('.//%s'%self.type) 
     38        if helper.strip(self.tree.tag)!=self.type: self.tree=helper.find(self.tree,self.type) 
    3939        if self.tree is None: raise TypeError, self.xml 
     40         
    4041        self.entryID=helper.getText(self.tree,'Entry_ID') 
    4142        self.abstract=helper.getText(self.tree,'Summary') 
     
    5960 
    6061        #load up information about spatial bounding box  
    61         self.bbox=Bounding(self.tree,entity='DIF') 
     62        self.bbox=Bounding(self.tree,entity='DIF',getter=helper.getText) 
    6263         
    6364        #load up information about temporal extent 
    64         self.timeCoverage=( 
     65        tc=( 
    6566            helper.getText(self.tree,'Temporal_Coverage/Start_Date'), 
    6667            helper.getText(self.tree,'Temporal_Coverage/Stop_Date'), 
    6768            helper.getText(self.tree,'Data_Set_Progress') ) 
     69        self.timeCoverage=TimeCoverage(tc) 
    6870             
    6971        #Data curator information 
     
    7476        self.creators=[] 
    7577        # use author here because a full dif entry for creator wont necessarily exist in citation ... 
    76         self.authors=helper.getText(self.tree,'Data_Set_Citation/Dataset_Creator') 
     78        self.getAuthors(helper) 
    7779        self.date=dateParse(helper.getText(self.tree,'Data_Set_Citation/Dataset_Release_Date'),'YYYY') 
     80        if self.date=='': self.date='XXXX' 
    7881        self.title=helper.getText(self.tree,'Data_Set_Citation/Dataset_Title') 
    7982        self.briefCitation=None 
     
    9396             
    9497             
    95     def toHTML(self,config): 
     98    def toHTML(self): 
    9699        if self.tree is not None: 
    97             renderer=renderEntity(config) 
     100            renderer=renderEntity(self.config) 
    98101            return renderer.render(self) 
    99102        else: 
    100103            return '<p>No Valid DIF</p>' 
    101              
     104 
     105    def getAuthors(self,helper): 
     106        ''' Attempt to get dataset authorship information from a DIF ''' 
     107        # first try for an author entry in a citation 
     108        self.authors=helper.getText(self.tree,'Data_Set_Citation/Dataset_Creator') 
     109        if self.authors!='': return 
     110        # ok, now let's look for investigator(s) in the personnel section 
     111        a='' 
     112        people=helper.findall(self.tree,'Personnel') 
     113        for p in people: 
     114            role=helper.getText(p,'Role') 
     115            if role=='Investigator': 
     116                a+='%s %s,'%(helper.getText(p,'First_Name'),helper.getText(p,'Last_Name')) 
     117        if a!='':a=a[0:-1] 
     118        self.authors=a 
     119        print a 
     120        return 
     121         
     122 
     123import unittest 
     124 
     125class TestCase(unittest.TestCase): 
     126    """ 
     127    """ 
     128 
     129    inputFile = 'examples/neodc.eg1.dif' 
     130    configFile='examples/example.config' 
     131     
     132    def setUp(self): 
     133        ''' Load example config and DIF files for testing ''' 
     134        f=file(self.inputFile,'r') 
     135        xml=f.read() 
     136        config=myConfig(self.configFile) 
     137        self.dif=DIF(xml,config) 
     138         
     139 
     140    def testEntryID(self): 
     141        ''' Testing the DIF object can be loaded an entry ID extracted ''' 
     142        print 'Entry ID [%s]'%self.dif.entryID 
     143         
     144    def testrenderDIF(self): 
     145        ''' Testing the conversion to html ''' 
     146        print self.dif.timeCoverage 
     147        html=self.dif.toHTML() 
     148        g=file('difOutput.html','w') 
     149        g.write(html) 
     150 
    102151if __name__=="__main__": 
    103      
    104     #f=file('../../../exampleD/spade.xml') 
    105     f=file('difeg.xml') 
    106     g=file('../../../exampleD/ucar.xml') 
    107     dif1xml=f.read() 
    108     dif2xml=g.read() 
    109     config=myConfig('browse.config') 
    110     D=DIF(dif1xml,config) 
    111     G=DIF(dif2xml,config) 
    112     y='''<?xml version="1.0" encoding="UTF-8"?> 
    113                 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> 
    114                 <html xmlsns="http://www.w3.org/1999/xhtml" xml:lang="en"> 
    115                         <head> 
    116                                 <META http-equiv="Content-Type" content="text/xhtml; charset=iso-8859-1"/> 
    117                                 <title>%s</title> 
    118                                 <LINK media="all, screen" href="../layout/style.css" type="text/css" rel="stylesheet"/> 
    119                         </head> '''%D.name+D.toHTML(config)+G.toHTML(config) 
    120     f.close() 
    121     f=file('output.html','wb') 
    122     f.write(y) 
    123     print str(D.binding),D.binding.url 
    124      
    125      
     152    unittest.main() 
     153 
    126154         
    127155         
    128          
    129          
    130          
  • TI07-MOLES/trunk/PythonCode/wsgi/DiscoveryGUI.py

    r1905 r1955  
    11import DiscoveryTemplate 
     2from paste.request import parse_querystring 
    23import ndgSearch as NS 
    34from DIF import DIF 
     
    1516    #this can all be embedded in anything else. 
    1617     
    17     def __init__(self,inputs,config,logger): 
     18    def __init__(self,environ,config,logger): 
    1819        ''' Takes a dictionary of variables which have been populated by the cgi (or whatever)  
    1920        handler, and tests them for sanity before handing queries off to the NDG backend xqquery 
    2021        web service ''' 
    2122         
     23        inputs=dict(parse_querystring(environ)) 
    2224        self.inputs=inputs 
     25        self.environ=environ 
    2326        self.config=config 
    2427        self.logger=logger 
     
    103106    def __setState(self,id,hits,offset,stride): 
    104107        ''' Sets the discovery state to be used by external routines ''' 
    105         return DiscoveryState(id,self.inputs,hits,offset,stride) 
     108        return DiscoveryState(id,self.environ,hits,offset,stride) 
    106109         
    107110    def doText(self,searchString,textTarget,start,howmany,scope=None,dateRange=None,bbox=None): 
  • TI07-MOLES/trunk/PythonCode/wsgi/DiscoveryState.py

    r1905 r1955  
     1from paste.request import parse_querystring,construct_url 
    12class DiscoveryState: 
    23    ''' This class holds the state associated with presenting multiple slices 
    34    of a large result set ''' 
    4     def __init__(self,sessionID,request,hits,offset=1,stride=10): 
     5    def __init__(self,sessionID,environ,hits,offset=1,stride=10): 
    56        ''' On instantiation, provide 
    67                the backend sessionID 
    78                the application URL that produced this query 
    89                the stride through the result set ''' 
    9         self.request=request 
     10        self.environ=environ # the wsgi environment 
    1011        self.sessID=sessionID 
    1112        self.hits=hits 
    1213        self.offset=offset 
    1314        self.stride=stride 
     15    def geturl(self,**kw): 
     16        ''' Get a url from the wsgi environment, modified by the keyword arguments offset and stride  
     17        which are to be part of the querystring ''' 
     18        args=dict(parse_querystring(self.environ)) 
     19        offset,stride=kw.get('offset'),kw.get('stride') 
     20        if offset is not None:args['start']=offset 
     21        if stride is not None:args['howmany']=stride 
     22        q='' 
     23        for i in args: q+='%s=%s&'%(i,args[i]) 
     24        q=q[0:-1] 
     25        url=construct_url(self.environ, with_query_string=True, with_path_info=True, querystring=q) 
     26        return url 
     27         
  • TI07-MOLES/trunk/PythonCode/wsgi/DocumentRetrieve.py

    r1925 r1955  
    4242            # xquery=listingQuery 
    4343 
    44             targetCollection='/db/ndg_B_metadata' 
     44            #targetCollection='/db/ndg_B_metadata' 
     45            targetCollection='/db/discovery/moles' 
    4546            xquery=ObjectTypeQuery 
    4647            xquery=queryReplace(xquery,repository,localID,targetCollection) 
  • TI07-MOLES/trunk/PythonCode/wsgi/ETxmlView.py

    r1905 r1955  
    1111    import ElementTree as ET 
    1212import re 
    13 from sub_orphan import * 
     13 
    1414 
    1515class nsdumb: 
     
    3131    def __str__(self): 
    3232        return 'Element Tree namespace helper with namespace: [%s]'%self.xmlns 
     33     
     34    def __distributens(self,xpathExpression): 
     35        ''' Actually we only support tag finding in this ''' 
     36        tags=xpathExpression.split('/') 
     37        new='' 
     38        for t in tags: new+=self.xmlns+t+'/' 
     39        new=new[0:-1] 
     40        return new 
    3341    def getText(self,elem,xpathExpression,multiple=0): 
    3442        ''' Get a text object sensibly ''' 
     
    3846            else: return ''  
    3947        if multiple: 
    40                 r=elem.findall(self.xmlns+xpathExpression) 
     48                r=elem.findall(self.__distributens(xpathExpression)) 
    4149        else: 
    42                 r=[elem.find(self.xmlns+xpathExpression),] 
     50                r=[elem.find(self.__distributens(xpathExpression)),] 
    4351        try:  # if element is None, this should fail ... 
    4452                rr=[] 
     
    5765       ''' Return relevant subelement ''' 
    5866       if elem is None: return '' 
    59        xe=self.xmlns+xpathExpression 
     67       xe=self.__distributens(xpathExpression) 
    6068       return elem.find(xe) 
    6169    
     
    6371       ''' Return all relevant subelements ''' 
    6472       if elem is None: return [] 
    65        xe=self.xmlns+xpathExpression 
     73       xe=self.__distributens(xpathExpression) 
    6674       return elem.findall(xe) 
    6775 
     
    136144    < or > signs ... and that the unicode has been processed to something that  
    137145    might work''' 
    138       
     146    from sub_orphan import * 
    139147    if inputString is None: return None 
    140148    inputString=re.sub(r'&(?!\w+;)', '&amp;', inputString) 
  • TI07-MOLES/trunk/PythonCode/wsgi/Utilities.py

    r1905 r1955  
    44except: 
    55    import ElementTree as ET 
     6from ETxmlView import * 
    67import ConfigParser 
    78import os 
     
    136137    else: 
    137138        return 'unknown instruction to dateParse %s'%instruction 
    138         
     139 
     140def idget(xml,dataType='DIF'): 
     141    ''' Given an xml document (string), parse it using ElementTree and  
     142    find the identifier within it. Supports dataTypes of 'DIF' ... 
     143    (actually only DIF for now). 
     144    ''' 
     145    et=loadET(xml) 
     146    helper=nsdumb(et) 
     147    if dataType=='DIF': 
     148        return helper.getText(et,'Entry_ID') 
     149    else: 
     150        raise TypeError,'idget does not support datatype [%s]'%dataType 
     151 
     152import unittest 
     153class TestCase(unittest.TestCase): 
     154    """ Tests as required """ 
     155 
     156    configFile='examples/example.config' 
     157    difFile='examples/neodc.eg1.dif' 
     158     
     159    def setUp(self): 
     160        # If pkg_resources is available assume the module is eggified and 
     161        # get a stream to the input data from the egg. 
     162        #try: 
     163        #    import pkg_resources 
     164        #    f = pkg_resources.resource_stream(__name__, self.configFile) 
     165        #except ImportError: 
     166            # Else take the input file from __file__ 
     167            #import os 
     168        self.config=myConfig(self.configFile) 
     169        f=file(self.difFile,'r') 
     170        self.difxml=f.read() 
     171            #f=file(os.path.join(os.path.basepath(__file__), self.configFile)) 
     172 
     173        #self.config=myConfig(f) 
     174 
     175    def testConfig(self): 
     176        print 'Discovery Icon [%s]'%self.config.get('DISCOVERY','icon') 
     177         
     178    def testidget(self): 
     179        self.assertEqual(idget(self.difxml),'NOCSDAT192') 
     180     
     181 
    139182if __name__=="__main__": 
    140     s,t='abc12','def' 
    141     print s,EnumerateString(s),t,EnumerateString(t) 
    142      
     183    unittest.main() 
     184 
     185 
     186 
  • TI07-MOLES/trunk/PythonCode/wsgi/geoUtilities.py

    r1930 r1955  
    11from Utilities import wrapGetText 
     2 
    23def geoString2float(x): 
    34    if x[-1:] in 'NE': 
     
    1011class Bounding: 
    1112    ''' Separated out because this is NDG specific really ''' 
    12     def __init__(self,elem,entity='stubB'): 
     13    def __init__(self,elem,entity='stubB',getter=wrapGetText): 
    1314        '''Parse a data entity and load a bounding box ''' 
    1415        match={'stubB': 
     
    2324                  'East':'Spatial_Coverage/Easternmost_Longitude'} 
    2425                } 
    25         try: 
    26             North=wrapGetText(elem,match[entity]['North']) 
    27             South=wrapGetText(elem,match[entity]['South']) 
    28             West=wrapGetText(elem,match[entity]['West']) 
    29             East=wrapGetText(elem,match[entity]['East']) 
    30             self.set([North,West,East,South]) 
    31         except: 
    32             self.box=None 
     26        #try: 
     27        North=getter(elem,match[entity]['North']) 
     28        South=getter(elem,match[entity]['South']) 
     29        West=getter(elem,match[entity]['West']) 
     30        East=getter(elem,match[entity]['East']) 
     31        self.set([North,West,East,South]) 
     32        #except: 
     33        #    self.box=None 
    3334 
    3435    def set(self,box): 
     
    5051            html='' 
    5152        return html 
     53 
     54class TimeCoverage: 
     55    def __init__(self,tc): 
     56        ''' Takes a tuple of (start date, end date, status ''' 
     57        self.data=tc 
     58    def __str__(self): 
     59        return 'Start:%s, End:%s, Status:%s'%self.data 
     60    def __getitem__(self,i): 
     61        return self.data[i] 
    5262         
    5363import unittest 
     
    6171        bbox.set(['15N','12W','12E','15S']) 
    6272        y=bbox.toHTML() 
     73         
     74    def testTimeCoverage(self): 
     75        ''' Test time coverage class ''' 
     76        tc=TimeCoverage(('01-01-2001','01-02-2001','Complete')) 
     77        print tc 
     78        self.assertEqual(tc[2],'Complete') 
    6379     
    6480if __name__=="__main__": 
  • TI07-MOLES/trunk/PythonCode/wsgi/ndgDiscovery.config

    r1927 r1955  
    1111layoutdir:      /home/bnl/sandboxes/ndg/TI07-MOLES/trunk/PythonCode/browse/portal/cgi/layout/ 
    1212layout:         /layout/ 
    13 repository:       gepidae.esc.rl.ac.uk 
     13repository:       glue.badc.rl.ac.uk 
    1414 
    1515[SEARCH] 
  • TI07-MOLES/trunk/PythonCode/wsgi/ndgDiscovery.py

    r1905 r1955  
    11from Utilities import myConfig 
    2 from paste.request import parse_querystring 
     2 
    33from DiscoveryGUI import DiscoveryGUI 
    44 
     
    3636        ''' This is the wsgi function which implements the ndgDiscovery ''' 
    3737         
    38         inputs=dict(parse_querystring(environ)) 
    39          
    40         d=DiscoveryGUI(inputs,self.config,self.logger) 
     38        d=DiscoveryGUI(environ,self.config,self.logger) 
    4139 
    4240        start_response('200 OK', [('Content-Type', 'text/html')]) 
  • TI07-MOLES/trunk/PythonCode/wsgi/renderDiscoverySet.py

    r1905 r1955  
    110110    #html+='<p>Results %s to %s of %s'%(state.offset,min(state.offset+state.stride-1,state.hits),state.hits) 
    111111    html+='<p>Results %s to %s of %s'%(state.offset,state.offset+len(difSet)-1,state.hits) 
    112     if state.stride < state.hits and state.request is not None: 
     112    if state.stride < state.hits: 
    113113        #1,10,21   11,20,21  21,21,21 
    114114        if state.offset+state.stride-1<state.hits: 
     
    116116            nextNum=min(state.stride,1+state.hits-next1) # 10,1 
    117117            s1='Next %s'%nextNum 
    118             nexturl=state.request.modify({'start':next1,'howmany':nextNum,'searchSession':state.sessID}) 
     118            nexturl=state.geturl(offset=next1,stride=nextNum) 
    119119            html+=', %s'%hyperlink(s1,nexturl) 
    120120        if state.offset>1: 
     
    123123            if lastNum<min(20,state.hits): lastNum=20 
    124124            l1='Last %s'%lastNum 
    125             lasturl=state.request.modify({'start':last1,'howmany':lastNum,'searchSession':state.sessID}) 
     125            lasturl=state.geturl(offset=last1,stride=lastNum) 
    126126            html+=', %s'%hyperlink(l1,lasturl) 
    127127    else: 
Note: See TracChangeset for help on using the changeset viewer.