如何用python的pysmb模块,下载smb服务器上的以deb结尾文件?

发布时间 2023-05-26 12:52:54作者: 山雨欲來風滿楼

需求:

  • 如何用python的pysmb模块,下载smb服务器上的以deb结尾文件?
    • 服务器在192.168.9.5
  • 扩展需求:有时候,也会下载以xxx开头的文件。

实现方式:

  • #  !/usr/bin/env python
    #  -*- coding: utf-8 -*-
    # 安装依赖模块:pip install pysmb
    
    from smb.SMBConnection import SMBConnection
    import re, os
    
    host = "192.168.9.5"  # 192.168.9.5服务器ip
    username = "qi.li@gg.net"  # 用户名,改成你自己的
    password = "liqi123456"  # 密码,
    conn_name = "liqi"  # 这个随便,可以为空字符串
    remote_name = "FS-SH"  # 这个是上海192.168.9.5共享主机的主机名,listShares会用到,保持不变即可
    
    # ver_dir只能有一级,否则报错,所有路径拼接到ver_dir
    ver_dir = '发布路径'
    
    # connect to the server
    conn = SMBConnection(username, password, conn_name, remote_name, is_direct_tcp=True)  # is_direct_tcp 保持长连接
    
    conn.connect(host, 445)  # smb协议默认端口445
    
    
    def get_latest_file(conn, share_name, folder, extension, flag=False):
        """
        conn:连接对象
        share_name:  例如:'软件发布'
        folder: 例如: "/03 软件版本/"
        extension :  要搜索的名字 .deb 默认是以xxx结尾匹配
        flag : 默认是关闭。开启后会以开头进行匹配
        """
        file_list = conn.listPath(share_name, folder)  # 列出所有deb文件
        # print(file_list)
    
        # *=============================匹配方式===================================*
        if not flag:  # 默认以结尾匹配
            matching_files = [f for f in file_list if f.filename.endswith(extension)]  # 查找文件名是否以".deb"结尾
        else:
            matching_files = [f for f in file_list if f.filename.startswith(extension)]  # 匹配以xxx开头
        # *=======================================================================*
        # print(matching_files)
    
        # *==========如果没有找到文件,递归查找=========*
        if matching_files:
            # 根据时间来匹配版本
            versions = [re.search(r'\d+\.\d+\.\d+', f.filename).group() for f in matching_files]
            latest_version = max(versions)  # 以结尾匹配,会匹配到多个版本,取最大的
            latest_file = [f.filename for f in matching_files if latest_version in f.filename]
            # print(latest_file)
    
            # *=============================以结尾匹配会匹配多个===================================*
            if not flag:  # 默认以结尾匹配
                if len(latest_file) > 1:  # 过滤掉单个的
                    for file in latest_file:
                        res = os.path.join(folder, file)  # 拼接路径
                        print("查找到版本有:", res)
                        res_list.append(res)
            # *=============================以开头匹配会匹配1个===================================*
            else:
                for file in latest_file:
                    res = os.path.join(folder, file)  # 拼接路径
                    print("查找到版本有:", res)
                    res_list.append(res)
    
        # *==========如果没有找到文件,递归查找=========*
        else:
            # 如果没有
            folders = [f.filename for f in file_list if f.isDirectory]
            new_list = []
            for i in folders:
                res = re.findall(r"\.{1,2}$", i)  # 剔除掉.和..
                if not res:
                    new_list.append(i)
            for sub_folder in new_list:
                sub_folder_path = os.path.join(folder, sub_folder)
                result = get_latest_file(conn, share_name, sub_folder_path, extension, flag)  # 递归调用
                if result:
                    return result
            return None
    
    
    def down_files(conn, res_list):
        for file_path in res_list:
            # 下载最新的文件
            local_folder = '.'  # 在当前文件下载,也可以自己创建,但要保证目录有
            local_file_path = os.path.join(local_folder, os.path.basename(file_path))  # 本地要存的文件位置
            # print(local_file_path)
            with open(local_file_path, 'wb') as f:
                print(">>>正在下载:", local_file_path)
                conn.retrieveFile(ver_dir, file_path, f)
            print(">>>已下载:", file_path)
        else:
            print("没有找到指定扩展名的文件")
    
    
    if __name__ == '__main__':
        res_list = []  # 存储所有搜索到的文件路径
    
        # =====0.配置路径======
        ver_dir = "软件发布"
        path = "/03 用户软件版本/"  # 从哪个目录下开始递归查找
    
        # ver_dir = '部门共享'
        # path = r"/测试部/软件发布/主线版本/202305/"  #
    
        # =====1.要匹配的参数======
        extension = ".deb"  # 匹配 以.deb为后缀的
        # extension = "SDK" # 匹配开头
    
        # =====2.以结尾进行匹配=====
        get_latest_file(conn, ver_dir, path, extension)  # 以结尾查找
    
        # =====以开头行匹配=====
        # get_latest_file(conn, ver_dir, path, extension,flag=True)  # 以开头进行查找
    
        # =====3.下载文件=====
        down_files(conn, res_list)