使用python通过ssh同步文件V2.0

#!usr/bin/python
# coding: utf-8

import json
import os
import sys
import time
import paramiko
import win32api
import win32con
import stat

os.chdir(os.path.dirname(os.path.abspath(__file__)))

config_filename = "config.json"
conf_key = ["remoteDir", "localDir", "host", "port", "username", "password", "checkMinSize", "proxy", "proxyIP", "proxyPort"]

downloaded = 0
print_str = ''


def write_config_file():
    default_conf = '{\n' \
                   '"remoteDir": "/www/",\n' \
                   '"localDir": "./www/",\n' \
                   '"host": "127.0.0.1",\n' \
                   '"port": 22,\n' \
                   '"username": "root",\n' \
                   '"password": "root",\n' \
                   '"checkMinSize": 1024,\n' \
                   '"proxy": true,\n' \
                   '"proxyIP": "127.0.0.1",\n' \
                   '"proxyPort": 1080\n' \
                   '}'
    f = open(config_filename, "w")
    f.write(default_conf)


def progress_bar(transferred, toBeTransferred):
    percents = round(100.0 * transferred / float(toBeTransferred), 1)
    sys.stdout.write('%s [%s%s] %s\r' % (print_str.encode("gbk"), '%s' % percents, '%', '%.2fMB' %
                                         (toBeTransferred / 1024 / 1024.00)))
    if percents != 100:
        sys.stdout.flush()
    else:
        print


class Download:
    # 初始化连接
    def __init__(self):
        self.config = {}
        self.read_config_file()
        self.set_proxy()
        self.scp = paramiko.Transport((self.config["host"], self.config["port"]))
        self.scp.connect(username=self.config["username"], password=self.config["password"])
        self.sftp = paramiko.SFTPClient.from_transport(self.scp)

        self.client = paramiko.SSHClient()
        self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        self.client.connect(hostname=self.config["host"], port=self.config["port"], username=self.config["username"], password=self.config["password"])
        stdin, stdout, stderr = self.client.exec_command(" find " + self.config["remoteDir"] + " -type f | wc -l")
        self.file_num = int(stdout.read())

    def read_config_file(self):
        if os.path.isfile(config_filename):
            try:
                f = open(config_filename, "r")
                config_ff = json.loads(f.read())
                config = {}
                for k in conf_key:
                    config[k] = config_ff[k]
                self.config = config
            except BaseException as e:
                print e
                win32api.MessageBox(0, "Config file error!", "ERROR", win32con.MB_ICONHAND)
                exit()
        else:
            self.write_config_file()
            win32api.MessageBox(0, "Config file missing. \rThe program has been created automatically.", "ERROR",
                                win32con.MB_ICONHAND)
            exit()

    def set_proxy(self):
        if self.config["proxy"]:
            import socks
            import socket
            socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, self.config["proxyIP"], self.config["proxyPort"], False, '',
                                  '')
            socket.socket = socks.socksocket

    def download_dir(self, localDir="", remoteDir=""):
        global file_num
        global print_str
        global downloaded
        if localDir == '':
            localDir = self.config["localDir"]
        if remoteDir == '':
            remoteDir = self.config["remoteDir"]
        localDir = localDir.rstrip("\\").rstrip("/")
        remoteDir = remoteDir.rstrip("\\").rstrip("/")

        if not os.path.exists(localDir):
            os.makedirs(localDir)

        files = self.sftp.listdir_attr(remoteDir)
        for f in files:
            localFile = os.path.join(localDir, f.filename)
            remoteFile = remoteDir + "/" + f.filename
            if stat.S_ISREG(f.st_mode):
                downloaded += 1
                try:
                    localSize = os.path.getsize(localFile)
                except:
                    localSize = 0
                if not os.path.isfile(localFile) or f.st_size != localSize:
                    print_str = (str(downloaded) + "/" + str(self.file_num) + "  ").rjust(11) + "Download:  ".rjust(12) + localFile
                    self.sftp.get(remoteFile, localFile, callback=progress_bar)
                else:
                    print (str(downloaded) + "/" + str(self.file_num) + "  ").rjust(11) + "Exists:  ".rjust(12) + localFile
            elif stat.S_ISDIR(f.st_mode):
                self.download_dir(localDir=localFile, remoteDir=remoteFile)
                pass
            else:
                pass

    def download_file(self):
        pass


if __name__ == "__main__":
    d = Download()
    print "Total files:" + str(d.file_num)
    time.sleep(1)
    d.download_dir()
    d.scp.close()
    print "Done!"
    time.sleep(10)

使用pyinstaller打包成exe使用更方便

《使用python通过ssh同步文件V2.0》SSH下载器.zip

点赞

发表评论

邮箱地址不会被公开。 必填项已用*标注