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

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

Sundry modifications associated with the deployment on glue, and better
options for viewing and downloading the underlying xml records (not yet
complete)

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,ndgObject=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        if et:
38            try:
39                self.tree=xml
40                self.xml=ET.tostring(xml)
41            except:
42                raise TypeError,'DIF input is not a valid ElementTree instance'
43        else:
44            try:
45                self.tree=loadET(xml)
46                self.xml=xml
47            except: # for some reason we can't parse the document, and it's worth knowing why
48                if isinstance(xml,str):
49                    l=min(len(xml),300)-1
50                    if l!=len(xml):xml=xml[0:l]+'\n...'
51                    raise ValueError,'DIF input cannot be parsed into an ElementTree instance:\n%s'%xml
52                else:
53                    raise TypeError,'DIF input of type [%s] needs to be a string!'%type(xml)
54       
55        self.debug=debug
56       
57        # if this is an ndgObject that'll have been sorted externally ...
58        self.ndgObject=ndgObject
59       
60        # now try and interpret it
61       
62        helper=nsdumb(self.tree)
63        self.metadataType='DIF'
64        if helper.strip(self.tree.tag)!=self.metadataType: 
65            self.tree=helper.find(self.tree,self.metadataType)
66            if self.tree is None: 
67                raise ValueError, 'DIF input does not include a DIF element:\n%s'%self.xml
68       
69        self.entryID=helper.getText(self.tree,'Entry_ID')
70        self.abstract=helper.getText(self.tree,'Summary')
71        self.name=helper.getText(self.tree,'Entry_Title')
72        self.abbreviation=self.name[0:min(5,len(self.name))]
73       
74        #Note that entity.constraints.html is about access control on the metadata,
75        #and so we don't populate this here ...
76        self.constraints=AccessControl(None)
77       
78        #need entity.parameters, entity.bbox, entity.timeCoverage, entity.curator, entity.creators
79
80        self.parameters=[]
81        for parameter in helper.findall(self.tree,'Parameters'):
82            name=''
83            for level in ['Category','Topic','Term','Variable','Detailed_Variable']:
84                name+=helper.getText(parameter,level)+'/'
85            self.parameters.append(name.rstrip('/'))
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        #Data curator information
99        self.centre=DIFcontact(helper.find(self.tree,'Data_Center'),ctype='centre',helper=helper)
100        self.curator=DIFcontact(self.tree)
101
102        #Data Creators
103        self.creators=[]
104        # use author here because a full dif entry for creator wont necessarily exist in citation ...
105        self.authors=DIFAuthors(self.tree,helper)
106        self.date=dateParse(helper.getText(self.tree,'Data_Set_Citation/Dataset_Release_Date'),'YYYY')
107        if self.date=='': self.date='XXXX'
108        self.title=helper.getText(self.tree,'Data_Set_Citation/Dataset_Title')
109        self.briefCitation=None
110        if (self.authors!='' and self.date!='' and self.title!=''):
111            self.briefCitation='%s (%s): %s'%(self.authors,self.date,self.title)
112
113        #services
114        self.services=[]
115
116        for item in helper.findall(self.tree,'Related_URL'):
117            self.services.append(
118                DIFService(
119                 helper.getText(item,'URL_Content_type'),
120                 helper.getText(item,'URL'),
121                 helper.getText(item,'Description') ))
122       
123        if self.ndgObject is not None:
124            if self.ndgObject.gettable:
125                self.binding=DIFService('DISCOVERY',self.ndgObject.baseURL,'Discovery record')
126        else:
127            self.binding=None
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    def toHTML(self,config):
135
136        if self.tree is not None:
137            renderer=renderEntity(config)
138            return renderer.render(self)
139        else:
140            return '<p>No Valid DIF</p>'
141
142
143import unittest
144
145class TestCase(unittest.TestCase):
146    """
147    """
148
149    inputFile = 'examples/neodc.eg1.dif'
150    configFile='examples/example.config'
151   
152    def setUp(self):
153        ''' Load example config and DIF files for testing '''
154        f=file(self.inputFile,'r')
155        xml=f.read()
156        self.dif=DIF(xml)
157        self.config=myConfig(self.configFile)
158
159    def testEntries(self):
160        ''' Testing the DIF object can be loaded and some key entries extracted '''
161        print 'Entry ID [%s]'%self.dif.entryID
162        print 'Author [%s]'%self.dif.authors
163       
164    def testrenderDIF(self):
165        ''' Testing the conversion to html '''
166        print self.dif.timeCoverage
167        html=self.dif.toHTML(self.config)
168        g=file('difOutput.html','w')
169        g.write(html)
170
171if __name__=="__main__":
172    unittest.main()
173
174       
175       
Note: See TracBrowser for help on using the repository browser.