def remove_dir_remote(sftp: pysftp.Connection, remotepath: str):
    try:
        sftp.rmdir(remotepath)
        return True

    except OSError as e:
        if e.strerror is None:
            print(ERROR_PREFACE, "could not remove directory " + remotepath)
        else:
            print(ERROR_PREFACE, e.strerror)
        return False
Exemplo n.º 2
0
def put_r(sftp: pysftp.Connection, foldername: str):
    """ There is a lot wrong with the pysftp imlementation of put_r. It:
    1. does not check if a folder exists already.
    2. does not copy the directory on the local machine, only its contents.
    3. changes into a directory (which doesnt exist) using os.chdir() before copying contents.
       This causes an exception to be thrown that the folder is not found
       (because there is no directory)

    As a result, our code has to:
    1. manually check if a folder exists already.
    2. create a remote directory of the local folder name we want to copy if it does not exist.
    3. manually step into that remote directory (so no error is thrown).
    4. then call pysftp's put_r function to copy the local contents.
    5. finally, step out of the remote directory.

    ***Notes***:
        * if there is no such file on the local machine, we must remove the folder we created in the exception block.
        * put_r works, while put_d does not work. put_d has separate, but similar issues.
    """

    try:
        # Tests if the file is a file, not a directory. This avoids NotADirectory error.
        if Path(foldername).is_file():
            return put_f.put(sftp, foldername)

        # 1) Change into the remote directory, if it exists.
        try:
            sftp.chdir(foldername)
        except:
            # 2) make remote directory, if it does not exist.
            sftp.makedirs(foldername)
            # 3) change into current remote directory
            sftp.chdir(foldername)
        # 4) copy contents of local directory into remote directory
        sftp.put_r(foldername, ".", preserve_mtime=False)

        # 5) change out of the remote directory.
        sftp.chdir("..")
    except FileNotFoundError as error:
        sftp.chdir("..")
        # remove folder created on remote if there is no such folder on local machine.
        sftp.rmdir(foldername)
        print(ERROR_MESSAGE)
        return False
    except PermissionError:
        print(PERMISSION_ERROR)
        return False
    except OSError as e:
        print("Error:", e.strerror)
        return False
    # if everything went fine, then the folder's contents have been copied. Return True.
    return True
Exemplo n.º 3
0
class SFTP:
    def __init__(self, sftp_server_config):
        self.server = sftp_server_config['host_address']
        self.username = sftp_server_config['user_name']
        self.private_key = sftp_server_config['key_path']
        self.sftp_folder = sftp_server_config['sftp_folder']
        self.connection_opts = CnOpts()
        self.connection_opts.hostkeys = None
        self.__connection: Connection = None

    def connect(self):
        if not self.__connection:
            self.__connection = Connection(self.server,
                                           self.username,
                                           self.private_key,
                                           cnopts=self.connection_opts)
        return self

    def put(self, file, remote_path):
        return self.__connection.put(file, remote_path)

    def remove(self, path):
        return self.__connection.remove(path)

    def rmdir(self, path):
        return self.__connection.rmdir(path)

    def listdir(self, path):
        return self.__connection.listdir(path)

    def is_dir(self, path):
        return self.__connection.isdir(path)

    def is_file(self, path):
        return self.__connection.isfile(path)

    def close(self):
        self.__connection.close()
        self.__connection = None