Ejemplo n.º 1
0
Archivo: dump.py Proyecto: rgalvanb/cdb
def dump_db(dburl, username=None, password=None, boundary=None):
    envelope = MIMEMultipart("mixed", boundary)
    db = Database(dburl)
    if username is not None and password is not None:
        db.resource.http.add_credentials(username, password)
    for docid in db:
        doc = db.get(docid, attachments=True)
        print >> sys.stderr, "Dumping document %r" % doc.id
        attachments = doc.pop("_attachments", {})

        part = MIMEBase("application", "json")
        part.set_payload(json.dumps(doc, sort_keys=True, indent=2))

        if attachments:
            inner = MIMEMultipart("mixed")
            inner.attach(part)
            for name, info in attachments.items():
                content_type = info.get("content_type")
                if content_type is None:  # CouchDB < 0.8
                    content_type = info.get("content-type")
                maintype, subtype = content_type.split("/", 1)
                subpart = MIMEBase(maintype, subtype)
                subpart["Content-ID"] = name
                subpart.set_payload(b64decode(info["data"]))
                inner.attach(subpart)
            part = inner

        part["Content-ID"] = doc.id
        part["ETag"] = doc.rev

        envelope.attach(part)
    return envelope.as_string()
Ejemplo n.º 2
0
	def create_couchdb_client(self, db_url, require_exists=True, **args):
		db = Database(db_url)
		
		if require_exists:
			try:
				db.info()
			except ResourceNotFound:
				raise Exception('No database found at %s' % db.resource.url)
		
		return db
Ejemplo n.º 3
0
def dump_db(dburl, username=None, password=None, boundary=None,
            output=sys.stdout, bulk_size=BULK_SIZE):

    db = Database(dburl)
    if username is not None and password is not None:
        db.resource.credentials = username, password

    envelope = write_multipart(output, boundary=boundary)
    start, num = 0, db.info()['doc_count']
    while start < num:
        opts = {'limit': bulk_size, 'skip': start}
        dump_docs(envelope, [row.id for row in db.view('_all_docs', **opts)], db)
        start += bulk_size

    envelope.close()
Ejemplo n.º 4
0
def dump_db(dburl,
            username=None,
            password=None,
            boundary=None,
            output=sys.stdout,
            bulk_size=BULK_SIZE):

    db = Database(dburl)
    if username is not None and password is not None:
        db.resource.credentials = username, password

    envelope = write_multipart(output, boundary=boundary)
    start, num = 0, db.info()['doc_count']
    while start < num:
        opts = {'limit': bulk_size, 'skip': start, 'include_docs': True}
        dump_docs(envelope, [row.doc for row in db.view('_all_docs', **opts)])
        start += bulk_size

    envelope.close()
Ejemplo n.º 5
0
def dump_db(dburl, username=None, password=None, boundary=None,
            output=None, bulk_size=BULK_SIZE):

    if output is None:
        output = sys.stdout if sys.version_info[0] < 3 else sys.stdout.buffer

    db = Database(dburl)
    if username is not None and password is not None:
        db.resource.credentials = username, password

    envelope = write_multipart(output, boundary=boundary)
    start, num = 0, db.info()['doc_count']
    while start < num:
        opts = {'limit': bulk_size, 'skip': start, 'include_docs': True}
        docs = (row.doc for row in db.view('_all_docs', **opts))
        dump_docs(envelope, db, docs)
        start += bulk_size

    envelope.close()
Ejemplo n.º 6
0
def dump_db(dburl, username=None, password=None, boundary=None,
            output=sys.stdout):
    db = Database(dburl)
    if username is not None and password is not None:
        db.resource.credentials = username, password

    envelope = write_multipart(output, boundary=boundary)
    for docid in db:

        doc = db.get(docid, attachments=True)
        print('Dumping document %r' % doc.id, file=sys.stderr)
        attachments = doc.pop('_attachments', {})
        jsondoc = json.encode(doc)

        if attachments:
            parts = envelope.open({
                'Content-ID': doc.id,
                'ETag': '"%s"' % doc.rev
            })
            parts.add('application/json', jsondoc)

            for name, info in list(attachments.items()):
                content_type = info.get('content_type')
                if content_type is None: # CouchDB < 0.8
                    content_type = info.get('content-type')
                parts.add(content_type, b64decode(info['data']), {
                    'Content-ID': name
                })
            parts.close()

        else:
            envelope.add('application/json', jsondoc, {
                'Content-ID': doc.id,
                'ETag': '"%s"' % doc.rev
            })

    envelope.close()
