def setup_couchapp_json(self): ''' Create ``couchapp.json`` from ``self.doc['couchapp']``. We will exclude the following properties: - ``signatures`` - ``manifest`` - ``objects`` - ``length`` ''' if 'couchapp' not in self.doc: logger.warning('missing `couchapp` property in document') return app_meta = copy.deepcopy(self.doc['couchapp']) if 'signatures' in app_meta: del app_meta['signatures'] if 'manifest' in app_meta: del app_meta['manifest'] if 'objects' in app_meta: del app_meta['objects'] if 'length' in app_meta: del app_meta['length'] couchapp_file = os.path.join(self.path, 'couchapp.json') util.write_json(couchapp_file, app_meta)
def create(self): if not os.path.isdir(self.docdir): logger.error("%s directory doesn't exist." % self.docdir) rcfile = os.path.join(self.docdir, '.couchapprc') if not os.path.isfile(rcfile): util.write_json(rcfile, {}) else: logger.info("CouchApp already initialized in %s." % self.docdir)
def create(self): util.setup_dir(self.docdir, require_empty=False) rcfile = os.path.join(self.docdir, '.couchapprc') ignfile = os.path.join(self.docdir, '.couchappignore') if not os.path.isfile(rcfile): util.write_json(rcfile, {}) util.write(ignfile, DEFAULT_IGNORE) else: logger.info("CouchApp already initialized in %s." % self.docdir)
def create(self): util.setup_dir(self.docdir, require_empty=False) rcfile = os.path.join(self.docdir, ".couchapprc") ignfile = os.path.join(self.docdir, ".couchappignore") if not os.path.isfile(rcfile): util.write_json(rcfile, {}) util.write(ignfile, DEFAULT_IGNORE) else: logger.info("CouchApp already initialized in %s.", self.docdir)
def create(self): if not os.path.isdir(self.docdir): logger.error("%s directory doesn't exist." % self.docdir) rcfile = os.path.join(self.docdir, ".couchapprc") ignfile = os.path.join(self.docdir, ".couchappignore") if not os.path.isfile(rcfile): util.write_json(rcfile, {}) util.write(ignfile, DEFAULT_IGNORE) else: logger.info("CouchApp already initialized in %s." % self.docdir)
def create(self): if not os.path.isdir(self.docdir): logger.error("%s directory doesn't exist." % self.docdir) rcfile = os.path.join(self.docdir, '.couchapprc') ignfile = os.path.join(self.docdir, '.couchappignore') if not os.path.isfile(rcfile): util.write_json(rcfile, {}) util.write(ignfile, DEFAULT_IGNORE) else: logger.info("CouchApp already initialized in %s." % self.docdir)
def test(conf, path, *args, **opts): export = opts.get('export', False) js = opts.get('spidermonkey', 'js'); test_file = args[0] dest = None doc_path = None # print("path: {0}".format(path)) # print("test_file: {0}".format(args)) # print("conf: {0}".format(conf)) if len(args) < 2: if export: if path is None and args: doc_path = args[0] else: doc_path = path else: doc_path = path if args: dest = args[0] else: doc_path = os.path.normpath(os.path.join(os.getcwd(), args[0])) dest = args[1] if doc_path is None: raise AppError("You aren't in a couchapp.") # print ("docPath:"+doc_path) conf.update(doc_path) doc = document(doc_path, create=False, docid=opts.get('docid')) if export: if opts.get('output'): util.write_json(opts.get('output'), str(doc)) else: print str(doc) return 0 with tempfile.NamedTemporaryFile(delete=False) as tmp: tmp.write("var couchdb_design_doc = {0};".format(str(doc))) tmp.flush() print(tmp.name) # util.write_json(tmp.name, str(doc)) p = Popen([js, test_file, tmp.name], stdout=PIPE, stderr=PIPE) # status = 1 # while status >= 0: stdout, stderr = p.communicate() print "OUT:\n"+stdout print "ERROR:\n"+stderr # status = p.poll() return 0
def pushapps(conf, source, dest=None, *args, **opts): export = opts.get('export', False) noatomic = opts.get('no_atomic', False) browse = opts.get('browse', False) dbs = conf.get_dbs(dest) if not export else None apps = [] source = os.path.normpath(os.path.join(os.getcwd(), source)) appdirs = util.discover_apps(source) logger.debug('Discovered apps: {0}'.format(appdirs)) for appdir in appdirs: doc = document(appdir) # if export mode, the ``dbs`` will be None hook(conf, appdir, "pre-push", dbs=dbs, pushapps=True) if export or not noatomic: apps.append(doc) else: doc.push(dbs, True, browse) hook(conf, appdir, "post-push", dbs=dbs, pushapps=True) if not apps: return 0 if export: docs = [doc.doc() for doc in apps] jsonobj = {'docs': docs} if opts.get('output'): util.write_json(opts.get('output'), jsonobj) else: print(util.json.dumps(jsonobj)) return 0 for db in dbs: docs = [doc.doc(db) for doc in apps] try: db.save_docs(docs) except BulkSaveError as e: docs1 = [] for doc in e.errors: try: doc['_rev'] = db.last_rev(doc['_id']) docs1.append(doc) except ResourceNotFound: pass if docs1: db.save_docs(docs1) return 0
def pushapps(conf, source, dest, *args, **opts): export = opts.get("export", False) noatomic = opts.get("no_atomic", False) browse = opts.get("browse", False) dbs = conf.get_dbs(dest) apps = [] source = os.path.normpath(os.path.join(os.getcwd(), source)) appdirs = util.discover_apps(source) logger.debug("Discovered apps: {0}".format(appdirs)) for appdir in appdirs: doc = document(appdir) hook(conf, appdir, "pre-push", dbs=dbs, pushapps=True) if export or not noatomic: apps.append(doc) else: doc.push(dbs, True, browse) hook(conf, appdir, "post-push", dbs=dbs, pushapps=True) if not apps: return 0 if export: docs = [doc.doc() for doc in apps] jsonobj = {"docs": docs} if opts.get("output"): util.write_json(opts.get("output"), jsonobj) else: print util.json.dumps(jsonobj) return 0 for db in dbs: docs = [doc.doc(db) for doc in apps] try: db.save_docs(docs) except BulkSaveError as e: docs1 = [] for doc in e.errors: try: doc["_rev"] = db.last_rev(doc["_id"]) docs1.append(doc) except ResourceNotFound: pass if docs1: db.save_docs(docs1) return 0
def create(self): ''' Init a dir as a couchapp. Only create ``.couchapprc`` and ``.couchappignore``. Do nothing if ``.couchapprc`` exists. ''' util.setup_dir(self.docdir, require_empty=False) rcfile = os.path.join(self.docdir, '.couchapprc') ignfile = os.path.join(self.docdir, '.couchappignore') if not os.path.isfile(rcfile): util.write_json(rcfile, {}) util.write(ignfile, DEFAULT_IGNORE) else: logger.info("CouchApp already initialized in %s.", self.docdir)
def pushapps(conf, source, dest, *args, **opts): export = opts.get('export', False) noatomic = opts.get('no_atomic', False) browse = opts.get('browse', False) dbs = conf.get_dbs(dest) apps = [] source = os.path.normpath(os.path.join(os.getcwd(), source)) for d in os.listdir(source): appdir = os.path.join(source, d) if os.path.isdir(appdir) and os.path.isfile(os.path.join(appdir, '.couchapprc')): doc = document(appdir) hook(conf, appdir, "pre-push", dbs=dbs, pushapps=True) if export or not noatomic: apps.append(doc) else: doc.push(dbs, True, browse) hook(conf, appdir, "post-push", dbs=dbs, pushapps=True) if apps: if export: docs = [] docs.append([doc.doc() for doc in apps]) jsonobj = {'docs': docs} if opts.get('output') is not None: util.write_json(opts.get('output'), json.dumps(jsonobj)) else: print json.dumps(jsonobj) return 0 else: for db in dbs: docs = [] docs = [doc.doc(db) for doc in apps] try: db.save_docs(docs) except BulkSaveError, e: docs1 = [] for doc in e.errors: try: doc['_rev'] = db.last_rev(doc['_id']) docs1.append(doc) except ResourceNotFound: pass if docs1: db.save_docs(docs1)
def pushapps(conf, source, dest, *args, **opts): export = opts.get('export', False) noatomic = opts.get('no_atomic', False) browse = opts.get('browse', False) dbs = conf.get_dbs(dest) apps = [] source = os.path.normpath(os.path.join(os.getcwd(), source)) for d in os.listdir(source): appdir = os.path.join(source, d) if os.path.isdir(appdir) and os.path.isfile( os.path.join(appdir, '.couchapprc')): doc = document(appdir) hook(conf, appdir, "pre-push", dbs=dbs, pushapps=True) if export or not noatomic: apps.append(doc) else: doc.push(dbs, True, browse) hook(conf, appdir, "post-push", dbs=dbs, pushapps=True) if apps: if export: docs = [] docs.append([doc.doc() for doc in apps]) jsonobj = {'docs': docs} if opts.get('output') is not None: util.write_json(opts.get('output'), util.json.dumps(jsonobj)) else: print util.json.dumps(jsonobj) return 0 else: for db in dbs: docs = [] docs = [doc.doc(db) for doc in apps] try: db.save_docs(docs) except BulkSaveError, e: docs1 = [] for doc in e.errors: try: doc['_rev'] = db.last_rev(doc['_id']) docs1.append(doc) except ResourceNotFound: pass if docs1: db.save_docs(docs1)
def push(conf, path, *args, **opts): export = opts.get('export', False) noatomic = opts.get('no_atomic', False) browse = opts.get('browse', False) force = opts.get('force', False) dest = None doc_path = None if len(args) < 2: if export: if path is None and args: doc_path = args[0] else: doc_path = path else: doc_path = path if args: dest = args[0] else: doc_path = os.path.normpath(os.path.join(os.getcwd(), args[0])) dest = args[1] if doc_path is None: raise AppError("You aren't in a couchapp.") conf.update(doc_path) doc = document(doc_path, create=False, docid=opts.get('docid')) if export: if opts.get('output'): util.write_json(opts.get('output'), doc) else: print(doc.to_json()) return 0 dbs = conf.get_dbs(dest) hook(conf, doc_path, "pre-push", dbs=dbs) doc.push(dbs, noatomic, browse, force) hook(conf, doc_path, "post-push", dbs=dbs) docspath = os.path.join(doc_path, '_docs') if os.path.exists(docspath): pushdocs(conf, docspath, dest, *args, **opts) return 0
def update(self, appdir, name=None, *args, **opts): should_force = opts.get("force", False) vendordir = os.path.join(appdir, "vendor") if not os.path.isdir(vendordir): os.makedirs(vendordir) if name is not None: if name not in self.installed_vendors(vendordir): raise VendorError("vendor `%s` doesn't exist" % name) dest = os.path.join(vendordir, name) metaf = os.path.join(dest, "metadata.json") meta = util.read_json(metaf) uri = meta.get("fetch_uri", "") if not uri: raise VendorError("Can't update vendor `%s`: fetch_uri undefined." % name) new_vendors, temppath = self.fetch_vendor(uri, *args, **opts) for vname, vpath, vmeta in new_vendors: if name != vname: continue else: util.deltree(dest) shutil.copytree(vpath, dest) util.write_json(metaf, vmeta) logger.info("%s updated in vendors" % vname) break util.deltree(temppath) else: # update all vendors updated = [] for vendor in self.installed_vendors(vendordir): if vendor in updated: continue else: dest = os.path.join(vendordir, vendor) metaf = os.path.join(dest, "metadata.json") meta = util.read_json(metaf) uri = meta.get("fetch_uri", "") if not uri: logger.warning("Can't update vendor `%s`: fetch_uri undefined." % vendor) continue else: new_vendors, temppath = self.fetch_vendor(uri, *args, **opts) for vname, vpath, vmeta in new_vendors: dest1 = os.path.join(vendordir, vname) metaf1 = os.path.join(dest1, "metadata.json") if os.path.exists(dest1): util.deltree(dest1) shutil.copytree(vpath, dest1) util.write_json(metaf1, vmeta) logger.info("%s updated in vendors" % vname) updated.append(vname) elif should_force: # install forced shutil.copytree(vpath, dest1) util.write_json(metaf1, vmeta) logger.info("%s installed in vendors" % vname) updated.append(vname) util.deltree(temppath) return 0
def install(self, appdir, uri, *args, **opts): """ install a vendor in the couchapp dir. """ should_force = opts.get('force', False) vendordir = os.path.join(appdir, "vendor") if not os.path.isdir(vendordir): os.makedirs(vendordir) new_vendors, temppath = self.fetch_vendor(uri, *args, **opts) for name, path, meta in new_vendors: dest = os.path.join(vendordir, name) metaf = os.path.join(dest, "metadata.json") if os.path.isdir(dest): if should_force: util.deltree(dest) else: logger.warning("vendor: %s already installed" % name) continue shutil.copytree(path, dest) util.write_json(metaf, meta) logger.info("%s installed in vendors" % name) util.deltree(temppath) return 0
def pushdocs(conf, source, dest, *args, **opts): export = opts.get('export', False) noatomic = opts.get('no_atomic', False) browse = opts.get('browse', False) dbs = conf.get_dbs(dest) docs = [] for d in os.listdir(source): docdir = os.path.join(source, d) if docdir.startswith('.'): continue elif os.path.isfile(docdir): if d.endswith(".json"): doc = util.read_json(docdir) docid, ext = os.path.splitext(d) doc.setdefault('_id', docid) doc.setdefault('couchapp', {}) if export or not noatomic: docs.append(doc) else: for db in dbs: db.save_doc(doc, force_update=True) else: doc = document(docdir, is_ddoc=False) if export or not noatomic: docs.append(doc) else: doc.push(dbs, True, browse) if docs: if export: docs1 = [] for doc in docs: if hasattr(doc, 'doc'): docs1.append(doc.doc()) else: docs1.append(doc) jsonobj = {'docs': docs} if opts.get('output') is not None: util.write_json(opts.get('output'), util.json.dumps(jsonobj)) else: print util.json.dumps(jsonobj) else: for db in dbs: docs1 = [] for doc in docs: if hasattr(doc, 'doc'): docs1.append(doc.doc(db)) else: newdoc = doc.copy() try: rev = db.last_rev(doc['_id']) newdoc.update({'_rev': rev}) except ResourceNotFound: pass docs1.append(newdoc) try: db.save_docs(docs1) except BulkSaveError, e: # resolve conflicts docs1 = [] for doc in e.errors: try: doc['_rev'] = db.last_rev(doc['_id']) docs1.append(doc) except ResourceNotFound: pass if docs1: db.save_docs(docs1)
def clone(source, dest=None, rev=None): """ Clone an application from a design_doc given. :attr design_doc: dict, the design doc retrieved from couchdb if something was wrong. """ try: dburl, docid = source.split('_design/') except ValueError: raise AppError("%s isn't a valid source" % source) if not dest: dest = docid path = os.path.normpath(os.path.join(os.getcwd(), dest)) if not os.path.exists(path): os.makedirs(path) db = client.Database(dburl[:-1], create=False) if not rev: doc = db.open_doc("_design/%s" % docid) else: doc = db.open_doc("_design/%s" % docid, rev=rev) docid = doc['_id'] metadata = doc.get('couchapp', {}) # get manifest manifest = metadata.get('manifest', {}) # get signatures signatures = metadata.get('signatures', {}) # get objects refs objects = metadata.get('objects', {}) # create files from manifest if manifest: for filename in manifest: logger.debug("clone property: %s" % filename) filepath = os.path.join(path, filename) if filename.endswith('/'): if not os.path.isdir(filepath): os.makedirs(filepath) elif filename == "couchapp.json": continue else: parts = util.split_path(filename) fname = parts.pop() v = doc while 1: try: for key in parts: v = v[key] except KeyError: break # remove extension last_key, ext = os.path.splitext(fname) # make sure key exist try: content = v[last_key] except KeyError: break if isinstance(content, basestring): _ref = md5(util.to_bytestring(content)).hexdigest() if objects and _ref in objects: content = objects[_ref] if content.startswith('base64-encoded;'): content = base64.b64decode(content[15:]) if fname.endswith('.json'): content = util.json.dumps(content).encode('utf-8') del v[last_key] # make sure file dir have been created filedir = os.path.dirname(filepath) if not os.path.isdir(filedir): os.makedirs(filedir) util.write(filepath, content) # remove the key from design doc temp = doc for key2 in parts: if key2 == key: if not temp[key2]: del temp[key2] break temp = temp[key2] # second pass for missing key or in case # manifest isn't in app for key in doc.iterkeys(): if key.startswith('_'): continue elif key in ('couchapp'): app_meta = copy.deepcopy(doc['couchapp']) if 'signatures' in app_meta: del app_meta['signatures'] if 'manifest' in app_meta: del app_meta['manifest'] if 'objects' in app_meta: del app_meta['objects'] if 'length' in app_meta: del app_meta['length'] if app_meta: couchapp_file = os.path.join(path, 'couchapp.json') util.write_json(couchapp_file, app_meta) elif key in ('views'): vs_dir = os.path.join(path, key) if not os.path.isdir(vs_dir): os.makedirs(vs_dir) for vsname, vs_item in doc[key].iteritems(): vs_item_dir = os.path.join(vs_dir, vsname) if not os.path.isdir(vs_item_dir): os.makedirs(vs_item_dir) for func_name, func in vs_item.iteritems(): filename = os.path.join(vs_item_dir, '%s.js' % func_name) util.write(filename, func) logger.warning("clone view not in manifest: %s" % filename) elif key in ('shows', 'lists', 'filter', 'updates'): showpath = os.path.join(path, key) if not os.path.isdir(showpath): os.makedirs(showpath) for func_name, func in doc[key].iteritems(): filename = os.path.join(showpath, '%s.js' % func_name) util.write(filename, func) logger.warning("clone show or list not in manifest: %s" % filename) else: filedir = os.path.join(path, key) if os.path.exists(filedir): continue else: logger.warning("clone property not in manifest: %s" % key) if isinstance(doc[key], ( list, tuple, )): util.write_json(filedir + ".json", doc[key]) elif isinstance(doc[key], dict): if not os.path.isdir(filedir): os.makedirs(filedir) for field, value in doc[key].iteritems(): fieldpath = os.path.join(filedir, field) if isinstance(value, basestring): if value.startswith('base64-encoded;'): value = base64.b64decode(content[15:]) util.write(fieldpath, value) else: util.write_json(fieldpath + '.json', value) else: value = doc[key] if not isinstance(value, basestring): value = str(value) util.write(filedir, value) # save id idfile = os.path.join(path, '_id') util.write(idfile, doc['_id']) util.write_json(os.path.join(path, '.couchapprc'), {}) if '_attachments' in doc: # process attachments attachdir = os.path.join(path, '_attachments') if not os.path.isdir(attachdir): os.makedirs(attachdir) for filename in doc['_attachments'].iterkeys(): if filename.startswith('vendor'): attach_parts = util.split_path(filename) vendor_attachdir = os.path.join(path, attach_parts.pop(0), attach_parts.pop(0), '_attachments') filepath = os.path.join(vendor_attachdir, *attach_parts) else: filepath = os.path.join(attachdir, filename) filepath = _replace_slash(filepath) currentdir = os.path.dirname(filepath) if not os.path.isdir(currentdir): os.makedirs(currentdir) if signatures.get(filename) != util.sign(filepath): resp = db.fetch_attachment(docid, filename) with open(filepath, 'wb') as f: for chunk in resp.body_stream(): f.write(chunk) logger.debug("clone attachment: %s" % filename) logger.info("%s cloned in %s" % (source, dest))
def setup_couchapprc(self): ''' Setup empty .couchapprc ''' util.write_json(os.path.join(self.path, '.couchapprc'), {})
def update(self, appdir, name=None, *args, **opts): should_force = opts.get('force', False) vendordir = os.path.join(appdir, "vendor") if not os.path.isdir(vendordir): os.makedirs(vendordir) if name is not None: if name not in self.installed_vendors(vendordir): raise VendorError("vendor `%s` doesn't exist" % name) dest = os.path.join(vendordir, name) metaf = os.path.join(dest, "metadata.json") meta = util.read_json(metaf) uri = meta.get("fetch_uri", "") if not uri: raise VendorError( "Can't update vendor `%s`: fetch_uri undefined." % name) new_vendors, temppath = self.fetch_vendor(uri, *args, **opts) for vname, vpath, vmeta in new_vendors: if name != vname: continue else: util.deltree(dest) shutil.copytree(vpath, dest) util.write_json(metaf, vmeta) logger.info("%s updated in vendors" % vname) break util.deltree(temppath) else: # update all vendors updated = [] for vendor in self.installed_vendors(vendordir): if vendor in updated: continue else: dest = os.path.join(vendordir, vendor) metaf = os.path.join(dest, "metadata.json") meta = util.read_json(metaf) uri = meta.get("fetch_uri", "") if not uri: logger.warning( "Can't update vendor `%s`: fetch_uri undefined." % vendor) continue else: new_vendors, temppath = self.fetch_vendor( uri, *args, **opts) for vname, vpath, vmeta in new_vendors: dest1 = os.path.join(vendordir, vname) metaf1 = os.path.join(dest1, "metadata.json") if os.path.exists(dest1): util.deltree(dest1) shutil.copytree(vpath, dest1) util.write_json(metaf1, vmeta) logger.info("%s updated in vendors" % vname) updated.append(vname) elif should_force: #install forced shutil.copytree(vpath, dest1) util.write_json(metaf1, vmeta) logger.info("%s installed in vendors" % vname) updated.append(vname) util.deltree(temppath) return 0
def clone(source, dest=None, rev=None): """ Clone an application from a design_doc given. :attr design_doc: dict, the design doc retrieved from couchdb if something was wrong. """ try: dburl, docid = source.split('_design/') except ValueError: raise AppError("%s isn't a valid source" % source) if not dest: dest = docid path = os.path.normpath(os.path.join(os.getcwd(), dest)) if not os.path.exists(path): os.makedirs(path) db = client.Database(dburl[:-1], create=False) if not rev: doc = db.open_doc("_design/%s" % docid) else: doc = db.open_doc("_design/%s" % docid, rev=rev) docid = doc['_id'] metadata = doc.get('couchapp', {}) # get manifest manifest = metadata.get('manifest', {}) # get signatures signatures = metadata.get('signatures', {}) # get objects refs objects = metadata.get('objects', {}) # create files from manifest if manifest: for filename in manifest: logger.debug("clone property: %s" % filename) filepath = os.path.join(path, filename) if filename.endswith('/'): if not os.path.isdir(filepath): os.makedirs(filepath) elif filename == "couchapp.json": continue else: parts = util.split_path(filename) fname = parts.pop() v = doc while 1: try: for key in parts: v = v[key] except KeyError: break # remove extension last_key, ext = os.path.splitext(fname) # make sure key exist try: content = v[last_key] except KeyError: break if isinstance(content, basestring): _ref = md5(util.to_bytestring(content)).hexdigest() if objects and _ref in objects: content = objects[_ref] if content.startswith('base64-encoded;'): content = base64.b64decode(content[15:]) if fname.endswith('.json'): content = util.json.dumps(content).encode('utf-8') del v[last_key] # make sure file dir have been created filedir = os.path.dirname(filepath) if not os.path.isdir(filedir): os.makedirs(filedir) util.write(filepath, content) # remove the key from design doc temp = doc for key2 in parts: if key2 == key: if not temp[key2]: del temp[key2] break temp = temp[key2] # second pass for missing key or in case # manifest isn't in app for key in doc.iterkeys(): if key.startswith('_'): continue elif key in ('couchapp'): app_meta = copy.deepcopy(doc['couchapp']) if 'signatures' in app_meta: del app_meta['signatures'] if 'manifest' in app_meta: del app_meta['manifest'] if 'objects' in app_meta: del app_meta['objects'] if 'length' in app_meta: del app_meta['length'] if app_meta: couchapp_file = os.path.join(path, 'couchapp.json') util.write_json(couchapp_file, app_meta) elif key in ('views'): vs_dir = os.path.join(path, key) if not os.path.isdir(vs_dir): os.makedirs(vs_dir) for vsname, vs_item in doc[key].iteritems(): vs_item_dir = os.path.join(vs_dir, vsname) if not os.path.isdir(vs_item_dir): os.makedirs(vs_item_dir) for func_name, func in vs_item.iteritems(): filename = os.path.join(vs_item_dir, '%s.js' % func_name) util.write(filename, func) logger.warning("clone view not in manifest: %s" % filename) elif key in ('shows', 'lists', 'filter', 'update'): showpath = os.path.join(path, key) if not os.path.isdir(showpath): os.makedirs(showpath) for func_name, func in doc[key].iteritems(): filename = os.path.join(showpath, '%s.js' % func_name) util.write(filename, func) logger.warning( "clone show or list not in manifest: %s" % filename) else: filedir = os.path.join(path, key) if os.path.exists(filedir): continue else: logger.warning("clone property not in manifest: %s" % key) if isinstance(doc[key], (list, tuple,)): util.write_json(filedir + ".json", doc[key]) elif isinstance(doc[key], dict): if not os.path.isdir(filedir): os.makedirs(filedir) for field, value in doc[key].iteritems(): fieldpath = os.path.join(filedir, field) if isinstance(value, basestring): if value.startswith('base64-encoded;'): value = base64.b64decode(content[15:]) util.write(fieldpath, value) else: util.write_json(fieldpath + '.json', value) else: value = doc[key] if not isinstance(value, basestring): value = str(value) util.write(filedir, value) # save id idfile = os.path.join(path, '_id') util.write(idfile, doc['_id']) util.write_json(os.path.join(path, '.couchapprc'), {}) if '_attachments' in doc: # process attachments attachdir = os.path.join(path, '_attachments') if not os.path.isdir(attachdir): os.makedirs(attachdir) for filename in doc['_attachments'].iterkeys(): if filename.startswith('vendor'): attach_parts = util.split_path(filename) vendor_attachdir = os.path.join(path, attach_parts.pop(0), attach_parts.pop(0), '_attachments') filepath = os.path.join(vendor_attachdir, *attach_parts) else: filepath = os.path.join(attachdir, filename) filepath = _replace_slash(filepath) currentdir = os.path.dirname(filepath) if not os.path.isdir(currentdir): os.makedirs(currentdir) if signatures.get(filename) != util.sign(filepath): resp = db.fetch_attachment(docid, filename) with open(filepath, 'wb') as f: for chunk in resp.body_stream(): f.write(chunk) logger.debug("clone attachment: %s" % filename) logger.info("%s cloned in %s" % (source, dest))
def pushdocs(conf, source, dest, *args, **opts): export = opts.get('export', False) noatomic = opts.get('no_atomic', False) browse = opts.get('browse', False) dbs = conf.get_dbs(dest) docs = [] for d in os.listdir(source): docdir = os.path.join(source, d) if d.startswith('.'): continue elif os.path.isfile(docdir): if d.endswith(".json"): doc = util.read_json(docdir) docid, ext = os.path.splitext(d) doc.setdefault('_id', docid) doc.setdefault('couchapp', {}) if export or not noatomic: docs.append(doc) else: for db in dbs: db.save_doc(doc, force_update=True) else: doc = document(docdir, is_ddoc=False) if export or not noatomic: docs.append(doc) else: doc.push(dbs, True, browse) if docs: if export: docs1 = [] for doc in docs: if hasattr(doc, 'doc'): docs1.append(doc.doc()) else: docs1.append(doc) jsonobj = {'docs': docs} if opts.get('output'): util.write_json(opts.get('output'), jsonobj) else: print(util.json.dumps(jsonobj)) else: for db in dbs: docs1 = [] for doc in docs: if hasattr(doc, 'doc'): docs1.append(doc.doc(db)) else: newdoc = doc.copy() try: rev = db.last_rev(doc['_id']) newdoc.update({'_rev': rev}) except ResourceNotFound: pass docs1.append(newdoc) try: db.save_docs(docs1) except BulkSaveError, e: # resolve conflicts docs1 = [] for doc in e.errors: try: doc['_rev'] = db.last_rev(doc['_id']) docs1.append(doc) except ResourceNotFound: pass if docs1: db.save_docs(docs1)