Example #1
0
    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)
Example #2
0
 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)
Example #3
0
    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)
Example #4
0
    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)
Example #5
0
    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)
Example #6
0
 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)
Example #7
0
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
Example #8
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
Example #9
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
Example #10
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
Example #11
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)
Example #12
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)
Example #13
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))
    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)
Example #14
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))
    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)
Example #15
0
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
Example #16
0
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
Example #17
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
Example #18
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
Example #19
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
Example #20
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)
Example #21
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', '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))
Example #22
0
 def setup_couchapprc(self):
     '''
     Setup empty .couchapprc
     '''
     util.write_json(os.path.join(self.path, '.couchapprc'), {})
Example #23
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
Example #24
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))
Example #25
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 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)