Ejemplo n.º 7
0
def dump_db(dburl, username=None, password=None, boundary=None,
            output=sys.stdout):
    db = Database(dburl)
    if username is not None and password is not None:
        db.resource.credentials = username, password

    envelope = write_multipart(output, boundary=boundary)
    for docid in db:

        doc = db.get(docid, attachments=True)
        print >> sys.stderr, 'Dumping document %r' % doc.id
        attachments = doc.pop('_attachments', {})
        jsondoc = json.encode(doc)

        if attachments:
            parts = envelope.open({
                'Content-ID': doc.id,
                'ETag': '"%s"' % doc.rev
            })
            parts.add('application/json', jsondoc)

            for name, info in attachments.items():
                content_type = info.get('content_type')
                if content_type is None: # CouchDB < 0.8
                    content_type = info.get('content-type')
                parts.add(content_type, b64decode(info['data']), {
                    'Content-ID': name
                })
            parts.close()

        else:
            envelope.add('application/json', jsondoc, {
                'Content-ID': doc.id,
                'ETag': '"%s"' % doc.rev
            })

    envelope.close()
Ejemplo n.º 8
0
    def get_couch_database(self, url, dbname):
        """
        Generate a couchdb.Database instance given a url and dbname.

        :param url: CouchDB's server url with credentials
        :type url: str
        :param dbname: Database name
        :type dbname: str

        :return: couch library database instance
        :rtype: couchdb.Database

        :raise DatabaseDoesNotExist: Raised if database does not exist.
        """
        try:
            return Database(urljoin(url, dbname), self._session)
        except ResourceNotFound:
            raise DatabaseDoesNotExist()
Ejemplo n.º 9
0
def load_db(fileobj, dburl, username=None, password=None, ignore_errors=False):
    db = Database(dburl)
    if username is not None and password is not None:
        db.resource.credentials = (username, password)
    hostname = Is_Server(dburl, db.name)

    for headers, is_multipart, payload in read_multipart(fileobj):
        docid = headers['content-id']
        time.sleep(1)
        if '-db' in db.name:
            if 'credential' in docid or 'flow' in docid or 'setting' in docid or 'functions' in docid:
                docid = Rename_docid(docid, hostname)
        obj = db.get(docid)
        if obj == None:
            new_doc = {'_id': docid}
            db.save(new_doc)
            obj = db.get(docid)
        if is_multipart:  # doc has attachments
            for headers, _, payload in payload:
                if 'content-id' not in headers:
                    doc = json.decode(payload)
                    doc['_attachments'] = {}
                else:
                    doc['_attachments'][headers['content-id']] = {
                        'data': b64encode(payload).decode('ascii'),
                        'content_type': headers['content-type'],
                        'length': len(payload)
                    }

        else:  # no attachments, just the JSON
            doc = json.decode(payload)
        doc['_rev'] = obj['_rev']
        doc['_id'] = obj['_id']
        print('Loading document %r' % docid, file=sys.stderr)
        try:
            db[docid] = doc
        except Exception as e:
            if not ignore_errors:
                raise
            print('Error: %s' % e, file=sys.stderr)
