source: TI07-MOLES/trunk/PythonCode/existInterface/eXistGeneralInterface.py @ 1449

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI07-MOLES/trunk/PythonCode/existInterface/eXistGeneralInterface.py@1449
Revision 1449, 6.7 KB checked in by domlowe, 13 years ago (diff)

added new file eXistGenericInterface.py with getXMLRecord() method to get any type of XML record from exist using collection/id

Line 
1# Code inspired by example on eXist website.
2import urllib2, base64, urllib, urlparse, httplib, xmlrpclib, types
3
4class   InstanceObject(object):
5    def __init__(self, **kw):
6        self.dict={}
7        self.dict.update(kw)
8    def __getattr__(self,arg):
9        return self.dict[arg]
10
11class  eXist_Connector(object):
12    """Access class for eXist"""
13    def __init__(self,constants=None):
14        ''' Instantiates the eXist connector using supplied constants '''
15        if constants is None: raise 'NoExistConstants'
16        authinfo = urllib2.HTTPPasswordMgrWithDefaultRealm()
17        authinfo.add_password(None,
18                                  constants.host,
19                                  constants.userid,
20                                  constants.password)
21        authHandler = urllib2.HTTPBasicAuthHandler(authinfo)
22        opener = urllib2.build_opener(authHandler)
23        s = constants.userid+':'+constants.password
24        z = base64.encodestring(s)[:-1] # strip trailing 12
25        opener.addheaders.append(('Authorization', 'Basic %s' % z))
26        self.http_headers = {'Authorization':'Basic %s' % z}
27        self.opener = opener
28        # also create an xmlrpc Server object
29       
30        xmlrpc_uri = '%s%s:%s@%s:%d%s' % ( 
31                                            'http://',
32                                            constants.userid,
33                                            constants.password,
34                                            constants.host,
35                                            constants.port,
36                                            constants.xmlrpc_base_path
37                                        )
38        print xmlrpc_uri
39        self.xmlrpc = xmlrpclib.Server(xmlrpc_uri)
40
41    def executeQuery(self, xquery, params={}):
42        '''Execute an xquery string, return session and summary information'''
43        xquery=xmlrpclib.Binary(xquery)
44        id = self.xmlrpc.executeQuery(xquery, params)
45        summary = self.xmlrpc.querySummary(id)
46        return id,summary
47
48    def release(self,id):
49        ''' Release an executeQuery session '''
50        self.xmlrpc.releaseQueryResult(id)
51       
52    def retrieve(self,id,pos,params={}):
53        ''' Retrieve a specific document from an executeQuery result set '''
54        return self.xmlrpc.retrieve(id,pos,params).data
55 
56    def executeChunkedQuery(self,xquery,start,number,params={}):
57        ''' Execute a query, return a specific part of the result set, and
58        dump the session automagically '''
59        xquery=xmlrpclib.Binary(xquery)
60        r=self.xmlrpc.query(xquery,number,start,params)
61        return r
62       
63class ndg_eXist(eXist_Connector):
64    ''' Adds ndg methods to a "standard" exist Connector '''
65    def __init__(self,myhost='localhost'):
66        f=file('passwords.txt','r')
67        pw={}
68        for line in f.readlines():
69            host,userid,password=line.strip().split(' ')
70            pw[host]=(userid,password)
71        eXistConstants = InstanceObject(host=myhost,
72                                userid=pw[myhost][0],
73                                password=pw[myhost][1],
74                                base_path="/exist/servlet",
75                                xmlrpc_base_path="/exist/xmlrpc",
76                                port=8080)
77       
78        eXist_Connector.__init__(self,eXistConstants)
79        self.ids={}
80       
81    def __buildquery(self,query,target):
82        '''Create an NDG full text query '''
83        s="//%s[. &='%s']"%(target,query)
84        return s#xmlrpclib.Binary(s)
85
86    def __buildParamSearch(self,param,value,target):
87        s="for $x in document()//%s where $x[.%s &= '%s'] return $x"%(target,param,value)
88        return s
89
90    def full_text(self,query,target='DIF'):
91        ''' Carry out a full text search within the "target" collection '''
92        id,summary=self.executeQuery(self.__buildquery(query,target))
93        self.ids[id]=0
94        return id,summary
95
96    def retrieveNext(self,id):
97        ''' Takes a sessionID from an existing query and gets the next document '''
98        try:
99            r=self.retrieve(id, self.ids[id])
100            self.ids[id]+=1
101            return r
102        except xmlrpclib.Fault:
103            return None
104        except KeyError:
105            return None
106   
107    def sessionRelease(self,id):
108        ''' Releases a session and removes the position counter '''
109        try:
110            self.release(id)
111            del self.ids[id]
112            return 1
113        except:
114            return 0
115   
116    def chunkedFullText(self,query,target='DIF',start=1,number=10):
117        ''' Execute a chunked full text query and return the result
118        set '''
119        return self.executeChunkedQuery(self.__buildquery(query,target),start,number,params={})
120   
121   
122    def getDIF(self,entryID):
123        ''' Get a specific DIF document from a repository by using the entryID '''
124        xq='''for $DE in collection('/db/dif')/DIF[Entry_ID='%s'] return $DE'''%entryID
125        xquery='''for $DE in collection('/db/dif')/DIF[Entry_ID='%s'] return $DE'''%entryID
126        id,summary=self.executeQuery(xq)#xquery)
127        if summary['hits']==1:
128            r=self.retrieve(id,0,{})
129            self.sessionRelease(id)
130        else:
131            r='none'
132        return r
133       
134    def getXMLRecord(self,collID,IDdefinition,itemID):
135        ''' Get a specific document from a collection in a repository by using the collection name and entryID '''
136        xq='''for $DE in collection('%s')/*[%s='%s'] return $DE'''%(collID,IDdefinition,itemID)
137        id,summary=self.executeQuery(xq)
138        if summary['hits']==1:
139            r=self.retrieve(id,0,{})
140            self.sessionRelease(id)
141        else:
142            r='none'
143        return r
144if __name__=="__main__":
145   
146    existDB=ndg_eXist()
147    #gepidaeDB=ndg_eXist(myhost='gepidae.esc.rl.ac.uk')
148   
149    #these both work fine
150    id,summary=existDB.full_text('coapec')
151    print 'GLUE:',summary
152    #id,summary=gepidaeDB.full_text('coapec')
153    #print 'GEPIDAE: ',summary
154   
155    #we can retrieve them all and look at them ...
156    r=1
157    while r is not None:
158        r=existDB.retrieveNext(id)
159        #if r is not None: print r
160    existDB.release(id)
161    #gepidaeDB.release(id)
162    print 'done simple'
163   
164    #now try and get the DIF documents alone:
165    #works fine: print gepidaeDB.getDIF('badc.nerc.ac.uk:DIF:dataent10')
166    print existDB.getDIF('badc.nerc.ac.uk:DIF:dataent12')
167    print 'done getDif'
168   
169    print existDB.getXMLRecord('/db/dif','Entry_ID','badc.nerc.ac.uk:DIF:dataent12')
170    print 'done getXMLRecord (DIF)'
171   
172    print existDB.getXMLRecord('/db/ndg_B_metadata','dgMetadataRecord/dgMetadataID/localIdentifier','dataent50')
173    print 'done getXMLRecord (MOLES)'
174    #print existDB.chunkedFullText('badc')
175   
176   
Note: See TracBrowser for help on using the repository browser.