Can I create a filesystem object of a specific directory?

452 views Asked by At

Need to create this type of object (from kivy.properties & Kivy filechooser)

ObjectProperty(FileSystemLocal(), baseclass=FileSystemAbstract)

1

There are 1 answers

6
John Anderson On

The FileSystemLocal class is a simple interface to some os and os.path methods. For example, the listdir() method of FileSystemLocal is simply a call to os.listdir(). So it is not specific to any directory, it is just specific to the local os and os.path. So, technically, the answer is no.

Perhaps you could define your own FileSystemLocal subclass that meets your requirements.

Here is an example of an extension of FileSystemLocal that uses a specific directory:

from os import listdir
from os.path import (basename, join, getsize, isdir)

from sys import platform as core_platform

from kivy import Logger
from kivy.uix.filechooser import FileSystemAbstract, _have_win32file

platform = core_platform

_have_win32file = False
if platform == 'win':
    # Import that module here as it's not available on non-windows machines.
    try:
        from win32file import FILE_ATTRIBUTE_HIDDEN, GetFileAttributesExW, \
                              error
        _have_win32file = True
    except ImportError:
        Logger.error('filechooser: win32file module is missing')
        Logger.error('filechooser: we cant check if a file is hidden or not')


class FileSystemLocalDir(FileSystemAbstract):
    def __init__(self, **kwargs):
        self.dir = kwargs.pop('dir', None)
        super(FileSystemLocalDir, self).__init__()

    def listdir(self, fn):
        if self.dir is not None:
            fn = join(self.dir, fn)
        print('listdir for', fn)
        return listdir(fn)

    def getsize(self, fn):
        if self.dir is not None:
            fn = join(self.dir, fn)
        return getsize(fn)

    def is_hidden(self, fn):
        if self.dir is not None:
            fn = join(self.dir, fn)
        if platform == 'win':
            if not _have_win32file:
                return False
            try:
                return GetFileAttributesExW(fn)[0] & FILE_ATTRIBUTE_HIDDEN
            except error:
                # This error can occurred when a file is already accessed by
                # someone else. So don't return to True, because we have lot
                # of chances to not being able to do anything with it.
                Logger.exception('unable to access to <%s>' % fn)
                return True

        return basename(fn).startswith('.')

    def is_dir(self, fn):
        if self.dir is not None:
            fn = join(self.dir, fn)
        return isdir(fn)

This can be used as:

fsld = FileSystemLocalDir(dir='/home')
print('dir:', fsld.dir)
print('listdir .:', fsld.listdir('.'))
print('listdir freddy:', fsld.listdir('freddy'))  # lists home directory of user `freddy`
print('listdir /usr:', fsld.listdir('/usr')) # this will list /usr regardless of the setting for self.dir

Note:

  • The FileSystemLocalDir is based heavily on FileSystemLocal.
  • The dir= in the constructor sets the default directory that is consulted for all the methods of FileSystemLocalDir.
  • If the dir= argument is not provided, the FileSystemLocalDir is equivalent to FileSystemLocal.
  • If an argument to any method of FileSystemLocalDir begins with a /, it is treated as an absolute path and the provided default directory is ignored (this is an effect of the use of os.join).