Ejemplo n.º 10
0
class CouchFSDatabase(fuse.Fuse):
    def __init__(self, mountpoint, db_uri=None, *args, **kwargs):
        print "db_uri: " + repr(db_uri)
        fuse.Fuse.__init__(self, *args, **kwargs)
        self.db = Database(db_uri)

    def readdir(self, path, offset):
        print self.db
        path = _path_to_docid(path)
        print "readdir: %r" % path
        for r in '.', '..':
            yield fuse.Direntry(r)

        if path == "":
            startkey = "+,\0"
            endkey = "+" + chr(ord(",") + 1)
        else:
            startkey = "+" + path + "/"
            endkey = "+" + path + chr(ord("/") + 1)
        for row in self.db.view('_all_docs', startkey=startkey,
                                endkey=endkey).rows:
            cpath = row.key
            #TODO unescape, if necessary
            print repr(cpath)
            if "," in cpath:
                prefix, cpath = cpath.split(",", 1)
                if "/" in cpath:
                    dirname, name = cpath.rsplit("/", 1)
                else:
                    name = cpath
                yield fuse.Direntry(name.encode('utf-8'))

    def children_count(self, docid):
        print self.db
        print "children_count: %r" % docid

        if docid == "":
            startkey = "+,\0"
            endkey = "+" + chr(ord(",") + 1)
        else:
            startkey = "+" + docid + "/"
            endkey = "+" + docid + chr(ord("/") + 1)

        return 2 + self.db.view(
            '_all_docs', startkey=startkey, endkey=endkey, limit=0).total_rows

    def getattr(self, path):
        path = _path_to_docid(path)
        print "getattr: %r, %r" % (path, path in self.db)
        try:
            st = CouchStat()
            if path == '':
                #TODO we should create a "." document for the root directory
                st.st_mode = stat.S_IFDIR | 0775
                st.st_nlink = self.children_count(path)
                return st

            doc = self.db[path]
        except (KeyError, ResourceNotFound):
            return -errno.ENOENT

        if doc["type"] == "dir":
            st.st_mode = stat.S_IFDIR | doc["mode"]
            st.st_nlink = self.children_count(path)
            st.st_mtime = doc["mtime"]
        else:
            data = self.db[path].get('_attachments',
                                     {}).get("content", {"length": 0})
            print repr(data)
            print repr(doc)
            st.st_mode = stat.S_IFREG | doc["mode"]
            st.st_nlink = 1
            st.st_size = data['length']
            st.st_mtime = doc["mtime"]
        return st

    def open(self, path, flags):
        path = _path_to_docid(path)
        try:
            doc = self.db[path]
            #TODO check mode
            #TODO should we allow open for directories?
            if doc:
                return 0
            else:
                return -errno.ENOENT
        except (KeyError, ResourceNotFound):
            return -errno.ENOENT
        #accmode = os.O_RDONLY | os.O_WRONLY | os.O_RDWR
        #if (flags & accmode) != os.O_RDONLY:
        #    return -errno.EACCES

    def read(self, path, size, offset):
        path = _path_to_docid(path)
        try:
            data = self.db.get_attachment(self.db[path], "content")
            if isinstance(data, cStringIO.InputType):
                data = data.getvalue()
            elif data is None:
                data = ""
            slen = len(data)
            if offset < slen:
                if offset + size > slen:
                    size = slen - offset
                buf = data[offset:offset + size]
            else:
                buf = ''
            return buf
        except (KeyError, ResourceNotFound):
            pass
        return -errno.ENOENT

    def write(self, path, buf, offset):
        path = _path_to_docid(path)
        try:
            #TODO can we push some Javascript that does the change on the server?
            # -> http://wiki.apache.org/couchdb/Document_Update_Handlers
            self._update_mtime(path)
            data = self.db.get_attachment(self.db[path], "content")
            if data is None:
                data = ""
            elif isinstance(data, cStringIO.InputType):
                data = data.getvalue()
            data = data[0:offset] + buf + data[offset + len(buf):]
            self.db.put_attachment(self.db[path], data, filename="content")
            return len(buf)
        except (KeyError, ResourceNotFound):
            pass
        return -errno.ENOENT

    def _current_time(self):
        return int(time())

    def _update_mtime(self, docid):
        doc = self.db[docid]
        doc["mtime"] = self._current_time()
        self.db.save(doc)

    def _update_mtime_for_parent(self, path):
        if "/" in path:
            parent, name = path.rsplit("/", 1)
            self._update_mtime(_path_to_docid(parent))
        else:
            #TODO update root directory unless normalized path is ""
            pass

    def mknod(self, path, mode, dev):
        if (mode & stat.S_IFREG) != 0:
            type = "file"
        else:
            type = "special"
        path = _path_to_docid(path)
        self.db.save({
            "_id": path,
            "type": type,
            "mode": mode,
            "dev": dev,
            "mtime": self._current_time()
        })
        if type == "file":
            self.db.put_attachment(self.db[path], u'', filename="content")
        return 0

    def unlink(self, path):
        path = _path_to_docid(path)
        del self.db[path]

        # recreate directory placeholder, if necessary
        parts = path.rsplit(u'/', 1)
        if len(parts) == 1:
            dirname, filename = u'', parts[0]
        else:
            dirname, filename = parts

    def truncate(self, path, size):
        path = _path_to_docid(path)
        self.db.put_attachment(self.db[path], u'', filename="content")
        return 0

    def utime(self, path, times):
        return 0

    def mkdir(self, path, mode):
        path = _path_to_docid(path)
        if path in self.db:
            return -errno.EACCES
        self.db.save({
            "_id": path,
            "type": "dir",
            "mode": mode,
            "mtime": self._current_time()
        })
        return 0

    def rmdir(self, path):
        path = _path_to_docid(path)
        #TODO don't delete non-empty directories
        if path not in self.db:
            return -errno.ENOENT
        elif self.db[path]["type"] != "dir":
            return -errno.EACCES
        del self.db[path]
        return 0

    def rename(self, pathfrom, pathto):
        #TODO use self.db.copy(...)
        pathfrom, pathto = _path_to_docid(pathfrom), _path_to_docid(pathto)
        doc = self.db[pathfrom].clone()
        doc["_id"] = pathto
        self.db.save(doc)
        data = self.db.get_attachment(self.db[pathfrom], "content")
        if isinstance(data, cStringIO.InputType):
            data = data.getvalue()
        elif data is None:
            data = ""
        self.db.put_attachment(self.db[pathto], data, filename="content")
        del self.db[pathfrom]
        return 0

    def fsync(self, path, isfsyncfile):
        self.db.commit()
        return 0

    def statfs(self):
        """
        Should return a tuple with the following 6 elements:
            - blocksize - size of file blocks, in bytes
            - totalblocks - total number of blocks in the filesystem
            - freeblocks - number of free blocks
            - availblocks - number of blocks available to non-superuser
            - totalfiles - total number of file inodes
            - freefiles - nunber of free file inodes
    
        Feel free to set any of the above values to 0, which tells
        the kernel that the info is not available.
        """
        st = fuse.StatVfs()
        block_size = 1024
        blocks = 1024 * 1024
        blocks_free = blocks
        blocks_avail = blocks_free
        files = 0
        files_free = 0
        st.f_bsize = block_size
        st.f_frsize = block_size
        st.f_blocks = blocks
        st.f_bfree = blocks_free
        st.f_bavail = blocks_avail
        st.f_files = files
        st.f_ffree = files_free
        return st
