source: TI07-MOLES/trunk/PythonCode/wsgi/stubB.py @ 2487

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

Modifications to support cut-down stub-b xquery.
Slight rearrangement of page positioning in discovery. (Needs CSS
support)

RevLine 
[1925]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# BNL April 2006
6#
7from renderEntity import renderEntity
8from Utilities import *
9from AccessControl import AccessControl
10from geoUtilities import Bounding
11from People import *
[2371]12from ndgObject import ndgObject
13from xmlHandler import xmlHandler
[2487]14from DeploymentHandling import *
[2045]15try: #python 2.5
16    from xml.etree import ElementTree as ET
17except ImportError:
18    try:
19        # if you've installed it yourself it comes this way
20        import ElementTree as ET
21    except ImportError:
22        # if you've egged it this is the way it comes
23        from elementtree import ElementTree as ET
[1925]24
[2371]25def idconvert(helper,elem,config=None):
26    ''' Given an elementTree element for a dgMetadataID, create
27    a standard ndg URI, and produce an ndgObject '''
28    id=helper.find(elem,'dgMetadataID')
29    entryID='%s__%s__%s'%(helper.getText(id,'repositoryIdentifier'),
30                            helper.getText(id,'schemeIdentifier'),
31                            helper.getText(id,'localIdentifier'))
32    uri=ndgObject(entryID,config)
33    return uri
34
[2379]35class ndgLink:
36    ''' This is a holder for an ndgObject which has a name (and possibly abbreviation) '''
[2380]37    def __init__(self,name,abbrev,ndgO,label='',image=None):
[2379]38        self.ndgObject=ndgO
39        self.name=name
40        self.abbrev=abbrev
[2380]41        self.image=image
42        self.label=label
43        self.URL=ndgO.BURL
[2379]44    def toHTML(self):
45        ### needs to be finished
46        return self.ndgObject.URL
47
[1925]48class dataGranule:
49        ''' Provides support for data granule structures '''
[2371]50        def __init__(self,helper,elem,config,name=''):
51            self.elem=elem
52            self.constraints=AccessControl(helper.find(elem,'accessControlPolicy'))
53            self.name=name
54            self.uri=idconvert(helper,elem,config)
55            self.entryID=self.uri.uri
56
[1925]57class ObservationStation:
58    def __init__(self,e):
59        self.e=e
60        if e is None: return
61class DataProductionTool:
62    def __init__(self,e):
63        self.e=e
64        if e is None: return
65class Activity:
66    def __init__(self,e):
67        self.e=e
68        if e is None: return
[2487]69       
[1925]70       
71class DataEntity:
[2371]72    def __init__(self,helper,element):
73        ''' Attempt to instantiate this stubB as a data entity'''
74        self.elem=element
75        self.helper=helper
76        #just one curator
77        self.curator=dgContact(self.elem.find('dgDataRoles/dgDataCurator'),ctype='organisation')
78        #possibly multiple creators
79        self.creators=[dgContact(i) for i in self.elem.findall('dgDataRoles/dgDataCreator')]
80        host,service = '','' # dummy for now
81        #possibly multiple granules
82        self.getGranules()
83        #bounding box, handled as a class because this is going to be difficult ...
84        self.bbox=Bounding(self.elem,entity='stubB')
85        self.temporal()
86        #parameters
87        self.parameters=wrapGetText(self.elem,'dgDataSummary/dgParameterSummary/ParameterName',multiple=1)
88       
89    def getGranules(self):
90        ''' Load up the granule content within the entity '''
91        granList=self.elem.findall('dgDataGranule')
92        self.granules=[]
93        i=0
94        for item in granList:
95            i+=1
96            #following needs to be refactored when granule definition includes a proper name ...
97            name=wrapGetText(item,'name')
98            if name=='': name='Granule %s'%i
99            self.granules.append(dataGranule(self.helper,item,self.config,name=name))
[1925]100               
[2371]101    def temporal(self):
102        '''Instantiate the timeCoverage attribute by parsing for temporal coverage '''
103        t=self.elem.find('dgDataSummary/dgDataCoverage/dgTemporalCoverage/DateRange')
104        if t is not None:
105           try:
106                self.timeCoverage=(float(i.text) for i in t)
107           except:
108                self.timeCoverage=('',)
[1925]109                               
[2371]110        else:
111           t=self.elem.find('dgDataSummary/dgDataCoverage/dgTemporalCoverage/DateSingle')
112           try:
113                self.timeCoverage=(t.text,)
114           except:
115                self.timeCoverage=('',)
[1925]116
[2379]117class dgMetadataDescription:
118   
119    def __init__(self,helper,elem):
120        ''' Initialise a Metadata Description '''
121        n=idconvert(helper,elem)
122        self.uri=n.uri
123        self.abstract=helper.getText(elem,'abstract/abstractText')
124        self.description=helper.getText(elem,'descriptionSection/dgDescriptionText')
125        self.descriptionType=helper.getText(elem,'descriptionSection/contentType')
126        online=helper.findall(elem,'descriptionSection/descriptionOnlineReference/dgSimpleLink')
127        self.onlineRefs=[]
128        for o in online:
129            self.onlineRefs.append((helper.getText(o,'name'),helper.getText(o,'URI')))
[1925]130
131
132class stubB(DataEntity,Deployment,ObservationStation,DataProductionTool,Activity):
133       
134        ''' Holds the stub-b document and provides methods which get and manipulate it '''
135       
136        def __init__(self,xml,config):
137               
138                '''Instantiate by parsing an xml document passed in as a string '''
139               
[2380]140                self.metadataType='NDG-B1'
[1925]141                self.services=[]
142                self.config=config
[2392]143                self.citation=''
[2422]144                self.personnel=[] # for DIF compatiability for the moment.
[1925]145               
[2364]146                try:
[1925]147                        self.xml=xml
[2371]148                        self.xh=xmlHandler(xml,string=1)
149                        self.tree=self.xh.tree
150                        helper=nsdumb(self.tree)
151                        self.name=helper.getText(self.tree,'name')
[2364]152                except Exception,e:
153                        raise ValueError('Error instantiating stubB [%s]'%e)
[2371]154
155                self.ndgObject=idconvert(helper,self.tree,self.config)
[2379]156                self.entryID=self.ndgObject.uri
157               
[1925]158                #Note that the root of the ElementTree instance is dgMetadataRecord
159                #so we don't need (or want) that in our xpath expressions.
160               
[2371]161                self.constraints=AccessControl(helper.find(self.tree,'dgMetadataSecurity'))
162                self.abbreviation=helper.getText(self.tree,'abbreviation')
[1925]163                if self.abbreviation=='': self.abbreviation=self.name[0:min(15,len(self.name))]
[2379]164               
165                for i in ('dgDataEntity','dgActivity','dgDataProductionTool','dgObservationStation'):
166                    elem=helper.find(self.tree,i)
167                    if elem is not None: break
168                if elem is None:
[2386]169                    f=file('tmp.xml','w')
170                    f.write(self.xml)
171                    f.close()
[2379]172                    raise ValueError('StubB record does not contain an Activity, DE, DPT, ObsStn')
173                elif elem.tag=='dgDataEntity':
[2371]174                        DataEntity.__init__(self,helper,elem)
[1925]175                        self.type='dgDataEntity'
176                        self.others=('activity','observationstation','dataproductiontool')
[2379]177                        related='RelatedDeployment'
178                elif elem.tag=='dgActivity':
[1925]179                        self.type='dgActivity'
180                        #nb activity stub-b seems to have dataentity instead of dataEntity
181                        self.others=('dataentity','dataEntity','observationstation','dataproductiontool')
[2379]182                        related='ActivityDeployment'
183                elif elem.tag=='dgDataProductionTool':
[1925]184                        self.type='dgDataProductionTool'
185                        self.others=('dataEntity','observationstation','activity')
186                        related='DPTDeployment'
[2379]187                elif elem.tag=='dgObservationStation':
188                        related='ObsStnDeployment'
[1925]189                        self.type='dgObservationStation'
190                        self.others=('dataEntity','dataproductiontool','activity')
191
[2379]192                self.description=dgMetadataDescription(helper,helper.find(self.tree,'dgMetadataDescription'))
193                self.abstract=self.description.abstract
[2380]194                self.stubBtype=elem.tag
[2379]195             
[1925]196                # now go get all the related links
[2487]197                #old stub-B:
198                #self.related=[]
199                #for d in helper.findall(elem,related):
200                #    self.related.append(Deployment(helper,d,self.others,self.config))
201                #stripped-B:
202                #self.related=Deployments(helper,helper.findall(elem,related))
203                self.related=Deployments(helper,elem.tag,self.config)
204                print elem.tag
205                for e in helper.findall(elem,related):
206                    print e.tag
207                    self.related.add(e)
[2379]208
[1925]209        def toHTML(self,config):
210            if self.tree is not None:
211                renderer=renderEntity(config)
212                return renderer.render(self)
213            else:
214                return '<p>No Valid Stub-B</p>'
[2379]215           
[2487]216import unittest
217import os.path
218
219de='examples/badc.nerc.ac.uk__NDG-B1__dataent_chablis.xml'
220dpt='examples/badc.nerc.ac.uk__NDG-B1__dpt_11634276941110630.xml'
221
222class TestCase(unittest.TestCase):
223
224        def testDE(self):
225            ''' Test rendering a DataEntity stubB '''
226            fname=de
227            self.doit(fname)
228           
229        def testDPT(self):
230            ''' Test rendering a Data Production Tool stubB '''
231            fname=dpt
232            self.doit(fname)
233           
234           
235        def doit(self,fname):
236            xml=open(fname,'r').read()
237            config=myConfig('ndgDiscovery.config')
238            x=stubB(xml,config)
239            y='''<?xml version="1.0" encoding="UTF-8"?>
[1925]240                <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
241                <html xmlsns="http://www.w3.org/1999/xhtml" xml:lang="en">
242                        <head>
243                                <META http-equiv="Content-Type" content="text/xhtml; charset=iso-8859-1"/>
244                                <title>stubB</title>
245                                <LINK media="all, screen" href="../layout/style.css" type="text/css" rel="stylesheet"/>
[2379]246                        </head> '''+x.toHTML(config)
[2487]247            ff=fname+'-output.html'
248            f=file(ff,'w')
249            f.write(y)
250           
251if __name__=="__main__":
252    unittest.main()
253           
254           
Note: See TracBrowser for help on using the repository browser.