Exemplo n.º 1
0
 def initialize(self):
     self.api = putioapi.Api(self.key, self.secret)
     if not self.api.access_token:
         raise AuthenticationFailed
     item = self._genitem(type='folder', name='.', id=0, parent_id=0)
     self.root_fs = CacheFS(item.id, Dir(item.name).stat, item)
     self.cache_fd = CacheManager((self.key, self.secret))
Exemplo n.º 2
0
class PutIOFS(fuse.Fuse):
    def __init__(self, *args, **kwargs):
        super(PutIOFS, self).__init__(*args, **kwargs)
        self.api = None
        self.key = None
        self.secret = None
        self.root_fs = None
        self.cache_fd = None

    @staticmethod
    def _dirname(p):
        """
        Roughly equivalent of os.path.dirname with specific separator.
        """
        i = p.rfind(PATH_SEP) + 1
        head = p[:i]
        if head and head != PATH_SEP*len(head):
            head = head.rstrip(PATH_SEP)
        return head

    def _geturl(self, path):
        return self.find_inode(path).item.download_url

    def _genitem(self, **config):
        config.setdefault('id', -1)
        config.setdefault('parent_id', -1)
        return putioapi.Item(self.api, config)

    def initialize(self):
        self.api = putioapi.Api(self.key, self.secret)
        if not self.api.access_token:
            raise AuthenticationFailed
        item = self._genitem(type='folder', name='.', id=0, parent_id=0)
        self.root_fs = CacheFS(item.id, Dir(item.name).stat, item)
        self.cache_fd = CacheManager((self.key, self.secret))

    def get_inode(self, path, item):
        try:
            return self.find_inode(path)
        except KeyError:
            return self.register_inode(path, item)

    def find_inode(self, path):
        dir_node = self.root_fs
        for name in path.split(PATH_SEP):
            if name:
                dir_node = dir_node.find_inode(name)
        return dir_node

    def register_inode(self, path, item):
        dirname = self._dirname(path)
        return self.find_inode(dirname).register_inode(item)

    def getattr(self, path):
        """
        Given a path string, returns the Dir or File object corresponding to
        the path, or None.
        """
        if not path.startswith(PATH_SEP):
            return None
        first_try = True
        while True:
            try:
                return self.find_inode(path).stat
            except KeyError:
                if first_try:
                    list(self.readdir(self._dirname(path)))
                    first_try = False
                else:
                    break

    def readdir(self, path, offset=0, dh=None):
        """
        Generator function. Produces a directory listing.
        Yields individual fuse.Direntry objects, one per file in the
        directory. Should always yield at least "." and "..".
        Should yield nothing if the file is not a directory or does not exist.
        (Does not need to raise an error).

        offset: I don't know what this does, but I think it allows the OS to
        request starting the listing partway through (which I clearly don't
        yet support). Seems to always be 0 anyway.
        """
        yield fuse.Direntry('.')
        yield fuse.Direntry('..')
        inode = self.find_inode(path)
        items = {_.item for _ in inode.get_entries()}
        if not items:
            while True:
                try:
                    newitems = set(self.api.get_items(20, len(items), inode.id))
                except putioapi.PutioError:
                    pass
                if items & newitems:
                    break
                items |= newitems
                if len(items) % 20:
                    break
        for it in items:
            name = it.name.encode('utf-8')
            it_path = PATH_SEP.join([path, name])
            inode = self.get_inode(it_path, it)
            yield fuse.Direntry(name)

    def read(self, path, size, offset):
        return self.cache_fd.read(self._geturl(path), size, offset)

    def write(self, path, buf, offset):
        return -errno.ENOSYS

    def release(self, path, flags):
        self.cache_fd.remove(self._geturl(path))
        return 0

    def open(self, path, flags):
        self.cache_fd.append(self._geturl(path))
        return 0

    def truncate(self, path, size):
        return -errno.ENOSYS

    def utime(self, path, times):
        return -errno.ENOSYS

    def mkdir(self, path, mode):
        return -errno.ENOSYS

    def rmdir(self, path):
        return -errno.ENOSYS

    def rename(self, pathfrom, pathto):
        return -errno.ENOSYS

    def fsync(self, path, isfsyncfile):
        return -errno.ENOSYS