Ejemplo n.º 11
0
 def __init__(self, mountpoint, uri=None, *args, **kwargs):
     fuse.Fuse.__init__(self, *args, **kwargs)
     db_uri, doc_id = uri.rsplit('/', 1)
     self.doc_id = unquote(doc_id)
     self.db = Database(db_uri)
Ejemplo n.º 12
0
class CouchFSDocument(fuse.Fuse):
    def __init__(self, mountpoint, uri=None, *args, **kwargs):
        fuse.Fuse.__init__(self, *args, **kwargs)
        db_uri, doc_id = uri.rsplit('/', 1)
        self.doc_id = unquote(doc_id)
        self.db = Database(db_uri)

    def get_dirs(self):
        dirs = {}
        attachments = self.db[self.doc_id].get('_attachments', {}).keys()
        for att in attachments:
            parents = [u'']
            for name in att.split('/'):
                filenames = dirs.setdefault(u'/'.join(parents[1:]), set())
                if name != COUCHFS_DIRECTORY_PLACEHOLDER:
                    filenames.add(name)
                    parents.append(name)
        return dirs

    def readdir(self, path, offset):
        path = _normalize_path(path)
        for r in '.', '..':
            yield fuse.Direntry(r)
        for name in self.get_dirs().get(path, []):
            yield fuse.Direntry(name.encode('utf-8'))

    def getattr(self, path):
        path = _normalize_path(path)
        try:
            st = CouchStat()
            if path == '' or path in self.get_dirs().keys():
                st.st_mode = stat.S_IFDIR | 0775
                st.st_nlink = 2
            else:
                att = self.db[self.doc_id].get('_attachments', {})
                data = att[path]
                st.st_mode = stat.S_IFREG | 0664
                st.st_nlink = 1
                st.st_size = data['length']
            return st
        except (KeyError, ResourceNotFound):
            return -errno.ENOENT

    def open(self, path, flags):
        path = _normalize_path(path)
        try:
            #data = self.db.get_attachment(self.db[self.doc_id], path.split('/')[-1])
            #att = self.db[self.doc_id].get('_attachments', {})
            #data = att[path.split('/')[-1]]
            parts = path.rsplit(u'/', 1)
            if len(parts) == 1:
                dirname, filename = u'', parts[0]
            else:
                dirname, filename = parts
            if filename in self.get_dirs()[dirname]:
                return 0
            return -errno.ENOENT
        except (KeyError, ResourceNotFound):
            return -errno.ENOENT
        #accmode = os.O_RDONLY | os.O_WRONLY | os.O_RDWR
        #if (flags & accmode) != os.O_RDONLY:
        #    return -errno.EACCES

    def read(self, path, size, offset):
        path = _normalize_path(path)
        try:
            data = self.db.get_attachment(self.db[self.doc_id], path)
            if isinstance(data, cStringIO.InputType):
                data = data.getvalue()
            elif data is None:
                data = ""
            slen = len(data)
            if offset < slen:
                if offset + size > slen:
                    size = slen - offset
                buf = data[offset:offset+size]
            else:
                buf = ''
            return buf
        except (KeyError, ResourceNotFound):
            pass
        return -errno.ENOENT

    def write(self, path, buf, offset):
        path = _normalize_path(path)
        try:
            data = self.db.get_attachment(self.db[self.doc_id], path)
            if data is None:
                data = ""
            elif isinstance(data, cStringIO.InputType):
                data = data.getvalue()
            data = data[0:offset] + buf + data[offset+len(buf):]
            self.db.put_attachment(self.db[self.doc_id], data, filename=path)
            return len(buf)
        except (KeyError, ResourceNotFound):
            pass
        return -errno.ENOENT

    def mknod(self, path, mode, dev):
        path = _normalize_path(path)
        self.db.put_attachment(self.db[self.doc_id], u'', filename=path)

    def unlink(self, path):
        path = _normalize_path(path)
        parts = path.rsplit(u'/', 1)
        if len(parts) == 1:
            dirname, filename = u'', parts[0]
        else:
            dirname, filename = parts
        self.db.delete_attachment(self.db[self.doc_id], path)
        if filename != COUCHFS_DIRECTORY_PLACEHOLDER and len(self.get_dirs().get(dirname, [])) == 0:
            print "putting to:", u'%s/%s' % (dirname, COUCHFS_DIRECTORY_PLACEHOLDER)
            self.db.put_attachment(self.db[self.doc_id], u'', filename=u'%s/%s' % (dirname, COUCHFS_DIRECTORY_PLACEHOLDER))

    def truncate(self, path, size):
        path = _normalize_path(path)
        self.db.put_attachment(self.db[self.doc_id], u'', filename=path)
        return 0

    def utime(self, path, times):
        return 0

    def mkdir(self, path, mode):
        path = _normalize_path(path)
        self.db.put_attachment(self.db[self.doc_id], u'', filename=u'%s/%s' % (path, COUCHFS_DIRECTORY_PLACEHOLDER))
        return 0

    def rmdir(self, path):
        path = _normalize_path(path)
        self.db.delete_attachment(self.db[self.doc_id], u'%s/%s' % (path, COUCHFS_DIRECTORY_PLACEHOLDER))
        return 0

    def rename(self, pathfrom, pathto):
        pathfrom, pathto = _normalize_path(pathfrom), _normalize_path(pathto)
        data = self.db.get_attachment(self.db[self.doc_id], pathfrom)
        if isinstance(data, cStringIO.InputType):
            data = data.getvalue()
        elif data is None:
            data = ""
        self.db.put_attachment(self.db[self.doc_id], data, filename=pathto)
        self.db.delete_attachment(self.db[self.doc_id], pathfrom)
        return 0

    def fsync(self, path, isfsyncfile):
        return 0

    def statfs(self):
        """
        Should return a tuple with the following 6 elements:
            - blocksize - size of file blocks, in bytes
            - totalblocks - total number of blocks in the filesystem
            - freeblocks - number of free blocks
            - availblocks - number of blocks available to non-superuser
            - totalfiles - total number of file inodes
            - freefiles - nunber of free file inodes
    
        Feel free to set any of the above values to 0, which tells
        the kernel that the info is not available.
        """
        st = fuse.StatVfs()
        block_size = 1024
        blocks = 1024 * 1024
        blocks_free = blocks
        blocks_avail = blocks_free
        files = 0
        files_free = 0
        st.f_bsize = block_size
        st.f_frsize = block_size
        st.f_blocks = blocks
        st.f_bfree = blocks_free
        st.f_bavail = blocks_avail
        st.f_files = files
        st.f_ffree = files_free
        return st
