source: TI05-delivery/ows_framework/trunk/ows_server/ows_server/models/stubB.py @ 3015

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI05-delivery/ows_framework/trunk/ows_server/ows_server/models/stubB.py@3015
Revision 3015, 11.3 KB checked in by lawrence, 12 years ago (diff)

Improvement to information on stubB page (requested by Ag).

Line 
1#!/usr/bin/env python
2#
3# This python code (will) handle all forms of stub-B and provide HTML
4# methods to the extent required by the NDG browse functionality.
5# NB, It would be cleaner to use Dom's way of doing things but we'd
6# need a schema for that ...
7# BNL April 2006
8#
9
10from Utilities import *
11from AccessControl import AccessControl
12from geoUtilities import Bounding
13from People import *
14from ndgObject import ndgObject
15#from DeploymentHandling import *
16try: #python 2.5
17    from xml.etree import ElementTree as ET
18except ImportError:
19    try:
20        # if you've installed it yourself it comes this way
21        import ElementTree as ET
22    except ImportError:
23        # if you've egged it this is the way it comes
24        from elementtree import ElementTree as ET
25
26
27def collapse2(keywords,split='>'):
28    ''' Take the last element of a DIF parameter tree entry, and put them in a dictionary
29    under the DIF category '''
30    d={}
31    for item in keywords:
32        line=item.split(split)
33        category=line[0]
34        if category not in d: d[category]=[]
35        while line<>[]:
36            c=line.pop()
37            if c<>'': 
38                if c<>category:
39                    d[category].append(c)
40                line=[]
41    return d
42
43
44def idconvert(helper,elem,config=None,idelem='dgMetadataID'):
45    ''' Given an elementTree element for a dgMetadataID, create
46    a standard ndg URI, and produce an ndgObject '''
47    id=helper.find(elem,idelem)
48    entryID='%s__%s__%s'%(helper.getText(id,'repositoryIdentifier'),
49                            helper.getText(id,'schemeIdentifier'),
50                            helper.getText(id,'localIdentifier'))
51    uri=ndgObject(entryID,config)
52    return uri
53
54class ndgLink:
55    ''' This is a holder for an ndgObject which has a name (and possibly abbreviation) '''
56    def __init__(self,name,abbrev,ndgO,label='',image=None):
57        self.ndgObject=ndgO
58        self.name=name
59        self.abbrev=abbrev
60        self.image=image
61        self.label=label
62        self.URL=ndgO.BURL
63    def toHTML(self):
64        ### needs to be finished
65        return self.ndgObject.URL
66
67class dataGranule:
68        ''' Provides support for data granule structures '''
69        def __init__(self,helper,elem,config,name=''):
70            self.elem=elem
71            self.constraints=AccessControl(helper.find(elem,'accessControlPolicy'))
72            self.name=name
73            self.uri=idconvert(helper,elem,config,idelem='dataModelID')
74            self.entryID=self.uri.uri
75
76class ObservationStation:
77    def __init__(self,h,e):
78        self.e=
79        self.hdg='Obsevation Station'
80        if e is None: return
81class DataProductionTool:
82    def __init__(self,h,e):
83        self.e=e
84        i=h.find(e,'dgInstrument')
85        if i is not None: 
86            self.hdg='Instrument'
87        else:
88            self.hdg='Model'
89        if e is None: return
90class Activity:
91    def __init__(self,h,e):
92        self.e=e
93        self.hdg='Activity'
94        if e is None: return
95       
96def Deployments(elem,helper,config):
97    ''' This is the late June 2007 version '''
98    if elem is None: return None
99    types={'dptList':'dataproductiontool','activityList':'activity','obsStnList':'observationstation','dataEntityList':'dataentity'}
100    names={'dptList':'Data Production Tools','activityList':'Activities','obsStnList':'Observation Stations','dataEntityList':'Data Entities'}
101    result={}
102    for alist in types:
103        blist=helper.find(elem,alist)
104        collection=[]
105        if blist is not None:
106            for object in blist:
107                uri=idconvert(helper,object,config=config)
108                name=helper.getText(object,'name')
109                shortName=helper.getText(object,'abbreviation')
110                collection.append((uri,name,shortName))
111            result[names[alist]]=collection
112    return result
113           
114class DataEntity:
115    def __init__(self,helper,element):
116        ''' Attempt to instantiate this stubB as a data entity'''
117        self.elem=element
118        self.helper=helper
119        #just one curator
120        self.curator=dgContact(self.elem.find('dgDataRoles/dgDataCurator'),ctype='organisation')
121        #possibly multiple creators
122        self.creators=[dgContact(i) for i in self.elem.findall('dgDataRoles/dgDataCreator')]
123        host,service = '','' # dummy for now
124        #possibly multiple granules
125        self.getGranules()
126        #bounding box, handled as a class because this is going to be difficult ...
127        self.bbox=Bounding(self.elem,entity='stubB')
128        self.timeCoverage=self.temporal()
129        print 'BOUNDING',self.bbox,self.timeCoverage
130        #parameters
131        plist=wrapGetText(self.elem,'dgDataSummary/dgParameterSummary/ParameterName',multiple=1)
132        self.parameters=collapse2(plist,split='/')
133        self.hdg='Data Entity'
134             
135       
136    def getGranules(self):
137        ''' Load up the granule content within the entity '''
138        granList=self.elem.findall('dgDataGranule')
139        self.granules=[]
140        i=0
141        for item in granList:
142            i+=1
143            #following needs to be refactored when granule definition includes a proper name ...
144            name=wrapGetText(item,'dgGranuleSummary/dgGranuleName')
145            if name=='': name='Granule %s'%i
146            self.granules.append(dataGranule(self.helper,item,self.config,name=name))
147               
148    def temporal(self):
149        '''Instantiate the timeCoverage attribute by parsing for temporal coverage '''
150        t=self.elem.find('dgDataSummary/dgDataCoverage/dgTemporalCoverage/DateRange')
151        if t is not None:
152            c=[self.helper.getText(t,'DateRangeStart'),]
153            c.append(self.helper.getText(t,'DateRangeEnd'))
154        else:
155            c=[self.helper.getText(self.elem,
156                    'dgDataSummary/dgDataCoverage/dgTemporalCoverage/DateSingle'),'']
157        c.append(self.helper.getText(self.elem,'dgDataSummary/dgDatasetStatus/dgDatasetClosure'))
158        return c
159
160class dgMetadataDescription:
161   
162    def __init__(self,helper,elem,viewService):
163        ''' Initialise a Metadata Description '''
164        n=idconvert(helper,elem)
165        self.uri=n.uri
166        self.logo=None
167        self.abstract=helper.getText(elem,'abstract/abstractText')
168        self.texts=[]
169        self.onlineRefs=[]
170        for e in helper.findall(elem,'descriptionSection'):
171            self.texts.append((helper.getText(e,'dgDescriptionText'),helper.getText(e,'contentType')))
172        online=helper.findall(elem,'descriptionSection/descriptionOnlineReference/dgSimpleLink')
173        for o in online:
174            rtype=helper.getText(o,'name')
175            #url and uri supported in 1.4 moles, but no one has implemented that yet ...
176            uri,url=helper.getText(o,'URI'),helper.getText(o,'URL')
177            if rtype=='Logo':
178                self.logo=uri
179            else:
180                try:
181                    value=help
182                    self.onlineRefs.append((rtype,{'NumSim':'%s/%s'%(viewService,uri)}[rtype]))
183                except KeyError:
184                    self.onlineRefs.append((rtype,uri))
185
186
187class stubB(DataEntity,ObservationStation,DataProductionTool,Activity):
188       
189        ''' Holds the stub-b document and provides methods which get and manipulate it '''
190       
191        def __init__(self,elem,config):
192               
193                '''Instantiate with an element tree elem '''
194               
195                self.tree=elem
196                self.metadataType='NDG-B1'
197                self.services=[]
198                self.config=config
199                self.citation=''
200                self.personnel=[] # for DIF compatiability for the moment.
201                self.parameters=None
202                self.granules=[]
203                self.logos=[]
204               
205               
206                try:
207                        helper=nsdumb(self.tree)
208                        self.name=helper.getText(self.tree,'name')
209                except Exception,e:
210                        raise ValueError('Error instantiating stubB [%s]'%e)
211
212                self.ndgObject=idconvert(helper,self.tree,self.config)
213                self.entryID=self.ndgObject.uri
214                self.viewService=self.ndgObject.viewService
215               
216                #Note that the root of the ElementTree instance is dgMetadataRecord
217                #so we don't need (or want) that in our xpath expressions.
218               
219                self.constraints=AccessControl(helper.find(self.tree,'dgMetadataSecurity'))
220                self.abbreviation=helper.getText(self.tree,'abbreviation')
221                if self.abbreviation=='': self.abbreviation=self.name[0:min(15,len(self.name))]
222                logos=helper.findall(self.tree,'dgMetadata/dgMetadatdataRecord/logos/logoURI')
223                for l in logos:
224                    self.logos.append((helper.find(l,'dgSimpleLink/name'),
225                                       helper.find(l,'dgSimpleLink/URI')))
226               
227                for i in ('dgDataEntity','dgActivity','dgDataProductionTool','dgObservationStation'):
228                    elem=helper.find(self.tree,i)
229                    if elem is not None: break
230                if elem is None:
231                    raise ValueError('StubB record does not contain an Activity, DE, DPT, ObsStn')
232                elif elem.tag=='dgDataEntity':
233                        DataEntity.__init__(self,helper,elem)
234                elif elem.tag=='dgActivity':
235                        Activity.__init__(self,helper,elem)
236                elif elem.tag=='dgDataProductionTool':
237                        DataProductionTool.__init__(self,helper,elem)
238                elif elem.tag=='dgObservationStation':
239                        ObservationStation.__init__(self,helper,elem)
240
241                self.description=dgMetadataDescription(
242                    helper,helper.find(self.tree,'dgMetadataDescription'),self.viewService)
243                if self.description.logo is not None:
244                    self.logos.append((('Logo',self.description.logo)))
245                    print 'LOGOS',self.logos
246                self.abstract=self.description.abstract
247                self.stubBtype=elem.tag
248               
249                # now go get all the related links
250               
251                self.related=Deployments(helper.find(elem,'DeploymentSummary'),helper,self.config)
252
253
254if __name__=="__main__":
255    import unittest
256    import os.path
257   
258    de='examples/badc.nerc.ac.uk__NDG-B1__dataent_chablis.xml'
259    dpt='examples/badc.nerc.ac.uk__NDG-B1__dpt_11634276941110630.xml'
260   
261    class TestCase(unittest.TestCase):
262   
263            def testDE(self):
264                ''' Test rendering a DataEntity stubB '''
265                fname=de
266                self.doit(fname)
267               
268            def testDPT(self):
269                ''' Test rendering a Data Production Tool stubB '''
270                fname=dpt
271                self.doit(fname)
272               
273               
274            def doit(self,fname):
275                xml=open(fname,'r').read()
276                config=myConfig('ndgDiscovery.config')
277                layoutdir=config.get('layout','layoutdir')
278                x=stubB(xml,config)
279                y='''<?xml version="1.0" encoding="UTF-8"?>
280                    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
281                    <html xmlsns="http://www.w3.org/1999/xhtml" xml:lang="en">
282                            <head>
283                                    <META http-equiv="Content-Type" content="text/xhtml; charset=iso-8859-1"/>
284                                    <title>stubB</title>
285                                    <LINK media="all, screen" href="%s/layout/ndg.css" type="text/css" rel="stylesheet"/>
286                            </head> '''%layoutdir+x.toHTML(config)
287                ff=fname+'-output.html'
288                f=file(ff,'w')
289                f.write(y)
290               
291   
292    unittest.main()
293           
294           
Note: See TracBrowser for help on using the repository browser.