python實現綠色軟件的升級,包括單文件升級和多文件升級
阿新 • • 發佈:2017-07-28
odi dev argv odin txt 註意 store isf out
# coding:utf-8 import sys, os, time import zipfile import shutil def print_usage(): print ‘‘‘usage: python software_upgrade.py subZipFullPath, targetZipFullPath, mainVersionZipPath[, relativePath]\n for example: linux platform: python software_upgrade.py /test/software_upgrade/subVersionDir/readme.txt /test/software_upgrade/latestVersionDir/myAPP_latest.zip /test/software_upgrade/mainVersionDir/myAPP_main.zip /readme.txt python software_upgrade.py /test/software_upgrade/subVersionDir/myAPP_subVersion_0.1.zip /test/software_upgrade/latestVersionDir/myAPP_latest.zip /test/software_upgrade/mainVersionDir/myAPP_main.zip windows platform: python software_upgrade.py C:\software_upgrade\subVersionDir\readme.txt C:\software_upgrade\latestVersionDir\myAPP_latest.zip C:\software_upgrade\mainVersionDir\myAPP_main.zip \readme.txt python software_upgrade.py C:\software_upgrade\subVersionDir\myAPP_subVersion_0.1.zip C:\software_upgrade\latestVersionDir\myAPP_latest.zip C:\software_upgrade\mainVersionDir\myAPP_main.zip ‘‘‘ def my_copytree(src, dst, symlinks=False): """ 若同樣的目標已存在則不動 Args: src: dst: symlinks: Returns: """ names = os.listdir(src) if not os.path.isdir(dst): os.makedirs(dst) errors = [] for name in names: srcname = os.path.join(src, name) dstname = os.path.join(dst, name) try: if symlinks and os.path.islink(srcname): linkto = os.readlink(srcname) os.symlink(linkto, dstname) elif os.path.isdir(srcname): my_copytree(srcname, dstname, symlinks) else: if os.path.isdir(dstname): os.rmdir(dstname) elif os.path.isfile(dstname): os.remove(dstname) shutil.copy2(srcname, dstname) # XXX What about devices, sockets etc.? except (IOError, os.error) as why: errors.append((srcname, dstname, str(why))) # catch the Error from the recursive copytree so that we can # continue with other files except OSError as err: errors.extend(err.args[0]) try: shutil.copystat(src, dst) except WindowsError: # can‘t copy file access times on Windows pass except OSError as why: errors.extend((src, dst, str(why))) if errors: pass # raise Error(errors) def unzip(filename, filedir): """ Args: filename: ‘foobar.zip‘ #要解壓的文件 filedir: 解壓後放入的目錄 Returns: """ r = zipfile.is_zipfile(filename) if r: starttime = time.time() fz = zipfile.ZipFile(filename, ‘r‘) for file in fz.namelist(): # print(file) # 打印zip歸檔中目錄 fz.extract(file, filedir) endtime = time.time() times = endtime - starttime else: print(‘This file is not zip file‘) print(‘[unzip file] time costs:‘ + str(times)) def zip(path, filename): """ 默認情況下,zip壓縮會保留根目錄,我們這裏不保留根目錄 Args: path: 要進行壓縮的文檔目錄 filename: ‘foobar.zip‘ # 壓縮後的文件名 Returns: """ try: import zlib compression = zipfile.ZIP_DEFLATED # 壓縮方法 except: compression = zipfile.ZIP_STORED starttime = time.time() # start = path.rfind(os.sep) + 1 # os.sep 分隔符 (保留根目錄) start = len(path) # (不保留根目錄) z = zipfile.ZipFile(filename, mode="w", compression=compression) try: for dirpath, dirs, files in os.walk(path): for file in files: if file == filename or file == "zip.py": continue # print(file) z_path = os.path.join(dirpath, file) z.write(z_path, z_path[start:]) z.close() endtime = time.time() times = endtime - starttime except: if z: z.close() print(‘[create zip file] time costs:‘ + str(times)) def create_latest_package(subVersionFullPath, latestVersionFullPath, mainVersionFullPath, relativePath): """ Args: subVersionFullPath: latestVersionFullPath: latest_Zip_path mainVersionFullPath: relativePath: Returns: """ if os.path.exists(subVersionFullPath) and os.path.exists(mainVersionFullPath): # 判斷子版本和主版本zip包是否存在 if not os.path.exists(latestVersionFullPath): # 如果不存在最新版本的zip包,將子版本的最新文件與主版本的文件進行組裝,然後將組裝後的文件壓縮到最新版本所在的目錄 oper(subVersionFullPath, mainVersionFullPath, latestVersionFullPath, relativePath) else: # 如果存在最新版本的zip包,將子版本的最新文件與最新版本的文件進行組裝,然後將組裝後的文件壓縮到最新版本所在的目錄 oper(subVersionFullPath, latestVersionFullPath, latestVersionFullPath, relativePath) else: print "not exists {0} or {1}".format(subVersionFullPath, mainVersionFullPath) def oper(srvZipPath, destZipPath, outZipPath, relativePath): """ 註意:多文件替換時,一般多文件存在壓縮包中,所以需要解壓 基本思路 1.將最新版本的zip文件解壓到同級的tmp目錄中 2.如果是單文件升級,則將子版本的文件拷貝到1步驟中的tmp目錄裏;如果是多文件升級,則首先需要將多文件解壓,然後再拷貝 3.將步驟2替換後的tmp文件重新壓縮,並放到新版本的位置 Args: srvZipPath: 子版本zip路徑 destZipPath: 目標版本zip路徑 outZipPath: 組裝後,生成新的zip文件的完整路徑 relativePath: 單文件和多文件標識,若為None則表明多文件替換,否則單文件替換 Returns: """ # 若最終生成的zip文件所在的路徑不存在,則創建 outZipPathDir = os.path.dirname(outZipPath) os.makedirs(outZipPathDir) if not os.path.exists(outZipPathDir) else ‘‘ # 確定臨時文件的路徑 srvZipPathTmp = os.path.dirname(srvZipPath) + os.sep + "tmp" destZipPathTmp = os.path.dirname(destZipPath) + os.sep + "tmp" print "[unzip target zip] srv:{0} dest:{1}".format(destZipPath, destZipPathTmp) unzip(destZipPath, destZipPathTmp) # 解壓目標zip文件 if relativePath: # 單文件和多文件標識,若為None則表明多文件替換,否則單文件替換 print "[single file replace] srv:{0} dest:{1}".format(srvZipPath, destZipPathTmp + relativePath) shutil.copy(srvZipPath, destZipPathTmp + relativePath) # 將要升級的文件拷貝到已經解壓開的目標zip文件destZipPathTmp中 else: print "[unzip source zip] srv:{0} dest:{1}".format(srvZipPath, srvZipPathTmp) unzip(srvZipPath, srvZipPathTmp) print "[replace files] srvZipPathTmp:{0} destZipPathTmp:{1}".format(srvZipPathTmp, destZipPathTmp) my_copytree(srvZipPathTmp, destZipPathTmp) # 將要升級的文件拷貝到已經解壓開的目標zip文件destZipPathTmp中 print "[create new zip file] srv:{0} dest:{1}".format(destZipPathTmp, outZipPath) zip(destZipPathTmp, outZipPath) # 刪除臨時文件 shutil.rmtree(srvZipPathTmp) if os.path.exists(srvZipPathTmp) else ‘‘ shutil.rmtree(destZipPathTmp) if os.path.exists(destZipPathTmp) else ‘‘ print "success" if __name__ == ‘__main__‘: number = 0 for i in sys.argv: print "arg{0}: {1}".format(number, i) number += 1 if len(sys.argv) < 4 or len(sys.argv) > 5: print_usage() if len(sys.argv) == 4: create_latest_package(sys.argv[1], sys.argv[2], sys.argv[3], None) elif len(sys.argv) == 5: create_latest_package(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
python實現綠色軟件的升級,包括單文件升級和多文件升級