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

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

Improvements to related URL display, in stubB and NumSim.

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=e
79        if e is None: return
80class DataProductionTool:
81    def __init__(self,h,e):
82        self.e=e
83        if e is None: return
84class Activity:
85    def __init__(self,h,e):
86        self.e=e
87        if e is None: return
88       
89def Deployments(elem,helper,config):
90    ''' This is the late June 2007 version '''
91    if elem is None: return None
92    types={'dptList':'dataproductiontool','activityList':'activity','obsStnList':'observationstation','dataEntityList':'dataentity'}
93    names={'dptList':'Data Production Tools','activityList':'Activities','obsStnList':'Observation Stations','dataEntityList':'Data Entities'}
94    result={}
95    for alist in types:
96        blist=helper.find(elem,alist)
97        collection=[]
98        if blist is not None:
99            for object in blist:
100                uri=idconvert(helper,object,config=config)
101                name=helper.getText(object,'name')
102                shortName=helper.getText(object,'abbreviation')
103                collection.append((uri,name,shortName))
104            result[names[alist]]=collection
105    return result
106           
107class DataEntity:
108    def __init__(self,helper,element):
109        ''' Attempt to instantiate this stubB as a data entity'''
110        self.elem=element
111        self.helper=helper
112        #just one curator
113        self.curator=dgContact(self.elem.find('dgDataRoles/dgDataCurator'),ctype='organisation')
114        #possibly multiple creators
115        self.creators=[dgContact(i) for i in self.elem.findall('dgDataRoles/dgDataCreator')]
116        host,service = '','' # dummy for now
117        #possibly multiple granules
118        self.getGranules()
119        #bounding box, handled as a class because this is going to be difficult ...
120        self.bbox=Bounding(self.elem,entity='stubB')
121        self.temporal()
122        #parameters
123        plist=wrapGetText(self.elem,'dgDataSummary/dgParameterSummary/ParameterName',multiple=1)
124        self.parameters=collapse2(plist,split='/')
125       
126       
127    def getGranules(self):
128        ''' Load up the granule content within the entity '''
129        granList=self.elem.findall('dgDataGranule')
130        self.granules=[]
131        i=0
132        for item in granList:
133            i+=1
134            #following needs to be refactored when granule definition includes a proper name ...
135            name=wrapGetText(item,'dgGranuleSummary/dgGranuleName')
136            if name=='': name='Granule %s'%i
137            self.granules.append(dataGranule(self.helper,item,self.config,name=name))
138               
139    def temporal(self):
140        '''Instantiate the timeCoverage attribute by parsing for temporal coverage '''
141        t=self.elem.find('dgDataSummary/dgDataCoverage/dgTemporalCoverage/DateRange')
142        if t is not None:
143           try:
144                self.timeCoverage=(float(i.text) for i in t)
145           except:
146                self.timeCoverage=('',)
147                               
148        else:
149           t=self.elem.find('dgDataSummary/dgDataCoverage/dgTemporalCoverage/DateSingle')
150           try:
151                self.timeCoverage=(t.text,)
152           except:
153                self.timeCoverage=('',)
154
155class dgMetadataDescription:
156   
157    def __init__(self,helper,elem,viewService):
158        ''' Initialise a Metadata Description '''
159        n=idconvert(helper,elem)
160        self.uri=n.uri
161        self.logo=None
162        self.abstract=helper.getText(elem,'abstract/abstractText')
163        self.texts=[]
164        self.onlineRefs=[]
165        for e in helper.findall(elem,'descriptionSection'):
166            self.texts.append((helper.getText(e,'dgDescriptionText'),helper.getText(e,'contentType')))
167        online=helper.findall(elem,'descriptionSection/descriptionOnlineReference/dgSimpleLink')
168        for o in online:
169            rtype=helper.getText(o,'name')
170            #url and uri supported in 1.4 moles, but no one has implemented that yet ...
171            uri,url=helper.getText(o,'URI'),helper.getText(o,'URL')
172            if rtype=='Logo':
173                self.logo=uri
174            else:
175                try:
176                    value=help
177                    self.onlineRefs.append((rtype,{'NumSim':'%s/%s'%(viewService,uri)}[rtype]))
178                except KeyError:
179                    self.onlineRefs.append((rtype,uri))
180
181
182class stubB(DataEntity,ObservationStation,DataProductionTool,Activity):
183       
184        ''' Holds the stub-b document and provides methods which get and manipulate it '''
185       
186        def __init__(self,elem,config):
187               
188                '''Instantiate with an element tree elem '''
189               
190                self.tree=elem
191                self.metadataType='NDG-B1'
192                self.services=[]
193                self.config=config
194                self.citation=''
195                self.personnel=[] # for DIF compatiability for the moment.
196                self.parameters=None
197                self.granules=[]
198                self.logos=[]
199               
200               
201                try:
202                        helper=nsdumb(self.tree)
203                        self.name=helper.getText(self.tree,'name')
204                except Exception,e:
205                        raise ValueError('Error instantiating stubB [%s]'%e)
206
207                self.ndgObject=idconvert(helper,self.tree,self.config)
208                self.entryID=self.ndgObject.uri
209                self.viewService=self.ndgObject.viewService
210               
211                #Note that the root of the ElementTree instance is dgMetadataRecord
212                #so we don't need (or want) that in our xpath expressions.
213               
214                self.constraints=AccessControl(helper.find(self.tree,'dgMetadataSecurity'))
215                self.abbreviation=helper.getText(self.tree,'abbreviation')
216                if self.abbreviation=='': self.abbreviation=self.name[0:min(15,len(self.name))]
217                logos=helper.findall(self.tree,'dgMetadata/dgMetadatdataRecord/logos/logoURI')
218                for l in logos:
219                    self.logos.append((helper.find(l,'dgSimpleLink/name'),
220                                       helper.find(l,'dgSimpleLink/URI')))
221               
222                for i in ('dgDataEntity','dgActivity','dgDataProductionTool','dgObservationStation'):
223                    elem=helper.find(self.tree,i)
224                    if elem is not None: break
225                if elem is None:
226                    raise ValueError('StubB record does not contain an Activity, DE, DPT, ObsStn')
227                elif elem.tag=='dgDataEntity':
228                        DataEntity.__init__(self,helper,elem)
229                elif elem.tag=='dgActivity':
230                        Activity.__init__(self,helper,elem)
231                elif elem.tag=='dgDataProductionTool':
232                        DataProductionTool.__init__(self,helper,elem)
233                elif elem.tag=='dgObservationStation':
234                        ObservationStation.__init__(self,helper,elem)
235
236                self.description=dgMetadataDescription(
237                    helper,helper.find(self.tree,'dgMetadataDescription'),self.viewService)
238                if self.description.logo is not None:
239                    self.logos.append((('Logo',self.description.logo)))
240                    print 'LOGOS',self.logos
241                self.abstract=self.description.abstract
242                self.stubBtype=elem.tag
243             
244                # now go get all the related links
245               
246                self.related=Deployments(helper.find(elem,'DeploymentSummary'),helper,self.config)
247
248
249if __name__=="__main__":
250    import unittest
251    import os.path
252   
253    de='examples/badc.nerc.ac.uk__NDG-B1__dataent_chablis.xml'
254    dpt='examples/badc.nerc.ac.uk__NDG-B1__dpt_11634276941110630.xml'
255   
256    class TestCase(unittest.TestCase):
257   
258            def testDE(self):
259                ''' Test rendering a DataEntity stubB '''
260                fname=de
261                self.doit(fname)
262               
263            def testDPT(self):
264                ''' Test rendering a Data Production Tool stubB '''
265                fname=dpt
266                self.doit(fname)
267               
268               
269            def doit(self,fname):
270                xml=open(fname,'r').read()
271                config=myConfig('ndgDiscovery.config')
272                layoutdir=config.get('layout','layoutdir')
273                x=stubB(xml,config)
274                y='''<?xml version="1.0" encoding="UTF-8"?>
275                    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
276                    <html xmlsns="http://www.w3.org/1999/xhtml" xml:lang="en">
277                            <head>
278                                    <META http-equiv="Content-Type" content="text/xhtml; charset=iso-8859-1"/>
279                                    <title>stubB</title>
280                                    <LINK media="all, screen" href="%s/layout/ndg.css" type="text/css" rel="stylesheet"/>
281                            </head> '''%layoutdir+x.toHTML(config)
282                ff=fname+'-output.html'
283                f=file(ff,'w')
284                f.write(y)
285               
286   
287    unittest.main()
288           
289           
Note: See TracBrowser for help on using the repository browser.