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

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

Tiny modification to citation handling

Line 
1# python class to support methods on a DIF ... to conform with
2# renderEntity etc ...
3#
4from Utilities import *
5from geoUtilities import *
6from People2 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   
22def shortLong(targetList,s,l):
23    ''' Format a short-long name combination as a string, and add to a list if non-empty,
24    and a non-duplicate'''
25    if l<>'':
26        if s<>'': 
27            r='%s (%s)'%(l,s)
28        else:
29            r=l
30    elif s<>'': r=s
31    if r not in targetList: targetList.append(r)
32    return targetList
33
34class DIF:
35    ''' Supports the NASA GCMD DIF format for python operations,
36    note ... not a complete implementation, currently minimum to
37    show a reasonable piece of content '''
38    def __init__(self,xml,et=0,debug=0,ndgObject=None):
39       
40        '''Initialise a python dif instance based on an xml document (expected
41        to be an input string if et=0, otherwise an ElementTree instance) '''
42        if et:
43            try:
44                self.tree=xml
45                self.xml=ET.tostring(xml)
46            except:
47                raise TypeError,'DIF input is not a valid ElementTree instance'
48        else:
49            try:
50                self.tree=loadET(xml)
51                self.xml=xml
52            except: # for some reason we can't parse the document, and it's worth knowing why
53                if isinstance(xml,str):
54                    l=min(len(xml),300)-1
55                    if l!=len(xml):xml=xml[0:l]+'\n...'
56                    raise ValueError,'DIF input cannot be parsed into an ElementTree instance:\n%s'%xml
57                else:
58                    raise TypeError,'DIF input of type [%s] needs to be a string!'%type(xml)
59       
60        self.debug=debug
61       
62        # if this is an ndgObject that'll have been sorted externally ...
63        self.ndgObject=ndgObject
64       
65        # now try and interpret it
66       
67        helper=nsdumb(self.tree)
68        self.metadataType='DIF'
69        if helper.strip(self.tree.tag)!=self.metadataType: 
70            self.tree=helper.find(self.tree,self.metadataType)
71            if self.tree is None: 
72                raise ValueError, 'DIF input does not include a DIF element:\n%s'%self.xml
73       
74        self.entryID=helper.getText(self.tree,'Entry_ID')
75        self.abstract=helper.getText(self.tree,'Summary')
76        self.name=helper.getText(self.tree,'Entry_Title')
77        self.abbreviation=self.name[0:min(5,len(self.name))]
78       
79        #Note that entity.constraints.html is about access control on the metadata,
80        #and so we don't populate this here ...
81        self.constraints=AccessControl(None)
82       
83        #need entity.parameters, entity.bbox, entity.timeCoverage, entity.curator, entity.creators
84        # nb, two ways of parameters being stored
85        self.parameters=[]
86        for parameter in helper.findall(self.tree,'Parameters'):
87            name=''
88            for level in ['Category','Topic','Term','Variable','Detailed_Variable']:
89                    name+=helper.getText(parameter,level)+'>'
90            name=name.rstrip('>')
91            #print '[%s]\n%s'%(name,ET.tostring(parameter))
92            if name=='':
93                name=helper.getText(parameter,'.')#.text
94                if name is not None: 
95                    #self.parameters.append(name.replace('>','/'))
96                    while len(name.split('>'))<5:name+='>'
97            self.parameters.append(name)
98       
99        #sensors are pretty important too
100        self.sensors=[]
101        for sensor in helper.findall(self.tree,'Sensor_Name'):
102            s,l=helper.getText(sensor,'Short_Name'),helper.getText(sensor,'Long_Name')
103            self.sensors=shortLong(self.sensors,s,l)
104               
105        #and sources
106        self.sources=[]
107        for source in helper.findall(self.tree,'Source_Name'):
108            s,l=helper.getText(source,'Short_Name'),helper.getText(source,'Long_Name')
109            self.sources=shortLong(self.sources,s,l)
110
111        #load up information about spatial bounding box
112        self.bbox=Bounding(self.tree,entity='DIF',getter=helper.getText)
113       
114        #load up information about temporal extent
115        # nb, some DIFS use Stop Date, some use End Date
116        date=helper.find(self.tree,'Temporal_Coverage')
117        e1,e2=helper.getText(date,'Stop_Date'),helper.getText(date,'End_Date')
118        start=helper.getText(date,'Start_Date')
119        status=helper.getText(self.tree,'Data_Set_Progress')
120        if e1<>'':
121            self.timeCoverage=TimeCoverage((start,e1,status))
122        else:
123            self.timeCoverage=TimeCoverage((start,e2,status))
124       
125        #load up those silly paleo keywords
126        self.paleoKeywords=[]
127        paleoElements=helper.findall(self.tree,'Paleo_Temporal_Coverage')
128        for e in paleoElements:
129            self.paleoKeywords.append(helper.getText(e,'Chronostratigraphic_Unit'))
130           
131        #Data curator information
132        self.centre=DIFcontact(helper,helper.find(self.tree,'Data_Center'))
133        self.curator=DIFcontact(helper,helper.find(self.tree,'Data_Curator'))
134        if self.curator.core is None:self.curator=self.centre
135       
136        #Data Creators
137        self.creators=[]
138        # Let's first see if we get an author out of the citation,
139        self.authors=helper.getText(self.tree,'Data_Set_Citation/Dataset_Creator') 
140        self.date=dateParse(helper.getText(self.tree,'Data_Set_Citation/Dataset_Release_Date'),'YYYY')
141        #if self.date=='': self.date='XXXX'
142        self.title=helper.getText(self.tree,'Data_Set_Citation/Dataset_Title')
143        self.briefCitation=''
144        if (self.authors!='' and self.date!='' and self.title!=''):
145            self.briefCitation='%s (%s): %s'%(self.authors,self.date,self.title)
146        #for now
147        self.citation=self.briefCitation
148       
149        self.personnel=[DIFcontact(helper,f) for f in helper.findall(self.tree,'Personnel')]
150       
151        #services
152        self.services=[]
153
154        for item in helper.findall(self.tree,'Related_URL'):
155            self.services.append(
156                DIFService(
157                 helper.getText(item,'URL_Content_Type'),
158                 helper.getText(item,'URL'),
159                 helper.getText(item,'Description') ))
160       
161        if self.ndgObject is None:
162            self.binding=None
163        else:
164            if self.ndgObject.discoveryURL is not None:
165                self.binding=DIFService('DISCOVERY',self.ndgObject.discoveryURL,'Discovery record')
166            else: self.binding=None
167
168        if self.debug:
169           f=open('difs.log','a')
170           f.write('%s##\n%s\n##################################\n'%(self.entryID,self.xml))
171           f.close()
172           
173    def toHTML(self,config):
174
175        if self.tree is not None:
176            renderer=renderEntity(config)
177            return renderer.render(self)
178        else:
179            return '<p>No Valid DIF</p>'
180
181
182import unittest
183
184class TestCase(unittest.TestCase):
185    """
186    """
187
188    inputFile = 'examples/neodc.eg1.dif'
189    inputFile2= 'examples/bodc.eg2.edmed.dif'
190    inputFile2= 'examples/bodc.eg3.difChange.dif'
191    configFile='examples/example.config'
192   
193    def setUp(self):
194        ''' Load example config and DIF files for testing '''
195        f=file(self.inputFile2,'r')
196        xml=f.read()
197        self.dif=DIF(xml)
198        self.config=myConfig(self.configFile)
199
200    def testEntries(self):
201        ''' Testing the DIF object can be loaded and some key entries extracted '''
202        print 'Entry ID [%s]'%self.dif.entryID
203        print 'Author [%s]'%self.dif.authors
204       
205    def testrenderDIF(self):
206        ''' Testing the conversion to html '''
207        print self.dif.timeCoverage
208        html=self.dif.toHTML(self.config)
209        g=file('difOutput.html','w')
210        g.write(html)
211   
212    def testParameters(self):
213        ''' Testing obtaining parameters from an edmed dif in original format '''
214        print 'Parameters %s'%self.dif.parameters
215       
216    def testDifficult(self):
217        ''' Grab a test example from the internet and load it '''
218        from ndgRetrieve import ndgRetrieve
219        retriever=ndgRetrieve('./')
220        #testURI='grid.bodc.nerc.ac.uk__DIF__EDMED1048008'
221        testURI='neodc.nerc.ac.uk__DIF__NEODC_NEXTMAP'
222        inputs={'repository':'glue.badc.rl.ac.uk','uri':testURI,'format':'original','type':'xml','original':'1'}
223        ctype,r=retriever._present(inputs,'text/html')
224        d=DIF(r)
225        print d.entryID,[str(i) for i in d.services]
226
227
228if __name__=="__main__":
229    unittest.main()
230
231       
232       
Note: See TracBrowser for help on using the repository browser.