Example #1
0
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)
Example #3
0
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.