Use twisted to post the design docs. twisty
authorMark Hammond <mhammond@skippinet.com.au>
Tue, 10 Mar 2009 14:01:47 +1100
branchtwisty
changeset 65 bfda6d157f1ff83f2ae02e530c20c9f047d55d72
parent 63 ac76ef89527f0009b10e30f280f8034c881deea4
child 66 c2f9a06c2985c3036a859bc34724f881e0e33c3e
push id1
push userroot
push dateWed, 08 Apr 2009 01:46:05 +0000
Use twisted to post the design docs.
server/python/junius/model.py
--- a/server/python/junius/model.py
+++ b/server/python/junius/model.py
@@ -1,33 +1,50 @@
 import os
 import logging
+
+import twisted.web.error
+try:
+    import simplejson as json
+except ImportError:
+    import json # Python 2.6
+
 import paisley
-from couchdb import schema, design
+from couchdb import schema
 from junius.config import get_config
 
+
 config = get_config()
 
 class _NotSpecified:
     pass
 
 logger = logging.getLogger('model')
 
 DBs = {}
 
+class CouchDB(paisley.CouchDB):
+    def postob(self, uri, ob):
+        # This seems to not use keep-alives etc where using twisted.web
+        # directly doesn't?
+        body = json.dumps(ob, allow_nan=False,
+                          ensure_ascii=False).encode('utf-8')
+        return self.post(uri, body)
+
+
 def get_db(couchname="local", dbname=_NotSpecified):
     try:
         return DBs[couchname]
     except KeyError:
         pass
     dbinfo = config.couches[couchname]
     if dbname is _NotSpecified:
         dbname = dbinfo['name']
     logger.info("Connecting to couchdb at %s", dbinfo)
-    db = paisley.CouchDB(dbinfo['host'], dbinfo['port'], dbname)
+    db = CouchDB(dbinfo['host'], dbinfo['port'], dbname)
     DBs[couchname] = db
     return db
 
 
 class WildField(schema.Field):
     '''
     Allows us to have dictionaries without schemas.
     '''
@@ -288,43 +305,48 @@ def fab_db(update_views=False):
     # XXX - we ignore update_views and always update them.  Its not clear
     # how to hook this in cleanly to twisted (ie, even if update_views is
     # False, we must still do it if the db didn't exist)
     couch_name = 'local'
     db = get_db(couch_name, None)
     dbinfo = config.couches[couch_name]
 
     def _create_failed(failure, *args, **kw):
+        failure.trap(twisted.web.error.Error)
         if failure.value.status != '412': # precondition failed.
             failure.raiseException()
         logger.info("DB already exists!")
 
     def _created_ok(d):
         logger.info("created new database")
         view_src = os.path.abspath(os.path.join(os.path.dirname(__file__),
                                                 "../../../schema/views"))
         logger.info("Updating views from '%s'", view_src)
         
         doc_types = [x for x in globals().itervalues()
                      if isinstance(x, type) and issubclass(x, RaindropDocument)
                      and x is not RaindropDocument]
+        docs = []
         for doc_class in doc_types:
             manifest_dir = os.path.join(view_src, doc_class.view_src)
             view_gen = load_views_from_manifest(os.path.join(manifest_dir, "MANIFEST"))
-            views = []
+            # XXX - rework this.
             for view_name, map_src, reduce_src in view_gen:
                 logger.debug("Creating view '%s', map=%r, reduce=%r",
                              view_name, map_src, reduce_src)
-                view = schema.View(view_name, map_src, reduce_src)
-                #view = design.ViewDefinition(view_doc, view_name, map_src, reduce_src)
-                views.append(view)
+                view_doc = "_design/" + doc_class.view_src + "/" + view_name
+                view = {'map': map_src}
+                if reduce_src:
+                    view['reduce'] = reduce_src
+                views = {view_name: view}
+                # don't bother setting language= - we always use default of js.
+                doc = {'_id': view_doc, 'views': views}
+                docs.append(doc)
 
-            # SOB - need a twisted version of this...
-            if views:
-                import couchdb
-                url = 'http://%(host)s:%(port)s/' % dbinfo
-                sserver = couchdb.Server(url)
-                sdb = sserver[dbinfo['name']]
-                design.ViewDefinition.sync_many(sdb, views)
+        assert docs, 'surely I have *some* docs!'
+        url = '/%(name)s/_bulk_docs' % dbinfo
+        ob = {'docs' : docs}
+        deferred = db.postob(url, ob)
+        return deferred
 
     d = db.createDB(dbinfo['name'])
     d.addCallbacks(_created_ok, _create_failed)
     return d