couch.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. """
  2. Data-Transport
  3. Steve L. Nyemba, The Phi Technology
  4. This file is a wrapper around couchdb using IBM Cloudant SDK that has an interface to couchdb
  5. """
  6. import cloudant
  7. import json
  8. from common import Reader,Writer
  9. class Couch:
  10. """
  11. This class is a wrapper for read/write against couchdb. The class captures common operations for read/write.
  12. @param url host & port reference
  13. @param doc user id involved
  14. @param dbname database name (target)
  15. """
  16. def __init__(self,**args):
  17. url = args['url']
  18. self.uid = args['doc']
  19. dbname = args['dbname']
  20. if 'username' not in args and 'password' not in args :
  21. self.server = cloudant.CouchDB(None,None,url=url)
  22. else:
  23. self.server = cloudant.CouchDB(args['username'],args['password'],url=url)
  24. self.server.connect()
  25. if dbname in self.server.all_dbs() :
  26. self.dbase = self.server.get(dbname,dbname,True)
  27. #
  28. # @TODO Check if the database exists ...
  29. #
  30. doc = cloudant.document.Document(self.dbase,self.uid) #self.dbase.get(self.uid)
  31. if not doc.exists():
  32. doc = self.dbase.create_document({"_id":self.uid})
  33. doc.save()
  34. else:
  35. self.dbase = None
  36. """
  37. Insuring the preconditions are met for processing
  38. """
  39. def isready(self):
  40. p = self.server.metadata() != {}
  41. if p == False or not self.dbase:
  42. return False
  43. #
  44. # At this point we are sure that the server is connected
  45. # We are also sure that the database actually exists
  46. #
  47. doc = cloudant.document.Document(self.dbase,self.uid)
  48. # q = self.dbase.all_docs(key=self.uid)['rows']
  49. # if not q :
  50. if not doc.exists():
  51. return False
  52. return True
  53. def view(self,**args):
  54. """
  55. The function will execute a view (provivded a user is authenticated)
  56. :id design document _design/xxxx (provide full name with _design prefix)
  57. :view_name name of the view i.e
  58. :key(s) key(s) to be used to filter the content
  59. """
  60. document = cloudant.design_document.DesignDocument(self.dbase,args['id'])
  61. document.fetch()
  62. params = {'group_level':1,'group':True}
  63. if 'key' in args :
  64. params ['key'] = args['key']
  65. elif 'keys' in args :
  66. params['keys'] = args['keys']
  67. return document.get_view(args['view_name'])(**params)['rows']
  68. class CouchReader(Couch,Reader):
  69. """
  70. This function will read an attachment from couchdb and return it to calling code. The attachment must have been placed before hand (otherwise oops)
  71. @T: Account for security & access control
  72. """
  73. def __init__(self,**args):
  74. """
  75. @param filename filename (attachment)
  76. """
  77. #
  78. # setting the basic parameters for
  79. Couch.__init__(self,**args)
  80. if 'filename' in args :
  81. self.filename = args['filename']
  82. else:
  83. self.filename = None
  84. # def isready(self):
  85. # #
  86. # # Is the basic information about the database valid
  87. # #
  88. # p = Couchdb.isready(self)
  89. # if p == False:
  90. # return False
  91. # #
  92. # # The database name is set and correct at this point
  93. # # We insure the document of the given user has the requested attachment.
  94. # #
  95. # doc = self.dbase.get(self.uid)
  96. # if '_attachments' in doc:
  97. # r = self.filename in doc['_attachments'].keys()
  98. # else:
  99. # r = False
  100. # return r
  101. def stream(self):
  102. #
  103. # @TODO Need to get this working ...
  104. #
  105. document = cloudant.document.Document(self.dbase,self.uid)
  106. # content = self.dbase.fetch_attachment(self.uid,self.filename).split('\n') ;
  107. content = self.get_attachment(self.filename)
  108. for row in content:
  109. yield row
  110. def read(self,size=-1):
  111. if self.filename is not None:
  112. self.stream()
  113. else:
  114. return self.basic_read()
  115. def basic_read(self):
  116. document = cloudant.document.Document(self.dbase,self.uid)
  117. # document = self.dbase.get(self.uid)
  118. if document.exists() :
  119. document.fetch()
  120. document = dict(document)
  121. del document['_rev']
  122. else:
  123. document = {}
  124. return document
  125. class CouchWriter(Couch,Writer):
  126. """
  127. This class will write on a couchdb document provided a scope
  128. The scope is the attribute that will be on the couchdb document
  129. """
  130. def __init__(self,**args):
  131. """
  132. @param uri host & port reference
  133. @param uid user id involved
  134. @param filename filename (attachment)
  135. @param dbname database name (target)
  136. """
  137. Couch.__init__(self,**args)
  138. def write(self,**params):
  139. """
  140. write a given attribute to a document database
  141. @param label scope of the row repair|broken|fixed|stats
  142. @param row row to be written
  143. """
  144. # document = self.dbase.get(self.uid)
  145. document = cloudant.document.Document(self.dbase,self.uid) #.get(self.uid)
  146. if document.exists() is False :
  147. document = self.dbase.create_document({"_id":self.uid})
  148. label = params['label']
  149. row = params['row']
  150. if label not in document :
  151. document[label] = []
  152. document[label].append(row)
  153. document.save()
  154. # self.dbase.bulk_docs([document])
  155. # self.dbase.save_doc(document)
  156. def archive(self,params=None):
  157. """
  158. This function will archive the document onto itself.
  159. """
  160. # document = self.dbase.all_docs(self.uid,include_docs=True)
  161. document = cloudant.document.Document(self.dbase,self.filename)
  162. document.fetch()
  163. content = {}
  164. # _doc = {}
  165. for id in document:
  166. if id not in ['_id','_rev','_attachments'] :
  167. content[id] = document[id]
  168. del document[id]
  169. content = json.dumps(content)
  170. # document= _doc
  171. now = str(datetime.today())
  172. name = '-'.join([document['_id'] , now,'.json'])
  173. # self.dbase.bulk_docs([document])
  174. # self.dbase.put_attachment(document,content,name,'application/json')
  175. document.put_attachment(self.dbase,name,'application/json',content)
  176. document.save()