Deepak N
Deepak N

Reputation: 1639

pysftp.Connection.walktree() fails if any directory don't have read permission

I am using pysftp connection using walktree() method to list all files as below

with pysftp.Connection(domain, username=USER,
                       password=PWD, port=port,
                       cnopts=cnopts) as sftp:

    # call back method to list the files for the directory found in walktree
    def dir_found_list_files(path):
        if path:
            files = sftp.listdir_attr(path)
            for file in files:
                if 'r' in file.longname[:4]:
                    filelist.append(path+'/'+file.filename)

    # call back method when file found in walktree
    def file_found(path):
        pass

    # call back method when unknown found in walktree
    def unknown_file(path):
        pass

    # sftp walk tree to list files
    sftp.walktree("/", file_found, dir_found_list_files, unknown_file, recurse=True)

This part works fine. But when any of the folder does not have the permission to read, the walktree method raises the permission exception. How can I ignore the the access denied folder and continue with walktree for accessible folders?

Upvotes: 1

Views: 557

Answers (1)

Martin Prikryl
Martin Prikryl

Reputation: 202494

You cannot. The Connection.walktree does not allow such customization.

But the method is quite trivial, check its source code. Just copy the code over and customize it anyway you need. Something like this (untested):

def robust_walktree(sftp, remotepath, fcallback, dcallback, ucallback, recurse=True)
    try:
        entries = sftp.listdir(remotepath)
    except IOError as e:
        if e.errno != errno.EACCES:
            raise
        else
            entries = []

    for entry in entries:
        pathname = posixpath.join(remotepath, entry)
        mode = sftp.stat(pathname).st_mode
        if S_ISDIR(mode):
            # It's a directory, call the dcallback function
            dcallback(pathname)
            if recurse:
                # now, recurse into it
                robust_walktree(sftp, pathname, fcallback, dcallback, ucallback)
        elif S_ISREG(mode):
            # It's a file, call the fcallback function
            fcallback(pathname)
        else:
            # Unknown file type
            ucallback(pathname)

Upvotes: 1

Related Questions