source: TI07-MOLES/trunk/StubB/XSLT/browse/portal/cgi/browse/ServiceBinding.py @ 1173

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI07-MOLES/trunk/StubB/XSLT/browse/portal/cgi/browse/ServiceBinding.py@1173
Revision 1173, 7.3 KB checked in by lawrence, 13 years ago (diff)

Handling selection and browse history better ...

Line 
1#
2# There are (at least) two classes of service map issues which NDG needs to support.
3# Firstly, one can expect that given a specific NDG record, there is a native
4# service for that record ... eg. for an A record, the native service is the
5# data extractor, but there may be others ... at some point we need to be
6# able to find those out (this is a processing affordance issue, and something
7# that we want to use registries for) ... anyway, meanwhile, we have these "native"
8# service types.
9# Secondly, in D  we have related URL's, which are essentially mappings to
10# services which may exist on the dataset described by that D-catalogue record.
11# This is a special case of the generic case described above ...
12#
13# This module provides classes to support these activities.
14
15from Utilities import wrapGetText, myConfig, DIFid2NDGid
16from htmlUtilities import hyperlink,image
17
18class ServiceMap(myConfig):
19    ''' This should itself eventually be a service that can be looked up, or maybe
20    even use the dns '''
21    def __init__(self,serviceFile='cgi/serviceMap.config'):
22        myConfig.__init__(self,serviceFile)
23        self.icon=self.get('RELATED','icon')
24        self.iconalt=self.get('RELATED','icon_alt')
25    def do(self,serviceType,dataProvider):
26        '''  Return an actual endpoint for a given service from the data provider, e.g.
27        for ndg_a_service,badc.nerc.ac.uk get http://superglue.badc.rl.ac.uk/cgi-bin/browse.py '''
28        serviceType=serviceType.upper() # ought to be redundant ...
29        r=self.get(serviceType,dataProvider)
30        if r is None:
31            #see if we have an icon anyway ...
32            try:
33                i,a=self.get(serviceType,'icon'),self.get(serviceType,'icon_alt')
34                if (i,a)!=(None,None):self.icon,self.iconalt=i,a
35            except: pass
36               
37            # just return the URL
38            if dataProvider[0:4]!='http':
39                return 'http://%s'%dataProvider
40            else: return dataProvider
41        else:
42            # this is a service type known to ndg, so we have constructed an endpoint
43            self.icon=self.get(serviceType,'icon')
44            self.iconalt=self.get(serviceType,'icon_alt')
45            return r
46       
47class Service:
48    ''' This simple class simply holds the service information known in a DIF ''' 
49    def __init__(self):
50        self.type='dif_related_url'
51        self.name=''
52        self.url=''
53        self.description=''
54
55class ServiceBinding (Service):
56        ''' Given a specific NDG id, we can go from the scheme identifier to the
57        native service which one expects to be able to operate upon it, for example,
58        an NDG-A type identifier should expect the NDG-A-Service running at the
59        specific repository. Note that we support the NDG id in one of two formats:
60            nativeID is an elementTree object from an xml form, and
61            entryID is a repository:scheme:localidentifier string  '''
62        def __init__(self,n='',nativeID=None,entryID=None,serviceFile='cgi/serviceMap.config',uri='local'):
63            Service.__init__(self)
64            # regrettably we used different things in our ID's than we did in
65            # our difs :
66            self.mapping={'NDG-A0':'NDG_A_SERVICE','NDG-B0':'NDG_B_SERVICE',
67            'NDG-B1':'NDG_B_SERVICE','DIF':'DISCOVERY'}
68            self.serviceMap=ServiceMap(serviceFile=serviceFile)
69            self.name=n
70            if nativeID is not None: 
71                self.native(nativeID,uri=uri)
72            elif entryID is not None:
73                self.entry(entryID)
74        def entry(self,id):
75            self.native(DIFid2NDGid(id))
76        def native(self,elem,uri='local',seqno=1):
77            ''' Given an ndg id, get the native service '''
78            #e.g.
79            #<dataModelID>
80            #    <schemeIdentifier>NDG-A0</schemeIdentifier>
81            #    <repositoryIdentifier>badc.nerc.ac.uk</repositoryIdentifier>
82            #    <localIdentifier>acsoe_badc_eae96_macehead_mcf_1</localIdentifier>
83            #</dataModelID>
84            if elem is None:return 'No valid URL'
85            s=wrapGetText(elem,'schemeIdentifier')
86            r=wrapGetText(elem,'repositoryIdentifier')
87            l=wrapGetText(elem,'localIdentifier')
88            if s in self.mapping: s=self.mapping[s].upper()
89            b=self.serviceMap.do(s,r)
90            uri=self.__makeuri(s,r,l)
91            self.url=self.__makeurl(s,b,uri,seqno)
92            self.serviceType=s
93            return self
94        def related(self,elem,idelem,seqno=1):
95            ''' Given a DIF related URL, get a service binding '''
96            # e.g:
97            #<Related_URL>
98            #<URL_Content_Type>NDG_B_Service</URL_Content_Type>
99            #<URL>badc.nerc.ac.uk</URL>
100            #</Related_URL>
101            #<Related_URL>
102            #<URL>http://badc.nerc.ac.uk/browse/badc/CDs/spade9293</URL>
103            #</Related_URL>
104            self.description=wrapGetText(elem,'Description')
105            s=wrapGetText(elem,'URL_Content_Type').upper()
106            self.serviceType=s
107            if s!='':
108                r=wrapGetText(elem,'URL')
109                b=self.serviceMap.do(s,r)
110                l=wrapGetText(idelem,'localIdentifier')
111                uri=self.__makeuri(s,r,l)
112                self.url=self.__makeurl(s,b,uri,seqno)
113            else:
114                self.url=wrapGetText(elem,'URL')
115            return self
116        def __str__(self):
117            ''' return string only html link '''
118            return hyperlink(self.name,self.url)
119        def icon(self):
120            ''' return html icon linking to specific service '''
121            return hyperlink(image(self.serviceMap.icon,self.serviceMap.iconalt),self.url)
122        def __makeuri(self,s,b,l):
123            ''' Actually create the URI '''
124            if s in ('NDG_B_SERVICE','DISCOVERY'):
125                uri='%s/%s'%(b,l)
126            else:
127                uri=l
128            return uri
129        def __makeurl(self,s,b,uri,seqno):
130            ''' Actually create the URL '''
131            iType=self.serviceMap.get(s,'instance','uri')
132            if '%s' in iType: iType=iType%seqno
133            return '%s?%s=%s'%(b,iType,uri)
134           
135if __name__=="__main__":
136        import ElementTree as ET
137        s='''<dataModelID>
138                <schemeIdentifier>NDG-A0</schemeIdentifier>
139                <repositoryIdentifier>badc.nerc.ac.uk</repositoryIdentifier>
140                <localIdentifier>acsoe_badc_eae96_macehead_mcf_1</localIdentifier>
141            </dataModelID>'''
142        idelem=ET.fromstring(s)
143        n=ServiceBinding('macehead',nativeID=idelem,serviceFile='serviceMap.config')
144        maceheadServices=[n]
145        s='''<dummy><Related_URL>
146        <URL_Content_Type>NDG_B_Service</URL_Content_Type>
147        <URL>badc.nerc.ac.uk</URL>
148        </Related_URL>
149        <Related_URL>
150        <URL>http://badc.nerc.ac.uk/browse/badc/CDs/spade9293</URL>
151        </Related_URL>
152        <Related_URL>
153        <URL_Content_Type>NDG_A_Service</URL_Content_Type>
154        <URL>glue.badc.rl.ac.uk/somelongpath</URL>
155        <Description> dummy dx example </Description>
156        </Related_URL></dummy>
157        '''
158        stuff=ET.fromstring(s)
159        for x in stuff.findall('Related_URL'):
160            n=ServiceBinding('macehead',serviceFile='serviceMap.config')
161            maceheadServices.append(n.related(x,idelem))
162        for i in maceheadServices: 
163            print str(i)
164            print i.icon()
Note: See TracBrowser for help on using the repository browser.