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

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

Sundry modes to wsgi browse/discovery on the road to deploying on
glue (mostly about the many possible locations of elementtree)

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
10try: #python 2.5
11    from xml.etree import ElementTree as ET
12except ImportError:
13    try:
14        # if you've installed it yourself it comes this way
15        import ElementTree as ET
16    except ImportError:
17        # if you've egged it this is the way it comes
18        from elementtree import ElementTree as ET
19
20class DIFService:
21    ''' A DIF only knows about a related URL '''
22    def __init__(self,c,u,d):
23        ''' Take a related url tuple (content_type,url,description) and store it, using
24        an ndgModifier if necessary '''
25        self.contentType,self.url,self.description=c,u,d
26    def __str__(self):
27        return '<a href="%s" title="%s">%s</a>'%self.contentType,self.url,self.description
28   
29class DIF:
30    ''' Supports the NASA GCMD DIF format for python operations,
31    note ... not a complete implementation, currently minimum to
32    show a reasonable piece of content '''
33    def __init__(self,xml,et=0,debug=0,url=None):
34       
35        '''Initialise a python dif instance based on an xml document (expected
36        to be an input string if et=0, otherwise an ElementTree instance) '''
37       
38        if et:
39            try:
40                self.tree=xml
41                self.xml=ET.tostring(xml)
42            except:
43                raise TypeError,'DIF input is not a valid ElementTree instance'
44        else:
45            try:
46                self.tree=loadET(xml)
47                self.xml=xml
48            except: # for some reason we can't parse the document, and it's worth knowing why
49                if isinstance(xml,str):
50                    l=min(len(xml),300)-1
51                    if l!=len(xml):xml=xml[0:l]+'\n...'
52                    raise ValueError,'DIF input cannot be parsed into an ElementTree instance:\n%s'%xml
53                else:
54                    raise TypeError,'DIF input of type [%s] needs to be a string!'%type(xml)
55       
56        self.debug=debug
57       
58        # now try and interpret it
59       
60        helper=nsdumb(self.tree)
61        self.metadataType='DIF'
62        if helper.strip(self.tree.tag)!=self.metadataType: 
63            self.tree=helper.find(self.tree,self.metadataType)
64            if self.tree is None: 
65                raise ValueError, 'DIF input does not include a DIF element:\n%s'%self.xml
66       
67        self.entryID=helper.getText(self.tree,'Entry_ID')
68        self.abstract=helper.getText(self.tree,'Summary')
69        self.name=helper.getText(self.tree,'Entry_Title')
70        self.abbreviation=self.name[0:min(5,len(self.name))]
71       
72        # The binding is an external piece of information which says how discovery
73        # information for this DIF instance (or it's latest version) can be recovered
74        # from the Internet (of course, it may simply recover itself ...)
75       
76        if url is not None:
77            self.binding=DIFService('DISCOVERY',url,'The discovery record for this dataset')
78        else:
79            self.binding=None
80                   
81        #Note that entity.constraints.html is about access control on the metadata,
82        #and so we don't populate this here ...
83        self.constraints=AccessControl(None)
84       
85        #need entity.parameters, entity.bbox, entity.timeCoverage, entity.curator, entity.creators
86
87        self.parameters=[]
88        for parameter in helper.findall(self.tree,'Parameters'):
89            name=''
90            for level in ['Category','Topic','Term','Variable','Detailed_Variable']:
91                name+=helper.getText(parameter,level)+'/'
92            self.parameters.append(name.rstrip('/'))
93           
94
95        #load up information about spatial bounding box
96        self.bbox=Bounding(self.tree,entity='DIF',getter=helper.getText)
97       
98        #load up information about temporal extent
99        tc=(
100            helper.getText(self.tree,'Temporal_Coverage/Start_Date'),
101            helper.getText(self.tree,'Temporal_Coverage/Stop_Date'),
102            helper.getText(self.tree,'Data_Set_Progress') )
103        self.timeCoverage=TimeCoverage(tc)
104           
105        #Data curator information
106        self.centre=DIFcontact(helper.find(self.tree,'Data_Center'),ctype='centre',helper=helper)
107        self.curator=DIFcontact(self.tree)
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        for item in helper.findall(self.tree,'Related_URL'):
123            self.services.append(
124                DIFService(
125                 helper.getText(item,'URL_Content_type'),
126                 helper.getText(item,'URL'),
127                 helper.getText(item,'Description') ))
128         
129        if self.debug:
130           f=open('difs.log','a')
131           f.write('%s##\n%s\n##################################\n'%(self.entryID,self.xml))
132           f.close()
133           
134           
135    def toHTML(self,config):
136
137        if self.tree is not None:
138            renderer=renderEntity(config)
139            return renderer.render(self)
140        else:
141            return '<p>No Valid DIF</p>'
142
143
144import unittest
145
146class TestCase(unittest.TestCase):
147    """
148    """
149
150    inputFile = 'examples/neodc.eg1.dif'
151    configFile='examples/example.config'
152   
153    def setUp(self):
154        ''' Load example config and DIF files for testing '''
155        f=file(self.inputFile,'r')
156        xml=f.read()
157        self.dif=DIF(xml)
158        self.config=myConfig(self.configFile)
159
160    def testEntries(self):
161        ''' Testing the DIF object can be loaded and some key entries extracted '''
162        print 'Entry ID [%s]'%self.dif.entryID
163        print 'Author [%s]'%self.dif.authors
164       
165    def testrenderDIF(self):
166        ''' Testing the conversion to html '''
167        print self.dif.timeCoverage
168        html=self.dif.toHTML(self.config)
169        g=file('difOutput.html','w')
170        g.write(html)
171
172if __name__=="__main__":
173    unittest.main()
174
175       
176       
Note: See TracBrowser for help on using the repository browser.