def exists(sftp: SFTPClient, remote_path): try: sftp.lstat(remote_path) return True except FileNotFoundError as e: return False except Exception as e: raise e
def _download_file( self, indentationlevel: int, sftp: paramiko.SFTPClient, remote_root: Path, localfile: Path, remote_filenode: Path, entry: BackupEntry ): options = entry.get_options() has_options = is_sequence_with_any_elements(options) is_simulation = False if has_options is True: is_simulation = options["simulate"] if "simulate" in options and options["simulate"] is True else False indentation = repeat("\t", indentationlevel+1) if not is_simulation: stat_remote = sftp.lstat(str(remote_filenode)) do_transfer = True self.info("{}Processing file: '{}'".format(indentation, remote_filenode)) if has_options and not is_simulation: do_transfer = self._check_file_with_options( options, remote_root, localfile, remote_filenode, stat_remote, indentation ) if do_transfer is not None: self.info("{}Excluding '{}' due to json-file-option {}".format( indentation, remote_filenode, do_transfer )) else: if is_simulation: self.info("{}Simulating download of file '{}'".format(indentation, remote_filenode)) else: self.info("{}Downloading file (Total: {})".format( indentation, bytes_to_unit(stat_remote.st_size, 1, True, False)) ) self._current_progress_divider = get_filesize_progress_divider(stat_remote.st_size) sftp.get(str(remote_filenode), str(localfile)) if self._copystats: self.info("{}Copying file modification dates".format(indentation)) utime(str(localfile), (stat_remote.st_atime, stat_remote.st_mtime))
def _process_directory( self, level: int, sftp: paramiko.SFTPClient, remote_root: Path, remote_path: Path, local_targetdir: Path, entry: BackupEntry ): isroot = False options = entry.get_options() has_options = not is_empty_dict(options) path_rootindex = None recurse = False if has_options: if "recurse" in options and not self._check_option_ignored("recures"): recurse = options["recurse"] if "path_rootindex" in options and not self._check_option_ignored("path_rootindex"): path_rootindex = options["path_rootindex"] if len(remote_path.parents) == 0: isroot = True if isroot: localdir = local_targetdir else: if path_rootindex is not None and is_integer(path_rootindex): f = path_from_partindex(remote_path, path_rootindex) localdir = local_targetdir.joinpath(f) else: localdir = local_targetdir.joinpath(str(remote_path)[1:]) remote_filenode = None tabs2 = repeat("\t", level + 1) do_transfer = self._check_folder_with_options(remote_root, remote_path, options) if do_transfer is not None: self.info("{}Excluding '{}' due to json-folder-option {}".format( tabs2, remote_path, do_transfer )) return if not localdir.exists(): self.info("{}Creating parent folders '{}'".format(tabs2, localdir)) makedirs(str(localdir)) try: filelist = sftp.listdir(str(remote_path)) if len(filelist) > 0: for filenode in filelist: remote_filenode = remote_path.joinpath(filenode) remote_stat = sftp.lstat(str(remote_filenode)) if stat.S_ISDIR(remote_stat.st_mode): if recurse is True: self.info("\n{}Recursing into sub-directory '{}'".format( tabs2, remote_filenode )) self._process_directory( level + 1, sftp, remote_path, remote_filenode, local_targetdir, entry ) else: localfile = localdir.joinpath(filenode) self._download_file(level, sftp, remote_root, localfile, remote_filenode, entry) except Exception as e: if isinstance(e, PermissionError): self.info("{}PermissionError while listing contents of {}\n".format( tabs2, remote_filenode if remote_filenode is not None else remote_path )) elif isinstance(e, JobException): raise e else: raise JobException(e, 1)