From 403af169d3371a69433330c5953d3aa7d59101b7 Mon Sep 17 00:00:00 2001
From: Kali Kaneko <kali@leap.se>
Date: Fri, 23 Sep 2016 19:36:26 -0400
Subject: [PATCH] hook blobs on get_doc

---
 client/src/leap/soledad/client/_blob.py | 18 +++++++++++---
 client/src/leap/soledad/client/api.py   | 33 ++++++++++++++++++++-----
 2 files changed, 42 insertions(+), 9 deletions(-)

diff --git a/client/src/leap/soledad/client/_blob.py b/client/src/leap/soledad/client/_blob.py
index 4e3fb83b..b567f09b 100644
--- a/client/src/leap/soledad/client/_blob.py
+++ b/client/src/leap/soledad/client/_blob.py
@@ -49,19 +49,30 @@ class BlobManager(object):
 
     @defer.inlineCallbacks
     def get(self, blob_id, doc_id, rev):
+        print "IN MANAGER: GETTING BLOB..."
         local_blob = yield self.local.get(blob_id)
         if local_blob:
+            print 'LOCAL BLOB', local_blob
             defer.returnValue(local_blob)
 
+        print "NO LOCAL BLOB, WILL DOWNLOAD"
+
         # TODO pass the fd to the downloader, possible?
         remoteblob = yield self._download(blob_id)
         ciphertext = BytesIO(str(remoteblob))
+
+        print 'remote ciphertext', remoteblob[:10], '[...]'
         logger.debug('got remote blob %s [...]' % remoteblob[:100])
         del remoteblob
 
         doc_info = docinfo(doc_id, rev)
         blob = yield self._decrypt(doc_info, ciphertext)
         if blob:
+            print 'GOT DECRYPTED BLOB', type(blob)
+            blob.seek(0)
+            print 'SAVING BLOB IN LOCAL STORE'
+            yield self.local.put(blob_id, blob)
+            blob.seek(0)
             defer.returnValue(blob)
         else:
         # XXX we shouldn't get here, but we will...
@@ -101,6 +112,8 @@ class BlobManager(object):
         defer.returnValue(blob)
 
 
+
+# --------------------8<----------------------------------------------
 class BlobDoc(object):
 
     # TODO probably not needed, but convenient for testing for now.
@@ -114,8 +127,7 @@ class BlobDoc(object):
         if blob_id is None:
             blob_id = uuid4().get_hex()
         self.blob_id = blob_id
-        
-
+# --------------------8<----------------------------------------------
 
 
 class SQLiteBlobBackend(object):
@@ -146,7 +158,7 @@ class SQLiteBlobBackend(object):
         select = 'SELECT payload FROM blobs WHERE blob_id = ?'
         result = yield self.dbpool.runQuery(select, (blob_id,))
         if result:
-            defer.returnValue(result[0][0])
+            defer.returnValue(BytesIO(str(result[0][0])))
 
 
 
diff --git a/client/src/leap/soledad/client/api.py b/client/src/leap/soledad/client/api.py
index eb0fc20c..d1ada1cd 100644
--- a/client/src/leap/soledad/client/api.py
+++ b/client/src/leap/soledad/client/api.py
@@ -389,6 +389,9 @@ class Soledad(object):
             also be updated.
         :rtype: twisted.internet.defer.Deferred
         """
+        # TODO --------------------------------
+        # do we need to hook blobs here too???
+        # TODO --------------------------------
         d = self._defer("put_doc", doc)
         return d
 
@@ -404,6 +407,9 @@ class Soledad(object):
         :return: A deferred.
         :rtype: twisted.internet.defer.Deferred
         """
+        # TODO --------------------------------
+        # SHOULD DELETE BLOBS IF NEEDED
+        # -------------------------------------
         return self._defer("delete_doc", doc)
 
     def get_doc(self, doc_id, include_deleted=False):
@@ -420,9 +426,28 @@ class Soledad(object):
             object.
         :rtype: twisted.internet.defer.Deferred
         """
-        return self._defer(
+        d = self._defer(
             "get_doc", doc_id, include_deleted=include_deleted)
 
+        # TODO ------------------------------------------------------------
+        # You might burn yourself
+
+        if self.blobs:
+            d.addCallback(self._get_doc_blob_cb)
+        # -----------------------------------------------------------------
+        return d
+
+    @inlineCallbacks
+    def _get_doc_blob_cb(self, doc):
+        if 'is_blob' in doc.content:
+            blob_id = doc.content.get('blob_id')
+            blob = yield self.blobs.get(blob_id, doc.doc_id, doc.rev)
+            if blob:
+                print "WE GOT A BLOB SIR!!!!"
+                doc.blob_fd = blob
+        returnValue(doc)
+
+
     def get_docs(
             self, doc_ids, check_for_conflicts=True, include_deleted=False):
         """
@@ -488,17 +513,13 @@ class Soledad(object):
         # TODO ------------------------------------------------------------
         # crazy shit ahead. Should check the type better.
 
-        if self.blobs and  isinstance(content, BytesIO):
+        if self.blobs and isinstance(content, BytesIO):
             blob_id = uuid.uuid4().get_hex()
             _content = {'is_blob': True, 'blob_id': blob_id}
         else:
             _content = content
 
         def blobbify(doc):
-            # I need the doc_id of the newly created doc,
-            # and its revision, because we're gonna stream the doc to the
-            # server backend.
-
             print "[blobbify] CREATING BLOB DOC", doc.doc_id, content
             blob_doc = BlobDoc(doc.doc_id, doc.rev, content, blob_id)
             d = self.blobs.put(blob_doc)
-- 
GitLab