Assistant: 
User: User: 你好
Assistant: 你好！有什么我可以帮助你的吗？
User: import os
import paramiko
import hashlib
import stat
import fnmatch

# 读取忽视列表
def load_ignore_list(ignore_file_path):
    ignore_patterns = []
    if os.path.exists(ignore_file_path):
        with open(ignore_file_path, 'r', encoding='utf-8') as f:
            for line in f:
                line = line.strip()
                if line and not line.startswith('#'):  # 跳过空行和注释行
                    ignore_patterns.append(line)
    return ignore_patterns

# 判断文件或文件夹是否在忽视列表中
def should_ignore(file_path, ignore_patterns, base_folder):
    relative_path = os.path.relpath(file_path, base_folder).replace("\\", "/")
    for pattern in ignore_patterns:
        if fnmatch.fnmatch(relative_path, pattern):
            return True
    return False

# 计算文件的哈希值
def calculate_file_hash(file_path, hash_algorithm='md5'):
    hash_func = hashlib.new(hash_algorithm)
    with open(file_path, 'rb') as f:
        while chunk := f.read(4096):
            hash_func.update(chunk)
    return hash_func.hexdigest()

# 获取远程文件的哈希值
def calculate_remote_file_hash(sftp, remote_file_path, hash_algorithm='md5'):
    hash_func = hashlib.new(hash_algorithm)
    with sftp.file(remote_file_path, 'rb') as remote_file:
        while chunk := remote_file.read(4096):
            hash_func.update(chunk)
    return hash_func.hexdigest()

# 创建SSH客户端
def create_ssh_client(server, port, user, password):
    ssh = paramiko.SSHClient()
    ssh.load_system_host_keys()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(server, port, user, password)
    return ssh

# 创建远程目录（如果不存在）
def create_remote_directory(sftp, remote_folder):
    try:
        sftp.chdir(remote_folder)  # 尝试切换到目录，看看是否存在
    except IOError:
        # 如果目录不存在，则递归创建它
        parent_dir = os.path.dirname(remote_folder)
        if parent_dir != remote_folder:
            create_remote_directory(sftp, parent_dir)
        sftp.mkdir(remote_folder)
        sftp.chdir(remote_folder)

# 上传文件，如果文件不同或不存在
def upload_file_if_needed(sftp, local_file_path, remote_file_path):
    try:
        # 计算远程文件哈希值
        remote_hash = calculate_remote_file_hash(sftp, remote_file_path)
    except IOError:
        # 如果远程文件不存在，则上传
        remote_hash = None

    # 计算本地文件哈希值
    local_hash = calculate_file_hash(local_file_path)

    if remote_hash != local_hash:
        sftp.put(local_file_path, remote_file_path)
        print(f"Uploaded {local_file_path} to {remote_file_path}")
    else:
        print(f"{local_file_path} is up to date, no upload needed.")

# 获取远程文件夹中的文件和目录列表
def get_remote_file_list(sftp, remote_folder):
    file_list = []
    try:
        for entry in sftp.listdir_attr(remote_folder):
            file_path = os.path.join(remote_folder, entry.filename).replace("\\", "/")
            file_list.append((file_path, stat.S_ISDIR(entry.st_mode)))  # 保存文件和目录的状态
            if stat.S_ISDIR(entry.st_mode):
                file_list.extend(get_remote_file_list(sftp, file_path))  # 递归处理子文件夹
    except IOError:
        pass  # 远程文件夹不存在时返回空列表
    return file_list

# 递归删除远程文件或目录
def delete_remote_file_or_directory(sftp, remote_path):
    try:
        # 尝试删除文件
        sftp.remove(remote_path)
        print(f"Deleted remote file {remote_path}")
    except IOError:
        # 如果是目录，则递归删除目录及其内容
        try:
            for entry in sftp.listdir_attr(remote_path):
                entry_path = os.path.join(remote_path, entry.filename).replace("\\", "/")
                delete_remote_file_or_directory(sftp, entry_path)  # 递归删除
            sftp.rmdir(remote_path)  # 删除空目录
            print(f"Deleted remote directory {remote_path}")
        except IOError as e:
            print(f"Failed to delete {remote_path}: {str(e)}")

# 同步本地文件夹到远程文件夹，支持增量同步和删除操作
def sync_folder(local_folder, remote_folder, sftp, ignore_patterns):
    # 本地文件夹中的所有文件和文件夹（相对于 local_folder 的相对路径）
    local_files = []
    local_dirs = []

    for root, dirs, files in os.walk(local_folder):
        # 处理文件
        for name in files:
            local_file_path = os.path.join(root, name)
            # 忽视列表检查
            if should_ignore(local_file_path, ignore_patterns, local_folder):
                print(f"Ignored {local_file_path}")
                continue

            relative_path = os.path.relpath(local_file_path, local_folder).replace("\\", "/")
            local_files.append(relative_path)

            # 计算远程文件路径
            remote_file_path = os.path.join(remote_folder, relative_path).replace("\\", "/")

            # 创建远程目录（确保文件所在的目录存在）
            remote_dir = os.path.dirname(remote_file_path)
            create_remote_directory(sftp, remote_dir)

            # 上传文件（如果文件内容不同）
            upload_file_if_needed(sftp, local_file_path, remote_file_path)

        # 处理文件夹
        for name in dirs:
            local_dir_path = os.path.join(root, name)
            relative_dir_path = os.path.relpath(local_dir_path, local_folder).replace("\\", "/")

            # 检查是否需要忽略该文件夹
            if should_ignore(local_dir_path, ignore_patterns, local_folder):
                print(f"Ignored directory {local_dir_path}")
                continue

            local_dirs.append(relative_dir_path)

            # 创建远程空目录
            remote_dir_path = os.path.join(remote_folder, relative_dir_path).replace("\\", "/")
            create_remote_directory(sftp, remote_dir_path)

    # 获取远程文件列表
    remote_files = get_remote_file_list(sftp, remote_folder)

    # 记录待删除的文件和目录
    to_delete = []

    # 删除远程文件（那些本地不存在的文件）
    for remote_file, is_dir in remote_files:
        relative_remote_path = os.path.relpath(remote_file, remote_folder).replace("\\", "/")
        if relative_remote_path not in local_files and relative_remote_path not in local_dirs:
            to_delete.append(remote_file)

    # 执行删除操作
    for remote_file in to_delete:
        delete_remote_file_or_directory(sftp, remote_file)

# 配置主机信息
server = '192.168.2.108'
port = 22
user = 'root'
password = '123123'
local_folder = r'D:\code\vs_python\rss'
remote_folder = '/path/to/your/remote/folder'
ignore_file_path = 'sync_ignore.txt'  # 忽视列表文件的路径

# 加载忽视列表
ignore_patterns = load_ignore_list(ignore_file_path)

# 创建SSH连接并执行同步
ssh_client = create_ssh_client(server, port, user, password)
sftp = ssh_client.open_sftp()
sync_folder(local_folder, remote_folder, sftp, ignore_patterns)
sftp.close()
ssh_client.close()

Assistant:
Assistant: