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()
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
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()
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()
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()
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()
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()
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()
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)
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
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)
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
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)
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
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
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