Ejemplo n.º 13
0
 def __init__(self, mountpoint, db_uri=None, *args, **kwargs):
     print "db_uri: " + repr(db_uri)
     fuse.Fuse.__init__(self, *args, **kwargs)
     self.db = Database(db_uri)
Ejemplo n.º 14
0
class CouchFSDatabase(fuse.Fuse):
    def __init__(self, mountpoint, db_uri=None, *args, **kwargs):
        print "db_uri: " + repr(db_uri)
        fuse.Fuse.__init__(self, *args, **kwargs)
        self.db = Database(db_uri)

    def readdir(self, path, offset):
        print self.db
        path = _path_to_docid(path)
        print "readdir: %r" % path
        for r in '.', '..':
            yield fuse.Direntry(r)

        if path == "":
            startkey = "+,\0"
            endkey   = "+" + chr(ord(",")+1)
        else:
            startkey = "+" + path + "/"
            endkey   = "+" + path + chr(ord("/")+1)
        for row in self.db.view('_all_docs', startkey=startkey, endkey=endkey).rows:
            cpath = row.key
            #TODO unescape, if necessary
            print repr(cpath)
            if "," in cpath:
                prefix, cpath = cpath.split(",", 1)
                if "/" in cpath:
                    dirname, name = cpath.rsplit("/", 1)
                else:
                    name = cpath
                yield fuse.Direntry(name.encode('utf-8'))

    def children_count(self, docid):
        print self.db
        print "children_count: %r" % docid

        if docid == "":
            startkey = "+,\0"
            endkey   = "+" + chr(ord(",")+1)
        else:
            startkey = "+" + docid + "/"
            endkey   = "+" + docid + chr(ord("/")+1)

        return 2 + self.db.view('_all_docs', startkey=startkey, endkey=endkey, limit=0).total_rows

    def getattr(self, path):
        path = _path_to_docid(path)
        print "getattr: %r, %r" % (path, path in self.db)
        try:
            st = CouchStat()
            if path == '':
                #TODO we should create a "." document for the root directory
                st.st_mode = stat.S_IFDIR | 0775
                st.st_nlink = self.children_count(path)
                return st

            doc = self.db[path]
        except (KeyError, ResourceNotFound):
            return -errno.ENOENT

        if doc["type"] == "dir":
            st.st_mode = stat.S_IFDIR | doc["mode"]
            st.st_nlink = self.children_count(path)
            st.st_mtime = doc["mtime"]
        else:
            data = self.db[path].get('_attachments', {}).get("content", {"length":0})
            print repr(data)
            print repr(doc)
            st.st_mode = stat.S_IFREG | doc["mode"]
            st.st_nlink = 1
            st.st_size = data['length']
            st.st_mtime = doc["mtime"]
        return st

    def open(self, path, flags):
        path = _path_to_docid(path)
        try:
            doc = self.db[path]
            #TODO check mode
            #TODO should we allow open for directories?
            if doc:
                return 0
            else:
                return -errno.ENOENT
        except (KeyError, ResourceNotFound):
            return -errno.ENOENT
        #accmode = os.O_RDONLY | os.O_WRONLY | os.O_RDWR
        #if (flags & accmode) != os.O_RDONLY:
        #    return -errno.EACCES

    def read(self, path, size, offset):
        path = _path_to_docid(path)
        try:
            data = self.db.get_attachment(self.db[path], "content")
            if isinstance(data, cStringIO.InputType):
                data = data.getvalue()
            elif data is None:
                data = ""
            slen = len(data)
            if offset < slen:
                if offset + size > slen:
                    size = slen - offset
                buf = data[offset:offset+size]
            else:
                buf = ''
            return buf
        except (KeyError, ResourceNotFound):
            pass
        return -errno.ENOENT

    def write(self, path, buf, offset):
        path = _path_to_docid(path)
        try:
            #TODO can we push some Javascript that does the change on the server?
            # -> http://wiki.apache.org/couchdb/Document_Update_Handlers
            self._update_mtime(path)
            data = self.db.get_attachment(self.db[path], "content")
            if data is None:
                data = ""
            elif isinstance(data, cStringIO.InputType):
                data = data.getvalue()
            data = data[0:offset] + buf + data[offset+len(buf):]
            self.db.put_attachment(self.db[path], data, filename="content")
            return len(buf)
        except (KeyError, ResourceNotFound):
            pass
        return -errno.ENOENT

    def _current_time(self):
        return int(time())

    def _update_mtime(self, docid):
        doc = self.db[docid]
        doc["mtime"] = self._current_time()
        self.db.save(doc)

    def _update_mtime_for_parent(self, path):
        if "/" in path:
            parent, name = path.rsplit("/", 1)
            self._update_mtime(_path_to_docid(parent))
        else:
            #TODO update root directory unless normalized path is ""
            pass

    def mknod(self, path, mode, dev):
        if (mode & stat.S_IFREG) != 0:
            type = "file"
        else:
            type = "special"
        path = _path_to_docid(path)
        self.db.save({
            "_id": path,
            "type": type,
            "mode": mode,
            "dev": dev,
            "mtime": self._current_time()
        })
        if type == "file":
            self.db.put_attachment(self.db[path], u'', filename="content")
        return 0

    def unlink(self, path):
        path = _path_to_docid(path)
        del self.db[path]

        # recreate directory placeholder, if necessary
        parts = path.rsplit(u'/', 1)
        if len(parts) == 1:
            dirname, filename = u'', parts[0]
        else:
            dirname, filename = parts

    def truncate(self, path, size):
        path = _path_to_docid(path)
        self.db.put_attachment(self.db[path], u'', filename="content")
        return 0

    def utime(self, path, times):
        return 0

    def mkdir(self, path, mode):
        path = _path_to_docid(path)
        if path in self.db:
            return -errno.EACCES
        self.db.save({
            "_id": path,
            "type": "dir",
            "mode": mode,
            "mtime": self._current_time()
        })
        return 0

    def rmdir(self, path):
        path = _path_to_docid(path)
        #TODO don't delete non-empty directories
        if path not in self.db:
            return -errno.ENOENT
        elif self.db[path]["type"] != "dir":
            return -errno.EACCES
        del self.db[path]
        return 0

    def rename(self, pathfrom, pathto):
        #TODO use self.db.copy(...)
        pathfrom, pathto = _path_to_docid(pathfrom), _path_to_docid(pathto)
        doc = self.db[pathfrom].clone()
        doc["_id"] = pathto
        self.db.save(doc)
        data = self.db.get_attachment(self.db[pathfrom], "content")
        if isinstance(data, cStringIO.InputType):
            data = data.getvalue()
        elif data is None:
            data = ""
        self.db.put_attachment(self.db[pathto], data, filename="content")
        del self.db[pathfrom]
        return 0

    def fsync(self, path, isfsyncfile):
        self.db.commit()
        return 0

    def statfs(self):
        """
        Should return a tuple with the following 6 elements:
            - blocksize - size of file blocks, in bytes
            - totalblocks - total number of blocks in the filesystem
            - freeblocks - number of free blocks
            - availblocks - number of blocks available to non-superuser
            - totalfiles - total number of file inodes
            - freefiles - nunber of free file inodes
    
        Feel free to set any of the above values to 0, which tells
        the kernel that the info is not available.
        """
        st = fuse.StatVfs()
        block_size = 1024
        blocks = 1024 * 1024
        blocks_free = blocks
        blocks_avail = blocks_free
        files = 0
        files_free = 0
        st.f_bsize = block_size
        st.f_frsize = block_size
        st.f_blocks = blocks
        st.f_bfree = blocks_free
        st.f_bavail = blocks_avail
        st.f_files = files
        st.f_ffree = files_free
        return st
