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

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

Cleaning up edge cases in discovery so that while NDG browse isn't
enabled, what you see still makes sense :-).

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=parameter.text
76            if name is not None: 
77                #self.parameters.append(name.replace('>','/'))
78                while len(name.split('>'))<5:name+='>'
79                self.parameters.append(name)
80            else:
81                name=''
82                for level in ['Category','Topic','Term','Variable','Detailed_Variable']:
83                    name+=helper.getText(parameter,level)+'>'
84                self.parameters.append(name.rstrip('>'))
85
86        #load up information about spatial bounding box
87        self.bbox=Bounding(self.tree,entity='DIF',getter=helper.getText)
88       
89        #load up information about temporal extent
90        tc=(
91            helper.getText(self.tree,'Temporal_Coverage/Start_Date'),
92            helper.getText(self.tree,'Temporal_Coverage/Stop_Date'),
93            helper.getText(self.tree,'Data_Set_Progress') )
94        self.timeCoverage=TimeCoverage(tc)
95       
96        #load up those silly paleo keywords
97        self.paleoKeywords=[]
98        paleoElements=helper.findall(self.tree,'Paleo_Temporal_Coverage')
99        for e in paleoElements:
100            self.paleoKeywords.append(helper.getText(e,'Chronostratigraphic_Unit'))
101           
102        #Data curator information
103        self.centre=DIFcontact(helper.find(self.tree,'Data_Center'),ctype='centre',helper=helper)
104        self.curator=DIFcontact(helper.find(self.tree,'Data_Curator'),ctype='centre',helper=helper)
105        if self.curator is None:self.curator=self.centre
106       
107        #Data Creators
108        self.creators=[]
109        # use author here because a full dif entry for creator wont necessarily exist in citation ...
110        self.authors=DIFAuthors(self.tree,helper)
111        self.date=dateParse(helper.getText(self.tree,'Data_Set_Citation/Dataset_Release_Date'),'YYYY')
112        if self.date=='': self.date='XXXX'
113        self.title=helper.getText(self.tree,'Data_Set_Citation/Dataset_Title')
114        self.briefCitation=None
115        if (self.authors!='' and self.date!='' and self.title!=''):
116            self.briefCitation='%s (%s): %s'%(self.authors,self.date,self.title)
117
118        #services
119        self.services=[]
120
121        for item in helper.findall(self.tree,'Related_URL'):
122            self.services.append(
123                DIFService(
124                 helper.getText(item,'URL_Content_Type'),
125                 helper.getText(item,'URL'),
126                 helper.getText(item,'Description') ))
127       
128        if self.ndgObject is None:
129            self.binding=None
130        else:
131            if self.ndgObject.discoveryURL is not None:
132                self.binding=DIFService('DISCOVERY',self.ndgObject.discoveryURL,'Discovery record')
133            else: self.binding=None
134
135        if self.debug:
136           f=open('difs.log','a')
137           f.write('%s##\n%s\n##################################\n'%(self.entryID,self.xml))
138           f.close()
139           
140    def toHTML(self,config):
141
142        if self.tree is not None:
143            renderer=renderEntity(config)
144            return renderer.render(self)
145        else:
146            return '<p>No Valid DIF</p>'
147
148
149import unittest
150
151class TestCase(unittest.TestCase):
152    """
153    """
154
155    inputFile = 'examples/neodc.eg1.dif'
156    inputFile2= 'examples/bodc.eg2.edmed.dif'
157    configFile='examples/example.config'
158   
159    def setUp(self):
160        ''' Load example config and DIF files for testing '''
161        f=file(self.inputFile2,'r')
162        xml=f.read()
163        self.dif=DIF(xml)
164        self.config=myConfig(self.configFile)
165
166    def testEntries(self):
167        ''' Testing the DIF object can be loaded and some key entries extracted '''
168        print 'Entry ID [%s]'%self.dif.entryID
169        print 'Author [%s]'%self.dif.authors
170       
171    def testrenderDIF(self):
172        ''' Testing the conversion to html '''
173        print self.dif.timeCoverage
174        html=self.dif.toHTML(self.config)
175        g=file('difOutput.html','w')
176        g.write(html)
177   
178    def testParameters(self):
179        ''' Testing obtaining parameters from an edmed dif in original format '''
180        print 'Parameters %s'%self.dif.parameters
181
182if __name__=="__main__":
183    unittest.main()
184
185       
186       
Note: See TracBrowser for help on using the repository browser.