def __init__(self, root): '''''' super(ConfigurablePyFuseBox, self).__init__(root, None) self.virtual_file = VirtualConfigFile(self.VIRTUAL_CONFIG_FILE, self) self.store_initialized = False self.logger.debug("initialized configurable pyfusebox") # public variable to trigger profiling in modules interactively (i.e. StoreSyncThread) self.do_profiling = False
def __init__(self, root): '''''' super( ConfigurablePyFuseBox, self ).__init__(root, None) self.virtual_file = VirtualConfigFile(self.VIRTUAL_CONFIG_FILE, self) self.store_initialized = False self.logger.debug("initialized configurable pyfusebox") # public variable to trigger profiling in modules interactively (i.e. StoreSyncThread) self.do_profiling = False
class ConfigurablePyFuseBox(PyFuseBox): '''Offers a virtual configuration file, to configure Cloudfusion at runtime. To better separate the data from the configuration directory, data can be accessed in the top level directory data, and the configuration file can be accessed in the top level directory config. ''' VIRTUAL_CONFIG_FILE = '/config/config' DATA_FOLDER_PATH = "/data" def __init__(self, root): '''''' super(ConfigurablePyFuseBox, self).__init__(root, None) self.virtual_file = VirtualConfigFile(self.VIRTUAL_CONFIG_FILE, self) self.store_initialized = False self.logger.debug("initialized configurable pyfusebox") # public variable to trigger profiling in modules interactively (i.e. StoreSyncThread) self.do_profiling = False def enable_logging(self): if not os.path.exists(".cloudfusion/logs"): os.makedirs(".cloudfusion/logs") logging.config.fileConfig( os.path.dirname(cloudfusion.__file__) + '/config/logging.conf') db_logging_thread.start() #.handlers = [] logging.disable(logging.NOTSET) def disable_logging(self): logging.disable(logging.CRITICAL) db_logging_thread.stop() def _getattr_for_folder_with_full_access(self): st = zstat() st['st_mode'] = 0777 | stat.S_IFDIR st['st_nlink'] = 2 st['st_size'] = 4096 st['st_blocks'] = (int)((st['st_size'] + 4095L) / 4096L) return st def getattr(self, path, fh=None): self.logger.debug("getattr %s", path) if path == "/": return self._getattr_for_folder_with_full_access() if path == self.virtual_file.get_path(): return self.virtual_file.getattr() if self.virtual_file.get_subdir(path): return self._getattr_for_folder_with_full_access() if self.store_initialized and path.startswith( self.DATA_FOLDER_PATH + '/'): #slash prevents getattr on /datata/x path = self.remove_data_folder_prefix(path) return super(ConfigurablePyFuseBox, self).getattr(path, fh) if path == self.DATA_FOLDER_PATH: return self._getattr_for_folder_with_full_access() raise FuseOSError(ENOENT) def truncate(self, path, length, fh=None): self.logger.debug("truncate %s to %s", path, length) if path == self.virtual_file.get_path(): self.virtual_file.truncate() return 0 if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super(ConfigurablePyFuseBox, self).truncate(path, length, fh) raise FuseOSError(ENOENT) def rmdir(self, path): self.logger.debug("rmdir %s", path) if path == self.DATA_FOLDER_PATH or path == self.virtual_file.get_dir( ): raise FuseOSError(EACCES) if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super(ConfigurablePyFuseBox, self).rmdir(path) raise FuseOSError(ENOENT) def mkdir(self, path, mode): self.logger.debug("mkdir %s with mode: %s", path, mode) if path == self.DATA_FOLDER_PATH: raise FuseOSError(EEXIST) if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super(ConfigurablePyFuseBox, self).mkdir(path, mode) raise FuseOSError(EACCES) def remove_data_folder_prefix(self, path): path = path[len(self.DATA_FOLDER_PATH):] if not path.startswith("/"): path = "/" return path def statfs(self, path): #add size of vtf self.logger.debug("statfs %s", path) if self.store_initialized: path = self.remove_data_folder_prefix(path) return super(ConfigurablePyFuseBox, self).statfs(path) def rename(self, old, new): self.logger.debug("rename %s to %s", old, new) if old == self.virtual_file.get_path( ) and os.path.basename(new).startswith( '.fuse_hidden' ): #rename to .fuse_hidden is like a remove (see: hard remove option in fuse manpage for details) print "shutdown" if sys.platform == "darwin": args = ["diskutil", "umount", self.root] elif "freebsd" in sys.platform: args = ["umount", "-l", self.root] else: args = ["fusermount", "-zu", self.root] import subprocess subprocess.Popen(args) sleep(5) # Give CloudFusion some time to unmount. # If it does not work terminate it the hard way. os.kill(os.getpid(), signal.SIGINT) """if new == self.virtual_file.get_path(): buf = written_bytes = self.virtual_file.write(buf, offset) if written_bytes >0: # configuration changed self._initialize_store() return written_bytes""" if old == self.DATA_FOLDER_PATH: raise FuseOSError(EACCES) if new == self.DATA_FOLDER_PATH: raise FuseOSError(EACCES) if self.store_initialized and old.startswith( self.DATA_FOLDER_PATH) and new.startswith( self.DATA_FOLDER_PATH): old = self.remove_data_folder_prefix(old) new = self.remove_data_folder_prefix(new) return super(ConfigurablePyFuseBox, self).rename(old, new) raise FuseOSError(EACCES) def create(self, path, mode): self.logger.debug("create %s with mode %s", path, mode) if path == self.DATA_FOLDER_PATH: raise FuseOSError(EACCES) if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super(ConfigurablePyFuseBox, self).create(path, mode) raise FuseOSError(EACCES) def unlink(self, path): if path == self.virtual_file.get_path(): if sys.platform == "darwin": args = ["diskutil", "umount", self.root] elif "freebsd" in sys.platform: args = ["umount", "-l", self.root] else: args = ["fusermount", "-zu", self.root] import subprocess subprocess.Popen(args) sleep(5) # Give CloudFusion some time to unmount. # If it does not work terminate it the hard way. os.kill(os.getpid(), signal.SIGINT) if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) super(ConfigurablePyFuseBox, self).unlink(path) def read(self, path, size, offset, fh): #self.logger.debug("read %s", path) if path == self.virtual_file.get_path(): return self.virtual_file.read(size, offset) if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super(ConfigurablePyFuseBox, self).read(path, size, offset, fh) def write(self, path, buf, offset, fh): #self.logger.debug("write %s ... starting with %s at %s - fh: %s", path, buf[0:10], offset, fh) if path == self.virtual_file.get_path(): self.logger.debug("writing to virtual file %s", path) written_bytes = self.virtual_file.write(buf, offset) return written_bytes if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super(ConfigurablePyFuseBox, self).write(path, buf, offset, fh) return 0 def flush(self, path, fh): self.logger.debug("flush %s - fh: %s", path, fh) if path == self.virtual_file.get_path(): return 0 if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super(ConfigurablePyFuseBox, self).flush(path, fh) def release(self, path, fh): self.logger.debug("release %s - fh: %s", path, fh) if path == self.virtual_file.get_path(): return 0 if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super(ConfigurablePyFuseBox, self).release(path, fh) def readdir(self, path, fh): self.logger.debug("readdir %s", path) directories = [] if path == self.virtual_file.get_dir(): #add virtual file directories.append(self.virtual_file.get_name()) if path == "/": # add virtual folders directories.append(self.virtual_file.get_dir()) directories.append(os.path.basename(self.DATA_FOLDER_PATH)) elif self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) directories += self.store.get_directory_listing(path) #self.logger.debug("readdir -> "+str(directories)+"") file_objects = [".", ".."] for file_object in directories: if file_object != "/": file_object = os.path.basename(file_object.encode('utf8')) file_objects.append(file_object) return file_objects
def __init__(self, root): self.virtual_file = VirtualConfigFile(self.VIRTUAL_CONFIG_FILE) self.store_initialized = False self.logger = logging.getLogger('pyfusebox') self.logger.debug("initialized configurable pyfusebox") super( ConfigurablePyFuseBox, self ).__init__(root, None)
class ConfigurablePyFuseBox(FlushingPyFuseBox): VIRTUAL_CONFIG_FILE = '/config/config' DATA_FOLDER_PATH = "/data" def __init__(self, root): self.virtual_file = VirtualConfigFile(self.VIRTUAL_CONFIG_FILE) self.store_initialized = False self.logger = logging.getLogger('pyfusebox') self.logger.debug("initialized configurable pyfusebox") super( ConfigurablePyFuseBox, self ).__init__(root, None) def _getattr_for_folder_with_full_access(self): st = zstat() st['st_mode'] = 0777 | stat.S_IFDIR st['st_nlink']=2 st['st_size'] = 4096 st['st_blocks'] = (int) ((st['st_size'] + 4095L) / 4096L); return st; def getattr(self, path, fh=None): self.logger.debug("getattr "+path+"") if path == "/": return self._getattr_for_folder_with_full_access(); if path == self.virtual_file.get_path(): return self.virtual_file.getattr() if self.virtual_file.get_subdir(path): return self._getattr_for_folder_with_full_access() if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super( ConfigurablePyFuseBox, self ).getattr(path, fh) if path == self.DATA_FOLDER_PATH: return self._getattr_for_folder_with_full_access(); raise FuseOSError(ENOENT) def truncate(self, path, length, fh=None): self.logger.debug("truncate %s to %s" % (path, length)) if path == self.virtual_file.get_path(): self.virtual_file.truncate() return 0 if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super( ConfigurablePyFuseBox, self ).truncate(path, length, fh) raise FuseOSError(ENOENT) def rmdir(self, path): self.logger.debug("rmdir %s" % (path)) if path == self.DATA_FOLDER_PATH or path == self.virtual_file.get_dir(): raise FuseOSError(EACCES) if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super( ConfigurablePyFuseBox, self ).rmdir(path) raise FuseOSError(ENOENT) def mkdir(self, path, mode): self.logger.debug("mkdir %s with mode: %s" % (path, str(mode))) if path == self.DATA_FOLDER_PATH: raise FuseOSError(EEXIST) if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super( ConfigurablePyFuseBox, self ).mkdir(path, mode) raise FuseOSError(EACCES) def remove_data_folder_prefix(self, path): path = path[len(self.DATA_FOLDER_PATH):] if not path.startswith("/"): path = "/" return path def statfs(self, path):#add size of vtf self.logger.debug("statfs %s" % (path)) if self.store_initialized: path = self.remove_data_folder_prefix(path) return super( ConfigurablePyFuseBox, self ).statfs(path) def rename(self, old, new): self.logger.debug("rename %s to %s" % (old, new)) """if new == self.virtual_file.get_path(): buf = written_bytes = self.virtual_file.write(buf, offset) if written_bytes >0: # configuration changed self._initialize_store() return written_bytes""" if old == self.DATA_FOLDER_PATH: raise FuseOSError(EACCES) if new == self.DATA_FOLDER_PATH: raise FuseOSError(EACCES) if self.store_initialized and old.startswith(self.DATA_FOLDER_PATH) and new.startswith(self.DATA_FOLDER_PATH): old = self.remove_data_folder_prefix(old) new = self.remove_data_folder_prefix(new) return super( ConfigurablePyFuseBox, self ).rename(old, new) raise FuseOSError(EACCES) def create(self, path, mode): self.logger.debug("create %s with mode %s" % (path, str(mode))) if path == self.DATA_FOLDER_PATH : raise FuseOSError(EACCES) if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super( ConfigurablePyFuseBox, self ).create(path, mode) raise FuseOSError(EACCES) def unlink(self, path): if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) super( ConfigurablePyFuseBox, self ).unlink(path) def read(self, path, size, offset, fh): self.logger.debug("read %s" % path) if path == self.virtual_file.get_path(): return self.virtual_file.read(size, offset) if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super( ConfigurablePyFuseBox, self ).read(path, size, offset, fh) def _initialize_store(self): self.logger.debug("_initialize_store:") conf = self.virtual_file.get_store_config_data() service = conf['name'] self.logger.debug("got service name") cache_time = 0 metadata_cache_time = 0 if 'cache' in conf: cache_time = int(conf['cache']) if 'metadata_cache' in conf: metadata_cache_time = int(conf['metadata_cache']) self.logger.debug("got cache parameter") auth = self.virtual_file.get_service_auth_data() self.logger.debug("got auth data: "+str(auth)) store = self.__get_new_store(service, auth) #catch error? self.logger.debug("initialized store") if cache_time > 0 and metadata_cache_time > 0: store = MetadataCachingStore( CachingStore( MetadataCachingStore( store, metadata_cache_time ), cache_time ), metadata_cache_time ) self.set_cache_expiration_time(cache_time) super( ConfigurablePyFuseBox, self ).start_cyclic_flushing() elif cache_time > 0: store = CachingStore(store, cache_time) self.set_cache_expiration_time(cache_time) super( ConfigurablePyFuseBox, self ).start_cyclic_flushing() elif metadata_cache_time > 0: store = MetadataCachingStore( store, metadata_cache_time ) super( ConfigurablePyFuseBox, self ).start_cyclic_flushing() self.store = store self.logger.debug("initialized service") self.store_initialized = True def __get_new_store(self, service, auth): self.logger.debug("__get_new_store:") if service.lower() == "sugarsync": store = SugarsyncStore(auth) elif service.lower() == "mangafuse": store = MangaStore(auth) else: # default self.logger.debug("get dropbox store") try: store = DropboxStore(auth) except Exception as e: self.logger.debug(str(e)) self.logger.debug("got dropbox store") return store def write(self, path, buf, offset, fh): self.logger.debug("write %s ... starting with %s at %s - fh: %s" % (path, buf[0:10], offset, fh)) if path == self.virtual_file.get_path(): self.logger.debug("writing to virtual file "+path) written_bytes = self.virtual_file.write(buf, offset) self.logger.debug("written bytes:"+str(written_bytes)) if written_bytes >0: # configuration changed self._initialize_store() return written_bytes if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super( ConfigurablePyFuseBox, self ).write(path, buf, offset, fh) return 0 def flush(self, path, fh): self.logger.debug("flush %s - fh: %s" % (path, fh)) if path == self.virtual_file.get_path(): return 0 if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super( ConfigurablePyFuseBox, self ).flush(path, fh) def release(self, path, fh): self.logger.debug("release %s - fh: %s" % (path, fh)) if path == self.virtual_file.get_path(): return 0 if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super( ConfigurablePyFuseBox, self ).release(path, fh) def readdir(self, path, fh): self.logger.debug("readdir "+path+"") directories = [] if path == self.virtual_file.get_dir(): #add virtual file directories.append(self.virtual_file.get_name()) if path == "/":# add virtual folders directories.append(self.virtual_file.get_dir()) directories.append(os.path.basename(self.DATA_FOLDER_PATH)) elif self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) directories += self.store.get_directory_listing(path) #self.logger.debug("readdir -> "+str(directories)+"") file_objects = [".", ".."] for file_object in directories: if file_object != "/": file_object = os.path.basename(file_object.encode('utf8')) file_objects.append( file_object ) return file_objects;
class ConfigurablePyFuseBox(PyFuseBox): '''Offers a virtual configuration file, to configure Cloudfusion at runtime. To better separate the data from the configuration directory, data can be accessed in the top level directory data, and the configuration file can be accessed in the top level directory config. ''' VIRTUAL_CONFIG_FILE = '/config/config' DATA_FOLDER_PATH = "/data" def __init__(self, root): '''''' super( ConfigurablePyFuseBox, self ).__init__(root, None) self.virtual_file = VirtualConfigFile(self.VIRTUAL_CONFIG_FILE, self) self.store_initialized = False self.logger.debug("initialized configurable pyfusebox") # public variable to trigger profiling in modules interactively (i.e. StoreSyncThread) self.do_profiling = False def enable_logging(self): if not os.path.exists(".cloudfusion/logs"): os.makedirs(".cloudfusion/logs") logging.config.fileConfig(os.path.dirname(cloudfusion.__file__)+'/config/logging.conf') db_logging_thread.start() #.handlers = [] logging.disable(logging.NOTSET) def disable_logging(self): logging.disable(logging.CRITICAL) db_logging_thread.stop() def _getattr_for_folder_with_full_access(self): st = zstat() st['st_mode'] = 0777 | stat.S_IFDIR st['st_nlink']=2 st['st_size'] = 4096 st['st_blocks'] = (int) ((st['st_size'] + 4095L) / 4096L) return st def getattr(self, path, fh=None): self.logger.debug("getattr %s", path) if path == "/": return self._getattr_for_folder_with_full_access() if path == self.virtual_file.get_path(): return self.virtual_file.getattr() if self.virtual_file.get_subdir(path): return self._getattr_for_folder_with_full_access() if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH+'/'): #slash prevents getattr on /datata/x path = self.remove_data_folder_prefix(path) return super( ConfigurablePyFuseBox, self ).getattr(path, fh) if path == self.DATA_FOLDER_PATH: return self._getattr_for_folder_with_full_access() raise FuseOSError(ENOENT) def truncate(self, path, length, fh=None): self.logger.debug("truncate %s to %s", path, length) if path == self.virtual_file.get_path(): self.virtual_file.truncate() return 0 if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super( ConfigurablePyFuseBox, self ).truncate(path, length, fh) raise FuseOSError(ENOENT) def rmdir(self, path): self.logger.debug("rmdir %s", path) if path == self.DATA_FOLDER_PATH or path == self.virtual_file.get_dir(): raise FuseOSError(EACCES) if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super( ConfigurablePyFuseBox, self ).rmdir(path) raise FuseOSError(ENOENT) def mkdir(self, path, mode): self.logger.debug("mkdir %s with mode: %s", path, mode) if path == self.DATA_FOLDER_PATH: raise FuseOSError(EEXIST) if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super( ConfigurablePyFuseBox, self ).mkdir(path, mode) raise FuseOSError(EACCES) def remove_data_folder_prefix(self, path): path = path[len(self.DATA_FOLDER_PATH):] if not path.startswith("/"): path = "/" return path def statfs(self, path):#add size of vtf self.logger.debug("statfs %s", path) if self.store_initialized: path = self.remove_data_folder_prefix(path) return super( ConfigurablePyFuseBox, self ).statfs(path) def rename(self, old, new): self.logger.debug("rename %s to %s", old, new) if old == self.virtual_file.get_path() and os.path.basename(new).startswith('.fuse_hidden'): #rename to .fuse_hidden is like a remove (see: hard remove option in fuse manpage for details) print "shutdown" if sys.platform == "darwin": args = ["diskutil", "umount", self.root] elif "freebsd" in sys.platform: args = ["umount", "-l", self.root] else: args = ["fusermount", "-zu", self.root] import subprocess subprocess.Popen(args) sleep(5) # Give CloudFusion some time to unmount. # If it does not work terminate it the hard way. os.kill(os.getpid(), signal.SIGINT) """if new == self.virtual_file.get_path(): buf = written_bytes = self.virtual_file.write(buf, offset) if written_bytes >0: # configuration changed self._initialize_store() return written_bytes""" if old == self.DATA_FOLDER_PATH: raise FuseOSError(EACCES) if new == self.DATA_FOLDER_PATH: raise FuseOSError(EACCES) if self.store_initialized and old.startswith(self.DATA_FOLDER_PATH) and new.startswith(self.DATA_FOLDER_PATH): old = self.remove_data_folder_prefix(old) new = self.remove_data_folder_prefix(new) return super( ConfigurablePyFuseBox, self ).rename(old, new) raise FuseOSError(EACCES) def create(self, path, mode): self.logger.debug("create %s with mode %s", path, mode) if path == self.DATA_FOLDER_PATH : raise FuseOSError(EACCES) if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super( ConfigurablePyFuseBox, self ).create(path, mode) raise FuseOSError(EACCES) def unlink(self, path): if path == self.virtual_file.get_path(): if sys.platform == "darwin": args = ["diskutil", "umount", self.root] elif "freebsd" in sys.platform: args = ["umount", "-l", self.root] else: args = ["fusermount", "-zu", self.root] import subprocess subprocess.Popen(args) sleep(5) # Give CloudFusion some time to unmount. # If it does not work terminate it the hard way. os.kill(os.getpid(), signal.SIGINT) if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) super( ConfigurablePyFuseBox, self ).unlink(path) def read(self, path, size, offset, fh): #self.logger.debug("read %s", path) if path == self.virtual_file.get_path(): return self.virtual_file.read(size, offset) if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super( ConfigurablePyFuseBox, self ).read(path, size, offset, fh) def write(self, path, buf, offset, fh): #self.logger.debug("write %s ... starting with %s at %s - fh: %s", path, buf[0:10], offset, fh) if path == self.virtual_file.get_path(): self.logger.debug("writing to virtual file %s", path) written_bytes = self.virtual_file.write(buf, offset) return written_bytes if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super( ConfigurablePyFuseBox, self ).write(path, buf, offset, fh) return 0 def flush(self, path, fh): self.logger.debug("flush %s - fh: %s", path, fh) if path == self.virtual_file.get_path(): return 0 if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super( ConfigurablePyFuseBox, self ).flush(path, fh) def release(self, path, fh): self.logger.debug("release %s - fh: %s", path, fh) if path == self.virtual_file.get_path(): return 0 if self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) return super( ConfigurablePyFuseBox, self ).release(path, fh) def readdir(self, path, fh): self.logger.debug("readdir %s", path) directories = [] if path == self.virtual_file.get_dir(): #add virtual file directories.append(self.virtual_file.get_name()) if path == "/":# add virtual folders directories.append(self.virtual_file.get_dir()) directories.append(os.path.basename(self.DATA_FOLDER_PATH)) elif self.store_initialized and path.startswith(self.DATA_FOLDER_PATH): path = self.remove_data_folder_prefix(path) directories += self.store.get_directory_listing(path) #self.logger.debug("readdir -> "+str(directories)+"") file_objects = [".", ".."] for file_object in directories: if file_object != "/": file_object = os.path.basename(file_object.encode('utf8')) file_objects.append( file_object ) return file_objects