source: TI07-MOLES/trunk/PythonCode/wsgi/DIF.py @ 2315

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI07-MOLES/trunk/PythonCode/wsgi/DIF.py@2315
Revision 2315, 7.1 KB checked in by lawrence, 14 years ago (diff)

Improved parameter handling, and better test cases.

Line 
1# python class to support methods on a DIF ... to conform with
2# renderEntity etc ...
3#
4from Utilities import *
5from geoUtilities import *
6from People import *
7from AccessControl import AccessControl
8from ETxmlView import loadET, nsdumb
9from renderEntity import renderEntity
10from ServiceBinding import DIFService
11try: #python 2.5
12    from xml.etree import ElementTree as ET
13except ImportError:
14    try:
15        # if you've installed it yourself it comes this way
16        import ElementTree as ET
17    except ImportError:
18        # if you've egged it this is the way it comes
19        from elementtree import ElementTree as ET
20debug=1
21   
22class DIF:
23    ''' Supports the NASA GCMD DIF format for python operations,
24    note ... not a complete implementation, currently minimum to
25    show a reasonable piece of content '''
26    def __init__(self,xml,et=0,debug=0,ndgObject=None):
27       
28        '''Initialise a python dif instance based on an xml document (expected
29        to be an input string if et=0, otherwise an ElementTree instance) '''
30        if et:
31            try:
32                self.tree=xml
33                self.xml=ET.tostring(xml)
34            except:
35                raise TypeError,'DIF input is not a valid ElementTree instance'
36        else:
37            try:
38                self.tree=loadET(xml)
39                self.xml=xml
40            except: # for some reason we can't parse the document, and it's worth knowing why
41                if isinstance(xml,str):
42                    l=min(len(xml),300)-1
43                    if l!=len(xml):xml=xml[0:l]+'\n...'
44                    raise ValueError,'DIF input cannot be parsed into an ElementTree instance:\n%s'%xml
45                else:
46                    raise TypeError,'DIF input of type [%s] needs to be a string!'%type(xml)
47       
48        self.debug=debug
49       
50        # if this is an ndgObject that'll have been sorted externally ...
51        self.ndgObject=ndgObject
52       
53        # now try and interpret it
54       
55        helper=nsdumb(self.tree)
56        self.metadataType='DIF'
57        if helper.strip(self.tree.tag)!=self.metadataType: 
58            self.tree=helper.find(self.tree,self.metadataType)
59            if self.tree is None: 
60                raise ValueError, 'DIF input does not include a DIF element:\n%s'%self.xml
61       
62        self.entryID=helper.getText(self.tree,'Entry_ID')
63        self.abstract=helper.getText(self.tree,'Summary')
64        self.name=helper.getText(self.tree,'Entry_Title')
65        self.abbreviation=self.name[0:min(5,len(self.name))]
66       
67        #Note that entity.constraints.html is about access control on the metadata,
68        #and so we don't populate this here ...
69        self.constraints=AccessControl(None)
70       
71        #need entity.parameters, entity.bbox, entity.timeCoverage, entity.curator, entity.creators
72        # nb, two ways of parameters being stored
73        self.parameters=[]
74        for parameter in helper.findall(self.tree,'Parameters'):
75            name=''
76            for level in ['Category','Topic','Term','Variable','Detailed_Variable']:
77                    name+=helper.getText(parameter,level)+'>'
78            name=name.rstrip('>')
79            #print '[%s]\n%s'%(name,ET.tostring(parameter))
80            if name=='':
81                name=parameter.text
82                if name is not None: 
83                    #self.parameters.append(name.replace('>','/'))
84                    while len(name.split('>'))<5:name+='>'
85            self.parameters.append(name)
86           
87
88        #load up information about spatial bounding box
89        self.bbox=Bounding(self.tree,entity='DIF',getter=helper.getText)
90       
91        #load up information about temporal extent
92        tc=(
93            helper.getText(self.tree,'Temporal_Coverage/Start_Date'),
94            helper.getText(self.tree,'Temporal_Coverage/Stop_Date'),
95            helper.getText(self.tree,'Data_Set_Progress') )
96        self.timeCoverage=TimeCoverage(tc)
97       
98        #load up those silly paleo keywords
99        self.paleoKeywords=[]
100        paleoElements=helper.findall(self.tree,'Paleo_Temporal_Coverage')
101        for e in paleoElements:
102            self.paleoKeywords.append(helper.getText(e,'Chronostratigraphic_Unit'))
103           
104        #Data curator information
105        self.centre=DIFcontact(helper.find(self.tree,'Data_Center'),ctype='centre',helper=helper)
106        self.curator=DIFcontact(helper.find(self.tree,'Data_Curator'),ctype='centre',helper=helper)
107        if self.curator is None:self.curator=self.centre
108       
109        #Data Creators
110        self.creators=[]
111        # use author here because a full dif entry for creator wont necessarily exist in citation ...
112        self.authors=DIFAuthors(self.tree,helper)
113        self.date=dateParse(helper.getText(self.tree,'Data_Set_Citation/Dataset_Release_Date'),'YYYY')
114        if self.date=='': self.date='XXXX'
115        self.title=helper.getText(self.tree,'Data_Set_Citation/Dataset_Title')
116        self.briefCitation=None
117        if (self.authors!='' and self.date!='' and self.title!=''):
118            self.briefCitation='%s (%s): %s'%(self.authors,self.date,self.title)
119
120        #services
121        self.services=[]
122
123        for item in helper.findall(self.tree,'Related_URL'):
124            self.services.append(
125                DIFService(
126                 helper.getText(item,'URL_Content_Type'),
127                 helper.getText(item,'URL'),
128                 helper.getText(item,'Description') ))
129       
130        if self.ndgObject is None:
131            self.binding=None
132        else:
133            if self.ndgObject.discoveryURL is not None:
134                self.binding=DIFService('DISCOVERY',self.ndgObject.discoveryURL,'Discovery record')
135            else: self.binding=None
136
137        if self.debug:
138           f=open('difs.log','a')
139           f.write('%s##\n%s\n##################################\n'%(self.entryID,self.xml))
140           f.close()
141           
142    def toHTML(self,config):
143
144        if self.tree is not None:
145            renderer=renderEntity(config)
146            return renderer.render(self)
147        else:
148            return '<p>No Valid DIF</p>'
149
150
151import unittest
152
153class TestCase(unittest.TestCase):
154    """
155    """
156
157    inputFile = 'examples/neodc.eg1.dif'
158    inputFile2= 'examples/bodc.eg2.edmed.dif'
159    inputFile2= 'examples/bodc.eg3.difChange.dif'
160    configFile='examples/example.config'
161   
162    def setUp(self):
163        ''' Load example config and DIF files for testing '''
164        f=file(self.inputFile2,'r')
165        xml=f.read()
166        self.dif=DIF(xml)
167        self.config=myConfig(self.configFile)
168
169    def testEntries(self):
170        ''' Testing the DIF object can be loaded and some key entries extracted '''
171        print 'Entry ID [%s]'%self.dif.entryID
172        print 'Author [%s]'%self.dif.authors
173       
174    def testrenderDIF(self):
175        ''' Testing the conversion to html '''
176        print self.dif.timeCoverage
177        html=self.dif.toHTML(self.config)
178        g=file('difOutput.html','w')
179        g.write(html)
180   
181    def testParameters(self):
182        ''' Testing obtaining parameters from an edmed dif in original format '''
183        print 'Parameters %s'%self.dif.parameters
184
185if __name__=="__main__":
186    unittest.main()
187
188       
189       
Note: See TracBrowser for help on using the repository browser.