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

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

Refactoring discovery wsgi for cleaner service binding. (Done, but
there will be implications for wsgi browse which may now be broken,
but I can't test it til the database is updated).

Line 
1# python class to support methods on a DIF ... to conform with
2# renderEntity etc ...
3#
4from xml.etree import ElementTree as ET
5from Utilities import *
6from geoUtilities import *
7from People import *
8from AccessControl import AccessControl
9from ETxmlView import loadET, nsdumb
10from renderEntity import renderEntity
11
12class DIFService:
13    ''' A DIF only knows about a related URL '''
14    def __init__(self,c,u,d):
15        ''' Take a related url tuple (content_type,url,description) and store it, using
16        an ndgModifier if necessary '''
17        self.contentType,self.url,self.description=c,u,d
18    def __str__(self):
19        return '<a href="%s" title="%s">%s</a>'%self.contentType,self.url,self.description
20   
21class DIF:
22    ''' Supports the NASA GCMD DIF format for python operations,
23    note ... not a complete implementation, currently minimum to
24    show a reasonable piece of content '''
25    def __init__(self,xml,et=0,debug=0,url=None):
26       
27        '''Initialise a python dif instance based on an xml document (expected
28        to be an input string if et=0, otherwise an ElementTree instance) '''
29       
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        # now try and interpret it
51       
52        helper=nsdumb(self.tree)
53        self.metadataType='DIF'
54        if helper.strip(self.tree.tag)!=self.metadataType: 
55            self.tree=helper.find(self.tree,self.metadataType)
56            if self.tree is None: 
57                raise ValueError, 'DIF input does not include a DIF element:\n%s'%self.xml
58       
59        self.entryID=helper.getText(self.tree,'Entry_ID')
60        self.abstract=helper.getText(self.tree,'Summary')
61        self.name=helper.getText(self.tree,'Entry_Title')
62        self.abbreviation=self.name[0:min(5,len(self.name))]
63       
64        # The binding is an external piece of information which says how discovery
65        # information for this DIF instance (or it's latest version) can be recovered
66        # from the Internet (of course, it may simply recover itself ...)
67       
68        if url is not None:
69            self.binding=DIFService('DISCOVERY',url,'The discovery record for this dataset')
70        else:
71            self.binding=None
72                   
73        #Note that entity.constraints.html is about access control on the metadata,
74        #and so we don't populate this here ...
75        self.constraints=AccessControl(None)
76       
77        #need entity.parameters, entity.bbox, entity.timeCoverage, entity.curator, entity.creators
78
79        self.parameters=[]
80        for parameter in helper.findall(self.tree,'Parameters'):
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
87        #load up information about spatial bounding box
88        self.bbox=Bounding(self.tree,entity='DIF',getter=helper.getText)
89       
90        #load up information about temporal extent
91        tc=(
92            helper.getText(self.tree,'Temporal_Coverage/Start_Date'),
93            helper.getText(self.tree,'Temporal_Coverage/Stop_Date'),
94            helper.getText(self.tree,'Data_Set_Progress') )
95        self.timeCoverage=TimeCoverage(tc)
96           
97        #Data curator information
98        self.centre=DIFcontact(helper.find(self.tree,'Data_Center'),ctype='centre',helper=helper)
99        self.curator=DIFcontact(self.tree)
100
101        #Data Creators
102        self.creators=[]
103        # use author here because a full dif entry for creator wont necessarily exist in citation ...
104        self.authors=DIFAuthors(self.tree,helper)
105        self.date=dateParse(helper.getText(self.tree,'Data_Set_Citation/Dataset_Release_Date'),'YYYY')
106        if self.date=='': self.date='XXXX'
107        self.title=helper.getText(self.tree,'Data_Set_Citation/Dataset_Title')
108        self.briefCitation=None
109        if (self.authors!='' and self.date!='' and self.title!=''):
110            self.briefCitation='%s (%s): %s'%(self.authors,self.date,self.title)
111
112        #services
113        self.services=[]
114        for item in helper.findall(self.tree,'Related_URL'):
115            self.services.append(
116                DIFService(
117                 helper.getText(item,'URL_Content_type'),
118                 helper.getText(item,'URL'),
119                 helper.getText(item,'Description') ))
120         
121        if self.debug:
122           f=open('difs.log','a')
123           f.write('%s##\n%s\n##################################\n'%(self.entryID,self.xml))
124           f.close()
125           
126           
127    def toHTML(self,config):
128
129        if self.tree is not None:
130            renderer=renderEntity(config)
131            return renderer.render(self)
132        else:
133            return '<p>No Valid DIF</p>'
134
135
136import unittest
137
138class TestCase(unittest.TestCase):
139    """
140    """
141
142    inputFile = 'examples/neodc.eg1.dif'
143    configFile='examples/example.config'
144   
145    def setUp(self):
146        ''' Load example config and DIF files for testing '''
147        f=file(self.inputFile,'r')
148        xml=f.read()
149        self.dif=DIF(xml)
150        self.config=myConfig(self.configFile)
151
152    def testEntries(self):
153        ''' Testing the DIF object can be loaded and some key entries extracted '''
154        print 'Entry ID [%s]'%self.dif.entryID
155        print 'Author [%s]'%self.dif.authors
156       
157    def testrenderDIF(self):
158        ''' Testing the conversion to html '''
159        print self.dif.timeCoverage
160        html=self.dif.toHTML(self.config)
161        g=file('difOutput.html','w')
162        g.write(html)
163
164if __name__=="__main__":
165    unittest.main()
166
167       
168       
Note: See TracBrowser for help on using the repository browser.