import paramiko from scp import SCPClient import os # === CONFIGURATION === ssh_host = '192.168.130.9' ssh_port = 22 ssh_user = 'root' ssh_password = '' # Or use SSH key (see notes below) remote_folder = '/temp/bc/' local_folder = r'C:\Backup\Telefonsentral' # Use raw string for Windows paths # === SETUP LOCAL FOLDER === os.makedirs(local_folder, exist_ok=True) def create_ssh_client(host, port, user, password): client = paramiko.SSHClient() client.load_system_host_keys() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(host, port, username=user, password=password) return client def copy_folder(ssh_client, remote_path, local_path): print(f"Downloading files from {remote_path} to {local_path}...") sftp = ssh_client.open_sftp() # Get all remote files stdin, stdout, _ = ssh_client.exec_command(f"find {remote_path} -type f") remote_files = [line.strip() for line in stdout.readlines()] for remote_file in remote_files: relative_path = os.path.relpath(remote_file, remote_path).replace('/', os.sep) local_file_path = os.path.join(local_path, relative_path) local_dir = os.path.dirname(local_file_path) os.makedirs(local_dir, exist_ok=True) try: print(f"Downloading {remote_file} → {local_file_path}") sftp.get(remote_file, local_file_path) except Exception as e: print(f"Failed to download {remote_file}: {e}") sftp.close() def list_remote_files(ssh, path): # Returns list of full file paths (e.g. /home/user/data/file.txt) stdin, stdout, stderr = ssh.exec_command(f"find {path} -type f") files = [line.strip() for line in stdout.readlines()] return files def list_local_files(path): # Returns full local file paths local_files = [] for dirpath, _, filenames in os.walk(path): for f in filenames: full_path = os.path.normpath(os.path.join(dirpath, f)) local_files.append(full_path) return local_files def sync_delete_unmatched(remote_files, local_base_path, remote_base_path): print("Checking for stale local files to delete...") # Compute relative paths from remote files remote_relative = [ os.path.normpath(f.replace(remote_base_path, '').lstrip('/').replace('/', os.sep)) for f in remote_files ] expected_local = {os.path.normpath(os.path.join(local_base_path, rel)) for rel in remote_relative} local_files = set(list_local_files(local_base_path)) to_delete = local_files - expected_local for f in to_delete: try: print(f"Deleting stale file: {f}") os.remove(f) except Exception as e: print(f"Failed to delete {f}: {e}") def main(): try: ssh = create_ssh_client(ssh_host, ssh_port, ssh_user, ssh_password) # 1. List remote files remote_files = list_remote_files(ssh, remote_folder) # 2. Download all files from remote copy_folder(ssh, remote_folder, local_folder) # 3. Delete local files not on remote sync_delete_unmatched(remote_files, local_folder, remote_folder) ssh.close() except Exception as e: print(f"Error: {e}") if __name__ == "__main__": main()