source: exist/trunk/python/ndgUtils/eXistConnector.py @ 4286

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/exist/trunk/python/ndgUtils/eXistConnector.py@4286
Revision 4286, 6.1 KB checked in by cbyrom, 11 years ago (diff)

Add new db structure for deployment atoms + add subtype term ID to atom.

Line 
1# Code inspired by example on eXist website.
2import urllib2, base64, urllib, urlparse, httplib, xmlrpclib, types, os, logging
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    def __str__(self):
11        return 'InstanceObject: %s '%self.dict
12       
13class edict(dict):
14    '''An extended dictionary which allows one to set and get values
15    as attributes (kudos Joe Gregorio's 1812)
16    The extended part allows you to get and set values as attributes.
17    That is,
18       d.fred
19    is the same as
20       d['fred']
21    '''
22    def __init__(self,**kw):
23        for a in kw:
24            self[a]=kw[a]
25    def __getattr__(self, key):
26        try:
27            return self.__dict__[key]
28        except KeyError:
29            pass
30        try:
31            assert not key.startswith('_')
32            return self.__getitem__(key)
33        except:
34            raise AttributeError, "object has no attribute '%s'" % key
35    def __setattr__(self, key, value):
36        if key.startswith('_'):
37            self.__dict__[key] = value
38        else:
39            return self.__setitem__(key, value)
40
41
42class eXistConnector(object):
43   
44    # default collections for the various file types in eXist
45    BASE_COLLECTION_PATH = "/db/atoms/"
46    OLD_COLLECTION_PATH = "old/"
47    PUBLISHED_COLLECTION_PATH = "Published/"
48    SMALL_P_PUBLISHED_COLLECTION_PATH = "published/"
49    WORKING_COLLECTION_PATH = "working/"
50    BACKUP_COLLECTION_PATH = "/db/atoms_backup/"
51    GRANULE_COLLECTION_PATH = "data_granules/"
52    DEPLOYMENT_COLLECTION_PATH = "deployment_data/"
53    DEPLOYMENTS_COLLECTION_PATH = "deployments/"
54    DE_COLLECTION_PATH = "data_entities/"
55    NDG_A_COLLECTION_PATH = "/db/ndg_A_metadata/"
56    NDG_A_COLLECTION_PATH_BACKUP = "/db/ndg_A_metadata_backup/"
57
58    """Access class for eXist"""
59    def __init__(self,constants=None):
60        ''' Instantiates the eXist connector using supplied constants '''
61        logging.debug("Setting up xmlrpc connection to eXist")
62        if constants is None: raise 'NoExistConstants'
63        logging.debug("Host: '%s', User: '%s'" %(constants.host, constants.userid))
64        authinfo = urllib2.HTTPPasswordMgrWithDefaultRealm()
65        authinfo.add_password(None,
66                                  constants.host,
67                                  constants.userid,
68                                  constants.password)
69        authHandler = urllib2.HTTPBasicAuthHandler(authinfo)
70        opener = urllib2.build_opener(authHandler)
71        s = constants.userid+':'+constants.password
72        z = base64.encodestring(s)[:-1] # strip trailing 12
73        opener.addheaders.append(('Authorization', 'Basic %s' % z))
74        self.http_headers = {'Authorization':'Basic %s' % z}
75        self.opener = opener
76        # also create an xmlrpc Server object
77       
78        xmlrpc_uri = '%s%s:%s@%s:%d%s' % ( 
79                                            'http://',
80                                            constants.userid,
81                                            constants.password,
82                                            constants.host,
83                                            constants.port,
84                                            constants.xmlrpc_base_path
85                                        )
86        self.xmlrpc = xmlrpclib.Server(xmlrpc_uri)
87        logging.debug("xmlrpc connection set up")
88
89
90    def executeQuery(self, xquery, params={}):
91        '''Execute an xquery string, return session and summary information'''
92        logging.debug("Executing xquery on eXist:\n%s" %xquery)
93        xquery=xmlrpclib.Binary(str(xquery))
94        id = self.xmlrpc.executeQuery(xquery, params)
95        summary = self.xmlrpc.querySummary(id)
96        logging.debug("XQuery executed")
97        return id,summary
98
99    def release(self,id):
100        ''' Release an executeQuery session '''
101        self.xmlrpc.releaseQueryResult(id)
102       
103    def retrieve(self,id,pos,params={}):
104        ''' Retrieve a specific document from an executeQuery result set '''
105        logging.debug("Retrieving document from eXist...")
106        xml = self.xmlrpc.retrieve(id,pos,params).data
107        logging.debug("Document retrieved.")
108        return xml
109 
110    def executeChunkedQuery(self,xquery,start,number,params={}):
111        ''' Execute a query, return a specific part of the result set, and
112        dump the session automagically '''
113        xquery=xmlrpclib.Binary(xquery)
114        r=self.xmlrpc.query(xquery,number,start,params)
115        return r
116   
117    def querySummary(self,id):
118        ''' Returns a summary of query results for the result-set referenced by id (which was returned by a previous query '''
119        return self.xmlrpc.querySummary(id)
120   
121    def getHits(self,id):
122        ''' Return the number of hits associated with the query that created session id '''
123        return self.xmlrpc.getHits(id)
124   
125    def getDoc(self,collectionName,documentName):
126        '''
127    Lightweight interface to the getDocument method
128    '''
129    # atoms have a more structured collection directory - as a result
130    # AtomList.xq returns the full path to the listed docs - so avoid
131    # concat'ing the collectionName for these
132        if documentName.startswith(collectionName):
133            name = documentName
134        else:
135            name='%s/%s'%(collectionName,documentName)
136        r=self.xmlrpc.getDocumentAsString(name,{})
137        return r
138   
139    def removeCollection(self,collectionPath):
140        ''' Remove a collection in the eXist database '''
141        r=self.xmlrpc.removeCollection(collectionPath)
142        return r
143   
144    def removeDoc(self, docPath):
145        ''' Remove a document from the eXist database '''
146        r=self.xmlrpc.remove(docPath)
147        return r
148   
149    def createCollection(self,collectionPath):
150        ''' Create a collection in the eXist database at collectionPath '''
151        logging.info("Creating collection: '%s'" %collectionPath)
152        r=self.xmlrpc.createCollection(collectionPath)
153        logging.info("Collection created")
154        return r
155   
156    def storeXML(self,xml,path,overwrite=0):
157        ''' Store some XML into the databse at path '''
158        return self.xmlrpc.parse(xml,path,overwrite)
159       
160 
Note: See TracBrowser for help on using the repository browser.