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

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

A whole raft of modifications

  • changing to the NERC icons
  • search support within Browse and NumSim
  • NumSim V10 support in viewing
  • older numsim docs will now not be found and displayed properly (which means a lot of updating is needed)
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.timeCoverage=self.temporal()
122        print 'BOUNDING',self.bbox,self.timeCoverage
123        #parameters
124        plist=wrapGetText(self.elem,'dgDataSummary/dgParameterSummary/ParameterName',multiple=1)
125        self.parameters=collapse2(plist,split='/')
126       
127       
128    def getGranules(self):
129        ''' Load up the granule content within the entity '''
130        granList=self.elem.findall('dgDataGranule')
131        self.granules=[]
132        i=0
133        for item in granList:
134            i+=1
135            #following needs to be refactored when granule definition includes a proper name ...
136            name=wrapGetText(item,'dgGranuleSummary/dgGranuleName')
137            if name=='': name='Granule %s'%i
138            self.granules.append(dataGranule(self.helper,item,self.config,name=name))
139               
140    def temporal(self):
141        '''Instantiate the timeCoverage attribute by parsing for temporal coverage '''
142        t=self.elem.find('dgDataSummary/dgDataCoverage/dgTemporalCoverage/DateRange')
143        if t is not None:
144            c=[self.helper.getText(t,'DateRangeStart'),]
145            c.append(self.helper.getText(t,'DateRangeEnd'))
146        else:
147            c=[self.helper.getText(self.elem,
148                    'dgDataSummary/dgDataCoverage/dgTemporalCoverage/DateSingle'),'']
149        c.append(self.helper.getText(self.elem,'dgDataSummary/dgDatasetStatus/dgDatasetClosure'))
150        return c
151
152class dgMetadataDescription:
153   
154    def __init__(self,helper,elem,viewService):
155        ''' Initialise a Metadata Description '''
156        n=idconvert(helper,elem)
157        self.uri=n.uri
158        self.logo=None
159        self.abstract=helper.getText(elem,'abstract/abstractText')
160        self.texts=[]
161        self.onlineRefs=[]
162        for e in helper.findall(elem,'descriptionSection'):
163            self.texts.append((helper.getText(e,'dgDescriptionText'),helper.getText(e,'contentType')))
164        online=helper.findall(elem,'descriptionSection/descriptionOnlineReference/dgSimpleLink')
165        for o in online:
166            rtype=helper.getText(o,'name')
167            #url and uri supported in 1.4 moles, but no one has implemented that yet ...
168            uri,url=helper.getText(o,'URI'),helper.getText(o,'URL')
169            if rtype=='Logo':
170                self.logo=uri
171            else:
172                try:
173                    value=help
174                    self.onlineRefs.append((rtype,{'NumSim':'%s/%s'%(viewService,uri)}[rtype]))
175                except KeyError:
176                    self.onlineRefs.append((rtype,uri))
177
178
179class stubB(DataEntity,ObservationStation,DataProductionTool,Activity):
180       
181        ''' Holds the stub-b document and provides methods which get and manipulate it '''
182       
183        def __init__(self,elem,config):
184               
185                '''Instantiate with an element tree elem '''
186               
187                self.tree=elem
188                self.metadataType='NDG-B1'
189                self.services=[]
190                self.config=config
191                self.citation=''
192                self.personnel=[] # for DIF compatiability for the moment.
193                self.parameters=None
194                self.granules=[]
195                self.logos=[]
196               
197               
198                try:
199                        helper=nsdumb(self.tree)
200                        self.name=helper.getText(self.tree,'name')
201                except Exception,e:
202                        raise ValueError('Error instantiating stubB [%s]'%e)
203
204                self.ndgObject=idconvert(helper,self.tree,self.config)
205                self.entryID=self.ndgObject.uri
206                self.viewService=self.ndgObject.viewService
207               
208                #Note that the root of the ElementTree instance is dgMetadataRecord
209                #so we don't need (or want) that in our xpath expressions.
210               
211                self.constraints=AccessControl(helper.find(self.tree,'dgMetadataSecurity'))
212                self.abbreviation=helper.getText(self.tree,'abbreviation')
213                if self.abbreviation=='': self.abbreviation=self.name[0:min(15,len(self.name))]
214                logos=helper.findall(self.tree,'dgMetadata/dgMetadatdataRecord/logos/logoURI')
215                for l in logos:
216                    self.logos.append((helper.find(l,'dgSimpleLink/name'),
217                                       helper.find(l,'dgSimpleLink/URI')))
218               
219                for i in ('dgDataEntity','dgActivity','dgDataProductionTool','dgObservationStation'):
220                    elem=helper.find(self.tree,i)
221                    if elem is not None: break
222                if elem is None:
223                    raise ValueError('StubB record does not contain an Activity, DE, DPT, ObsStn')
224                elif elem.tag=='dgDataEntity':
225                        DataEntity.__init__(self,helper,elem)
226                elif elem.tag=='dgActivity':
227                        Activity.__init__(self,helper,elem)
228                elif elem.tag=='dgDataProductionTool':
229                        DataProductionTool.__init__(self,helper,elem)
230                elif elem.tag=='dgObservationStation':
231                        ObservationStation.__init__(self,helper,elem)
232
233                self.description=dgMetadataDescription(
234                    helper,helper.find(self.tree,'dgMetadataDescription'),self.viewService)
235                if self.description.logo is not None:
236                    self.logos.append((('Logo',self.description.logo)))
237                    print 'LOGOS',self.logos
238                self.abstract=self.description.abstract
239                self.stubBtype=elem.tag
240             
241                # now go get all the related links
242               
243                self.related=Deployments(helper.find(elem,'DeploymentSummary'),helper,self.config)
244
245
246if __name__=="__main__":
247    import unittest
248    import os.path
249   
250    de='examples/badc.nerc.ac.uk__NDG-B1__dataent_chablis.xml'
251    dpt='examples/badc.nerc.ac.uk__NDG-B1__dpt_11634276941110630.xml'
252   
253    class TestCase(unittest.TestCase):
254   
255            def testDE(self):
256                ''' Test rendering a DataEntity stubB '''
257                fname=de
258                self.doit(fname)
259               
260            def testDPT(self):
261                ''' Test rendering a Data Production Tool stubB '''
262                fname=dpt
263                self.doit(fname)
264               
265               
266            def doit(self,fname):
267                xml=open(fname,'r').read()
268                config=myConfig('ndgDiscovery.config')
269                layoutdir=config.get('layout','layoutdir')
270                x=stubB(xml,config)
271                y='''<?xml version="1.0" encoding="UTF-8"?>
272                    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
273                    <html xmlsns="http://www.w3.org/1999/xhtml" xml:lang="en">
274                            <head>
275                                    <META http-equiv="Content-Type" content="text/xhtml; charset=iso-8859-1"/>
276                                    <title>stubB</title>
277                                    <LINK media="all, screen" href="%s/layout/ndg.css" type="text/css" rel="stylesheet"/>
278                            </head> '''%layoutdir+x.toHTML(config)
279                ff=fname+'-output.html'
280                f=file(ff,'w')
281                f.write(y)
282               
283   
284    unittest.main()
285           
286           
Note: See TracBrowser for help on using the repository browser.