python linux目录上传脚本。自动对比文件md5一键上传,上传模式SFTP。 支持路径排除,多目录上传,自动创建文件夹。
免费分享, 有能力可以点下面链接支持一下
https://download.csdn.net/download/samema/86824767
from __future__ import print_function
import json, os, platform, re, datetime, time, zipfile, wget, paramiko, shutil, win32file, win32con, hashlib
dirname, filename = os.path.split(os.path.abspath(__file__))
#服务器配置
server_ip = "192.168.1.100"
server_port = 22
server_username = "root"
server_password = "password"
#配置文件名
server_name = "test_server"
server_name_title = "我的服务器"
#设置上传路径
server_paths = {
"server": {
"local" : os.path.abspath(dirname + "/server"),
"server" : "/home/myserver",
},
"client" : {
"local" : os.path.abspath(dirname + "/client"),
"server" : "/www/wwwroot/test",
},
}
#排除文件, 分支名 + 相对路径,
#匹配模式为startswith
pass_files = [
'server/temp',
'client/build',
]
conf_path = os.path.abspath(dirname + "/conf.json")
def convertPath(localPath:str, serverPath:str, filePath: str):
localPath = localPath.strip().replace('\\','/')
serverPath = serverPath.strip().replace('\\','/')
filePath = filePath.replace('\\','/').replace(localPath, '')
if not serverPath.endswith('/') and not filePath.startswith('/') :
serverPath = serverPath + '/'
return serverPath + filePath, filePath
def getmd5(file:str):
m = hashlib.md5()
with open(file,'rb') as f:
for line in f:
m.update(line)
md5code = m.hexdigest()
return md5code
def fileName(path:str):
return os.path.basename(path)
def isHidenFile(filePath):
if 'Windows' in platform.system():
fileAttr = win32file.GetFileAttributes(filePath)
if fileAttr & win32con.FILE_ATTRIBUTE_HIDDEN :
return True
return False
return False
def getFiles(path:str, ex:str = '*', showHiden:bool=False):
file = []
for root, dirs, files in os.walk(path):
for f in files:
_path = os.path.join(root, f)
if (ex == '*' or f.endswith(ex)) and (showHiden or not isHidenFile(_path)) :
file.append(_path)
return file
def clearDir(filepath):
if not os.path.exists(filepath):
os.mkdir(filepath)
else:
shutil.rmtree(filepath)
os.mkdir(filepath)
def makeDir(path):
if not os.path.exists(path):
os.makedirs(path)
def copyFile(source:str, target:str):
makeDir(os.path.dirname(target))
if os.path.isdir(source):
if os.path.exists(target):
shutil.rmtree(target)
return shutil.copytree(source, target)
else:
return shutil.copyfile(source, target)
def downFile(url, path):
makeDir(os.path.dirname(path))
wget.download(url, path)
f = open(path, 'r', -1, 'utf8')
data = f.read()
f.close()
return data
def toJson(_data):
if not _data or _data == "":
return None
try:
return json.loads(_data)
except ValueError:
return None
def loadFile(path):
if not os.path.isfile(path):
return None
f = open(path, 'r', -1, 'utf8')
data = f.read()
f.close()
return data
def saveFile(path, data):
makeDir(os.path.dirname(path))
f = open(path, 'w', -1, 'utf8')
f.write(data)
f.close()
def loadJson(path):
data = loadFile(path)
return toJson(data) if data else None
def saveJson(path, data):
saveFile(path, json.dumps(data, ensure_ascii=False, indent=4))
def getSize(size):
size = round(size/float(1024 * 1024), 2)
return "%.2f MB"%(size)
def cmd(comm):
return os.system(comm)
def date(fmt = "%Y-%m-%d %H:%M:%S"):
return time.strftime(fmt, time.localtime())
def mkdir_p(sftp, remote_directory):
if remote_directory == '/':
sftp.chdir('/')
return
if remote_directory == '':
return
try:
sftp.chdir(remote_directory)
except IOError:
dirname, basename = os.path.split(remote_directory.rstrip('/'))
mkdir_p(sftp, dirname)
sftp.mkdir(basename)
sftp.chdir(basename)
return True
def chdir(path):
os.chdir(path)
def uploadFiles(files: dict):
global server_ip, server_port, server_username, server_password
transport = paramiko.Transport((server_ip, server_port)) # 获取Transport实例
transport.connect(username=server_username, password=server_password) # 建立连接
sftp = paramiko.SFTPClient.from_transport(transport)
num_max = len(files)
num = 0
for file in files:
num += 1
print('上传'+str(num)+'/'+str(num_max), file['file'])
mkdir_p(sftp, os.path.dirname(file['server']))
sftp.put(file['local'], file['server'])
transport.close()
def checkPass(path):
global pass_files
for _path in pass_files:
if path.startswith(_path):
return False
return True
def main():
config = loadJson(conf_path)
update_list = []
if not config:
config = {}
config[server_name] = {}
if not config.__contains__(server_name):
config[server_name] = {}
for name, paths in server_paths.items():
print("开始检测 " + name)
for file_path in getFiles(paths["local"]):
(sverPath, file) = convertPath(paths["local"], paths["server"], file_path)
md5 = getmd5(file_path)
conf_key = name + file
if checkPass(conf_key) and (not config[server_name].__contains__(conf_key) or md5 != config[server_name][conf_key]):
if config[server_name].__contains__(conf_key):
del config[server_name][conf_key]
config[server_name][conf_key] = md5
print('检测到文件改动', conf_key)
update_list.append({
'local': file_path,
'server': sverPath,
'file': conf_key,
})
if(len(update_list) == 0):
print('没有文件更新')
os.system('pause')
exit()
print(str(len(update_list)) + '个文件需要更新,是否更新 ip=' + server_ip)
os.system('pause')
uploadFiles(update_list)
saveJson(conf_path, config)
print('更新完成')
os.system('pause')
if __name__ == "__main__":
main()