Ejemplo n.º 15
0
class CouchFSDocument(fuse.Fuse):
    def __init__(self, mountpoint, uri=None, *args, **kwargs):
        fuse.Fuse.__init__(self, *args, **kwargs)
        db_uri, doc_id = uri.rsplit('/', 1)
        self.doc_id = unquote(doc_id)
        self.db = Database(db_uri)

    def get_dirs(self):
        dirs = {}
        attachments = self.db[self.doc_id].get('_attachments', {}).keys()
        for att in attachments:
            parents = [u'']
            for name in att.split('/'):
                filenames = dirs.setdefault(u'/'.join(parents[1:]), set())
                if name != COUCHFS_DIRECTORY_PLACEHOLDER:
                    filenames.add(name)
                    parents.append(name)
        return dirs

    def readdir(self, path, offset):
        path = _normalize_path(path)
        for r in '.', '..':
            yield fuse.Direntry(r)
        for name in self.get_dirs().get(path, []):
            yield fuse.Direntry(name.encode('utf-8'))

    def getattr(self, path):
        path = _normalize_path(path)
        try:
            st = CouchStat()
            if path == '' or path in self.get_dirs().keys():
                st.st_mode = stat.S_IFDIR | 0775
                st.st_nlink = 2
            else:
                att = self.db[self.doc_id].get('_attachments', {})
                data = att[path]
                st.st_mode = stat.S_IFREG | 0664
                st.st_nlink = 1
                st.st_size = data['length']
            return st
        except (KeyError, ResourceNotFound):
            return -errno.ENOENT

    def open(self, path, flags):
        path = _normalize_path(path)
        try:
            #data = self.db.get_attachment(self.db[self.doc_id], path.split('/')[-1])
            #att = self.db[self.doc_id].get('_attachments', {})
            #data = att[path.split('/')[-1]]
            parts = path.rsplit(u'/', 1)
            if len(parts) == 1:
                dirname, filename = u'', parts[0]
            else:
                dirname, filename = parts
            if filename in self.get_dirs()[dirname]:
                return 0
            return -errno.ENOENT
        except (KeyError, ResourceNotFound):
            return -errno.ENOENT
        #accmode = os.O_RDONLY | os.O_WRONLY | os.O_RDWR
        #if (flags & accmode) != os.O_RDONLY:
        #    return -errno.EACCES

    def read(self, path, size, offset):
        path = _normalize_path(path)
        try:
            data = self.db.get_attachment(self.db[self.doc_id], path)
            if isinstance(data, cStringIO.InputType):
                data = data.getvalue()
            elif data is None:
                data = ""
            slen = len(data)
            if offset < slen:
                if offset + size > slen:
                    size = slen - offset
                buf = data[offset:offset + size]
            else:
                buf = ''
            return buf
        except (KeyError, ResourceNotFound):
            pass
        return -errno.ENOENT

    def write(self, path, buf, offset):
        path = _normalize_path(path)
        try:
            data = self.db.get_attachment(self.db[self.doc_id], path)
            if data is None:
                data = ""
            elif isinstance(data, cStringIO.InputType):
                data = data.getvalue()
            data = data[0:offset] + buf + data[offset + len(buf):]
            self.db.put_attachment(self.db[self.doc_id], data, filename=path)
            return len(buf)
        except (KeyError, ResourceNotFound):
            pass
        return -errno.ENOENT

    def mknod(self, path, mode, dev):
        path = _normalize_path(path)
        self.db.put_attachment(self.db[self.doc_id], u'', filename=path)

    def unlink(self, path):
        path = _normalize_path(path)
        parts = path.rsplit(u'/', 1)
        if len(parts) == 1:
            dirname, filename = u'', parts[0]
        else:
            dirname, filename = parts
        self.db.delete_attachment(self.db[self.doc_id], path)
        if filename != COUCHFS_DIRECTORY_PLACEHOLDER and len(
                self.get_dirs().get(dirname, [])) == 0:
            print "putting to:", u'%s/%s' % (dirname,
                                             COUCHFS_DIRECTORY_PLACEHOLDER)
            self.db.put_attachment(self.db[self.doc_id],
                                   u'',
                                   filename=u'%s/%s' %
                                   (dirname, COUCHFS_DIRECTORY_PLACEHOLDER))

    def truncate(self, path, size):
        path = _normalize_path(path)
        self.db.put_attachment(self.db[self.doc_id], u'', filename=path)
        return 0

    def utime(self, path, times):
        return 0

    def mkdir(self, path, mode):
        path = _normalize_path(path)
        self.db.put_attachment(self.db[self.doc_id],
                               u'',
                               filename=u'%s/%s' %
                               (path, COUCHFS_DIRECTORY_PLACEHOLDER))
        return 0

    def rmdir(self, path):
        path = _normalize_path(path)
        self.db.delete_attachment(
            self.db[self.doc_id],
            u'%s/%s' % (path, COUCHFS_DIRECTORY_PLACEHOLDER))
        return 0

    def rename(self, pathfrom, pathto):
        pathfrom, pathto = _normalize_path(pathfrom), _normalize_path(pathto)
        data = self.db.get_attachment(self.db[self.doc_id], pathfrom)
        if isinstance(data, cStringIO.InputType):
            data = data.getvalue()
        elif data is None:
            data = ""
        self.db.put_attachment(self.db[self.doc_id], data, filename=pathto)
        self.db.delete_attachment(self.db[self.doc_id], pathfrom)
        return 0

    def fsync(self, path, isfsyncfile):
        return 0

    def statfs(self):
        """
        Should return a tuple with the following 6 elements:
            - blocksize - size of file blocks, in bytes
            - totalblocks - total number of blocks in the filesystem
            - freeblocks - number of free blocks
            - availblocks - number of blocks available to non-superuser
            - totalfiles - total number of file inodes
            - freefiles - nunber of free file inodes
    
        Feel free to set any of the above values to 0, which tells
        the kernel that the info is not available.
        """
        st = fuse.StatVfs()
        block_size = 1024
        blocks = 1024 * 1024
        blocks_free = blocks
        blocks_avail = blocks_free
        files = 0
        files_free = 0
        st.f_bsize = block_size
        st.f_frsize = block_size
        st.f_blocks = blocks
        st.f_bfree = blocks_free
        st.f_bavail = blocks_avail
        st.f_files = files
        st.f_ffree = files_free
        return st
