PBXActBackup/SSH_SCP_Copy.py

101 lines
3.2 KiB
Python

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()