class LocalBoxMemoryFS(): ''' # # Class that handles in memory file system for localbox # ''' def __init__(self): self.memory = MemoryFS() ## WINDOWS if sys.platform == 'win32': from fs.expose import dokan letter = random.choice(string.letters) + ":\\" while os.path.exists(letter): letter = random.choice(string.letters) + ":\\" self.mount_directory = letter if not os.path.exists(letter): dokan.mount(self.memory, letter) ## LINUX else: self.mount_directory = os.path.join(os.path.expanduser('~')) +'/mtdecoded/' def createfile(self, path, content, wipe=True): self.memory.createfile(path, wipe=wipe) with self.memory.open(path, "wb") as f: f.write(content) if not os.path.exists(self.mount_directory): os.makedirs(self.mount_directory) mount(self.memory, self.mount_directory) # else: # fuse.unmount(self.mount_directory) # mount(self.memory, self.mount_directory) # If system is mounted with video it can't be unmounted, find a wait o update mounted resources TODO return self.mount_directory + path def destroy(self): time.sleep(3) try: fuse.unmount(self.mount_directory) os.removedirs(self.mount_directory) except OSError: #Mounted in use, try again self.destroy()
class SlfFS(FS): """ Implements a read-only file system on top of a SLF-file """ _meta = { 'thread_safe': False, 'virtual': False, 'read_only': True, 'unicode_paths': False, 'case_insensitive_paths': False, 'network': False, 'atomic.setcontents': False } def __init__(self, slf_filename): super(SlfFS, self).__init__() if isinstance(slf_filename, str): slf_filename = os.path.expanduser(os.path.expandvars(slf_filename)) slf_filename = os.path.normpath(os.path.abspath(slf_filename)) try: self.file_name = slf_filename self.file = open(slf_filename, 'rb') except FileNotFoundError as e: raise CreateFailedError( 'Slf file not found ({0})'.format(slf_filename), details=e ) else: self.file_name = 'file-like' self.file = slf_filename self.header = SlfHeader.from_bytes(self.file.read(SlfHeader.get_size())) self.entries = list(map(self._read_entry, range(self.header['number_of_entries']))) self.library_name = self.header['library_name'] self.library_path = self.header['library_path'] self.sort = self.header['sort'] self.version = self.header['version'] self._path_fs = MemoryFS() for e in self.entries: path = _get_normalized_filename(e['file_name']).split('/') directory = '/'.join(path[:-1]) if len(path) > 2 else '/' if self._path_fs.isfile(directory): # Sometimes there exists a file that has the same name as a directory # Solution: Rename it with a _DIRECTORY_CONFLICT suffix self._path_fs.move(directory, directory + DIRECTORY_CONFLICT_SUFFIX) if self._path_fs.isdir('/'.join(path)): self._path_fs.createfile('/'.join(path) + DIRECTORY_CONFLICT_SUFFIX) else: self._path_fs.makedir(directory, recursive=True, allow_recreate=True) self._path_fs.createfile('/'.join(path)) def _read_entry(self, index): entry_size = SlfEntry.get_size() self.file.seek(-entry_size * (self.header['number_of_entries'] - index), os.SEEK_END) return SlfEntry.from_bytes(self.file.read(entry_size)) def __str__(self): return '<SlfFS: {0}>'.format(self['library_name']) def isfile(self, path): return self._path_fs.isfile(path) def isdir(self, path): return self._path_fs.isdir(path) def listdir(self, path="/", wildcard=None, full=False, absolute=False, dirs_only=False, files_only=False): return self._path_fs.listdir(path, wildcard, full, absolute, dirs_only, files_only) def open(self, path, mode='r', buffering=-1, encoding='ascii', errors=None, newline=None, line_buffering=False, **kwargs): if mode != 'r' and mode != 'rb': raise UnsupportedError(WRITING_NOT_SUPPORTED_ERROR.format('open')) if not self.exists(path): raise ResourceNotFoundError(path) if self.isdir(path): raise ResourceInvalidError(path) slf_entry = self._get_slf_entry_for_path(path) self.file.seek(slf_entry['offset'], os.SEEK_SET) if mode == 'rb': return io.BytesIO(self.file.read(slf_entry['length'])) return io.StringIO(self.file.read(slf_entry['length']).decode(encoding)) def getinfo(self, path): if not self.exists(path): raise ResourceNotFoundError(path) if self.isdir(path): return { 'size': 0 } slf_entry = self._get_slf_entry_for_path(path) return { 'size': slf_entry['length'], 'modified_time': slf_entry['time'] } def makedir(self, path, recursive=False, allow_recreate=False): raise UnsupportedError(WRITING_NOT_SUPPORTED_ERROR.format('makedir')) def remove(self, path): raise UnsupportedError(WRITING_NOT_SUPPORTED_ERROR.format('remove')) def removedir(self, path, recursive=False, force=False): raise UnsupportedError(WRITING_NOT_SUPPORTED_ERROR.format('removedir')) def rename(self, src, dst): raise UnsupportedError(WRITING_NOT_SUPPORTED_ERROR.format('rename')) def _get_slf_entry_for_path(self, path): if path.endswith(DIRECTORY_CONFLICT_SUFFIX): path = path[:-len(DIRECTORY_CONFLICT_SUFFIX)] return next(e for e in self.entries if _get_normalized_filename(e['file_name']) == path)
from fs.memoryfs import MemoryFS from fs.expose import fuse fs = MemoryFS() # create an in memory file system fs.createfile('filename.txt') # creating an empty file fs.setcontents('filename.txt', 'contents of file') # putting content into the file. from fs.osfs import OSFS home_fs = OSFS('/') # home_fs.makedir( '/home/dave/scratch/ramdrive', allow_recreate=True ) # have to make a directory for us to mount our memory file system on. mp = fuse.mount( fs, '/home/dave/scratch/ramdrive' ) # exposes fs to everything else on machine. (ie: other system calls can see these files) mp.path # in case you need the path to the files created. mp.unmount() # files are no longer being exposed via fuse home_fs.removedir('/home/dave/scratch/ramdrive/' ) #remove the real file system directory when done. fs.remove('filename.txt') home_fs.close() fs.close() # creating a ramdrive like this wont work for my desired task, as other external applications cannot write to the directory. They only have read access.