add basic attachment support to the doc_model twisty
authorMark Hammond <mhammond@skippinet.com.au>
Mon, 23 Mar 2009 14:08:42 +1100
branchtwisty
changeset 112 b2f2984dd6482fbd7d4f8b13f937aaf03288b198
parent 111 b0340c2821da37ecd100912692f3876ed6fa1806
child 113 e07ebe3f1e17ed502d2dc052bc753b6146d33d73
push id1
push userroot
push dateWed, 08 Apr 2009 01:46:05 +0000
add basic attachment support to the doc_model
server/python/junius/model.py
--- a/server/python/junius/model.py
+++ b/server/python/junius/model.py
@@ -68,16 +68,23 @@ class CouchDB(paisley.CouchDB):
 
     def openView(self, *args, **kwargs):
         # The base class of this returns the raw json object - eg:
         # {'rows': [], 'total_rows': 0}
         # *sob* - and it also doesn't handle encoding options...
         return super(CouchDB, self).openView(*args, **_encode_options(kwargs)
                         ).addCallback(_raw_to_rows)
 
+    def openDoc(self, dbName, docId, revision=None, full=False, attachment=""):
+        # paisley appears to use an old api for attachments?
+        if attachment:
+            uri = "/%s/%s/%s" % (dbName, docId, attachment)
+            return  self.get(uri)
+        return super(CouchDB, self).openDoc(dbName, docId, revision, full)
+
 def get_db(couchname="local", dbname=_NotSpecified):
     dbinfo = config.couches[couchname]
     if dbname is _NotSpecified:
         dbname = dbinfo['name']
     key = couchname, dbname
     try:
         return DBs[key]
     except KeyError:
@@ -93,40 +100,46 @@ def quote_id(doc_id):
 class DocumentModel(object):
     """The layer between 'documents' and the 'database'.  Responsible for
        creating the unique ID for each document (other than the raw document),
        for fetching documents based on an ID, etc
     """
     def __init__(self, db):
         self.db = db
 
-    def open_document(self, doc_id):
-        """Open the specific extension's document for the given ID"""
-        return self.db.openDoc(quote_id(doc_id)).addBoth(self._cb_doc_opened)
+    def open_document(self, doc_id, **kw):
+        """Open the specific document, returning None if it doesn't exist"""
+        return self.db.openDoc(quote_id(doc_id), **kw).addBoth(self._cb_doc_opened)
 
     def _cb_doc_opened(self, result):
         if isinstance(result, Failure):
             result.trap(twisted.web.error.Error)
             if result.value.status != '404': # not found
                 result.raiseException()
             result = None # indicate no doc exists.
         return result
 
-    def create_raw_document(self, docid, doc, doc_type, account):
+    def create_raw_document(self, docid, doc, doc_type, account, attachments=None):
         assert '_id' not in doc # that isn't how you specify the ID.
         assert '!' not in docid, docid # these chars are special.
         assert 'raindrop_account' not in doc, doc # we look after that!
         doc['raindrop_account'] = account.details['_id']
 
         assert 'type' not in doc, doc # we look after that!
         doc['type'] = doc_type
 
         assert 'raindrop_seq' not in doc, doc # we look after that!
         doc['raindrop_seq'] = get_seq()
 
+        # XXX - for small blobs this is good (we get the attachment in the
+        # same request as the doc).  For large blobs this is bad, as we
+        # base64 encode the data in memory before sending it.
+        if attachments:
+            self.db.addAttachments(doc, attachments)
+
         # save the document.
         logger.debug('create_raw_document saving doc %r', docid)
         return self.db.saveDoc(doc, docId=quote_id(docid),
                     ).addCallback(self._cb_saved_document
                     ).addErrback(self._cb_save_failed
                     )
 
     def _cb_saved_document(self, result):