Ejemplo n.º 16
0
 def __init__(self, mountpoint, db_uri=None, *args, **kwargs):
     print "db_uri: " + repr(db_uri)
     fuse.Fuse.__init__(self, *args, **kwargs)
     self.db = Database(db_uri)
Ejemplo n.º 17
0
 def __init__(self, mountpoint, uri=None, *args, **kwargs):
     fuse.Fuse.__init__(self, *args, **kwargs)
     db_uri, doc_id = uri.rsplit('/', 1)
     self.doc_id = unquote(doc_id)
     self.db = Database(db_uri)
Ejemplo n.º 18
0
from datetime import datetime
from django.contrib.auth.models import User
from django.db.models.signals import class_prepared
from django.contrib.auth.models import UserManager as Manager
from couchdb.client import Server, Database
from couchdb.http import PreconditionFailed
from django.db.models.signals import post_save
import json

COUCHDB_HOST = 'http://211.101.12.224'
COUCHDB_PORT = '5984'
COUCHDB_ROOT_USERNAME = '******'
COUCHDB_ROOT_PASSWORD = '******'
server = Server('{0}:{1}'.format(COUCHDB_HOST, COUCHDB_PORT))
server.resource.credentials = (COUCHDB_ROOT_USERNAME, COUCHDB_ROOT_PASSWORD)
userdb = Database('{0}:{1}/_users'.format(COUCHDB_HOST, COUCHDB_PORT))
userdb.resource.credentials = (COUCHDB_ROOT_USERNAME, COUCHDB_ROOT_PASSWORD)


class UserManager(Manager):
    """automatically create corresponding user syncable database in couchdb"""
    def create_user(self, username, email=None, password=None):
        user = super(UserManager, self).create_user(username, email, password)
        if user:
            try:
                server.create('user_sync_db_{0}'.format(user.pk))
            except PreconditionFailed:
                user.delete()
                raise PreconditionFailed
        return user