def __construct_remote_paths(self, source, root_dest, remote_directories, local_remote_files): """Computes the directories and files that are to uploaded to remote system. Arguments: source (str) - absolute path to the local source directory root_dest (str) - absolute path to the remote destination directory remote_directories (list) - list reference where the directories which has to created will be added local_remote_files (list) - list reference where a tuples of (localfile_path, remotefile_path) will be added root_dest_exists (boolean) - defaults to False; Set to True if dest exists at remote side Returns: The return values are append to the reference variables i.e remote_directories and local_remote_files list """ if local_isfile(source): root_dest = joinpath(root_dest, local_basename(source)) local_remote_files.append((source, root_dest)) return parent_dest_exists = root_dest_exists = False parent_path = root_dest if self.sftp.isdir(root_dest): parent_dest_exists = root_dest_exists = True for base_dir, _, files in local_walk(source): dest_dir = local_normpath(joinpath(root_dest, base_dir.replace(source, '').strip(pathsep))) if root_dest_exists: new_parent_path = local_dirname(base_dir) if new_parent_path == parent_path and not parent_dest_exists: remote_directories.append(dest_dir) else: parent_path = new_parent_path if not self.sftp.exists(dest_dir): parent_dest_exists = False remote_directories.append(dest_dir) elif not self.sftp.isdir(dest_dir): msg = ''.join(["Copy aborted. Mismatch in file type ", "Local: '%s' Remote: '%s'" % (base_dir, dest_dir)]) raise RemoteDispatcherException(msg) else: parent_dest_exists = True else: remote_directories.append(local_normpath(dest_dir)) local_remote_files.extend(\ [(joinpath(base_dir, fname), \ joinpath(dest_dir, fname)) \ for fname in files])
def __get_paths_source_pattern(self, source, dest): """Costructs the the remote directories and files to be created Arguments: source - local source pattern dest - remote destionation path Returns: Tuple ([dir1, dir2, ...], [(local_file_path1, remote_file_path1), (local_file_path1, remote_file_path2), ...]) """ remote_directories = deque() local_remote_files = deque() root_dest = dest # Get pattern matching files and directories source_list = glob.glob(source) if not source_list: raise RemoteDispatcherException("File or Directory not found: %s" % (source)) if not self.sftp.isdir(root_dest): remote_directories.append(root_dest) for lfile in source_list: # IF lfile is a directory then concatenated the dir-name with # remote path. if local_isdir(lfile): dest = joinpath(root_dest, local_basename(lfile)) else: dest = root_dest self.__construct_remote_paths(lfile, dest, remote_directories, local_remote_files) return (remote_directories, local_remote_files)
def __get_paths_source_dir(self, source, dest): """Costructs the the remote directories and files to be created Arguments: source - local source directory path dest - remote destionation path Returns: Tuple ([dir1, dir2, ...], [(local_file_path1, remote_file_path1), (local_file_path1, remote_file_path2), ...]) """ remote_directories = deque() local_remote_files = deque() if self.sftp.isdir(dest): dest = joinpath(dest, local_basename(source)) self.__construct_remote_paths(source, dest, remote_directories, local_remote_files) return (remote_directories, local_remote_files)
def scp(self, source, dest, recursive=False): """Copies a file[s] or directories between the local and remote host Arguments: source (str) - absolute path to the source file or directory or a pattern dest (str) - remote absolute path recursive (boolean) - for copying recursively; should be enabled in case of directory or more than 2 files i.e pattern matched to be copied Actions: * Get list of directories and files need to uploaded to remote system * Create remote directory skeleton * Upload the files to respective directories Returns: Exception if errors encountered """ source = local_normpath(source) dest = local_normpath(dest) if local_isdir(source) or len(glob.glob(source)) > 1: if not recursive: # For copying more than one file recursive flag should be # enabled. msg = "Please enable recursive argument to copy recursively" LOG.error(msg) raise RemoteDispatcherException(msg) # Establish the secure connection. self.connect() if local_isfile(source): (rdirs, lrfiles) = self.__get_paths_source_file(source, dest) elif local_isdir(source): (rdirs, lrfiles) = self.__get_paths_source_dir(source, dest) else: # else local_ispattern (rdirs, lrfiles) = self.__get_paths_source_pattern(source, dest) # Create directory skeleton for rdir in rdirs: try: LOG.debug(rdir) self.sftp.mkdir(rdir) except IOError: msg = "Couldn't create dest directory: '%s'" % (rdir) LOG.error(msg) raise RemoteDispatcherException(msg) # Upload the files for lfile, rfile in lrfiles: try: LOG.info("%s [%0.3f KB]" % \ (local_basename(lfile), local_getsize(lfile)/float(1024))) self.sftp.put(lfile, rfile) except IOError: msg = "Couldn't copy from local: '%s' to remote: '%s'" \ % (lfile, rfile) LOG.error(msg) raise RemoteDispatcherException(msg)