之前有使用批处理进行前面和打包,感觉好累人啊。所以抽了点时间学习一下python。虽然是第一次接触python,学习之后感觉python比较强大,在很多方面比较像C++。以后大可以使用python代替批处理了。以下是我写的一个签名和打包的代码。这个代码受限于我们公司的签名等流程。不过里面有写文件、ftp、目录、字符串、面向对象的东西,可以作为以后使用的标记。
import ConfigParser
import os
from ftplib import FTP
import time
import shutil
timedir=time.strftime('%Y-%m-%d_%H_%M')
print timedir
def list_dir(dirpath):
filelist=[]
dirlist=[]
if os.path.isdir(dirpath):
files=os.listdir(dirpath)
for i in files:
if os.path.isdir(dirpath+'\\'+i):
filelist = filelist + list_dir(dirpath+'\\'+i)
dirlist.append(dirpath)
else:
filelist.append(dirpath+'\\'+i)
return filelist
class FtpConfigInfo:
'''get ftp config info from file'''
def __init__(self,confpath):
self.confpath=confpath
self.parse()
def parse(self):
try:
config = ConfigParser.ConfigParser()
config.readfp(open(self.confpath))
self.ip=config.get('Ftp','ip')
self.port=config.getint('Ftp','port')
self.pasv=config.getboolean('Ftp','pasv')
self.user=config.get('Ftp','user')
self.pswd=config.get('Ftp','pswd')
except:
print 'error: parse ftp failed!!!'
def get_ip(self):
return self.ip
def get_port(self):
return self.port
def get_pasv(self):
return self.pasv
def get_user(self):
return self.user
def get_pswd(self):
return self.pswd
def dispay_info(self):
print 'ftp config info:'
print 'ip:',self.ip
print 'port:',self.port
print 'pasv:',self.pasv
print 'user:',self.user
print 'pswd:',self.pswd
class SetupConfigInfo:
'''get about make setup arg info'''
def __init__(self,configfilepath):
self.toolpath=''
self.scriptlist=[]
self.outputfilelist=[]
self.uninstallfilelist=[]
self.confpath=configfilepath
self.succeed=False
self.succeed=self.parse()
pass
def get_setup_tool_path(self):
return self.toolpath
pass
def get_setup_script_count(self):
return len(self.scriptlist)
pass
def get_setup_script_files(self):
return self.scriptlist
def get_output_files(self):
return self.outputfilelist
def get_uninstaller_files(self):
return self.uninstallfilelist
def is_succeed(self):
return self.succeed
def parse(self):
try:
print self.confpath
config = ConfigParser.ConfigParser()
config.readfp(open(self.confpath))
self.toolpath=os.path.abspath(config.get('Setup','tool'))
self.count=config.getint('Setup','num')
print self.count
for i in range(0,self.count):
filename=config.get('Setup','file'+str(i))
self.scriptlist.append(os.path.abspath(filename))
filename=config.get('Setup','output'+str(i))
self.outputfilelist.append(os.path.abspath(filename))
filename=config.get('Setup','uninstaller'+str(i))
self.uninstallfilelist.append(os.path.abspath(filename))
except:
print 'error: parse SetupConfigInfo failed!!!'
return False
return True
def display(self):
print self.toolpath
print self.scriptlist
print self.outputfilelist
print self.uninstallfilelist
class SignConfigInfo:
''' get need sign files and old signed files'''
def __init__(self,configfilepath):
self.confpath=configfilepath
#print configfilepath
self.unsignedfilelist=[]
self.oldsignedfilelist=[]
self.succeeed=False
self.succeeed=self.parse()
def is_succeed(self):
return self.succeeed
def parse(self):
'''parse config file to get need sign files
and old signed files'''
try:
self.parse_package_dir()
self.parse_signed_dir()
self.parse_old_signed_dir()
self.parse_old_signed_files()
self.parse_unsigned_files()
self.parse_backup_dir()
except:
print 'error: parse file %s failed!!!' %self.confpath
def parse_unsigned_files(self):
'''parse file to get unsigned file list'''
try:
print self.packagedir
if self.packagedir=='':
self.parse_package_dir()
config = ConfigParser.ConfigParser()
config.readfp(open(self.confpath))
self.count=config.getint('Files','num')
for i in range(0,self.count):
filename=config.get('Files','file'+str(i))
self.unsignedfilelist.append(self.packagedir+'\\'+filename)
except:
print 'error: parse_unsigned_files failed!!!'
return False
return True
def parse_old_signed_files(self):
'''get old signed files'''
self.parse_old_signed_dir()
self.oldsignedfilelist=list_dir(self.oldsigneddir)
def parse_old_signed_dir(self):
'''get signed dir'''
try:
config = ConfigParser.ConfigParser()
config.readfp(open(self.confpath))
self.oldsigneddir=os.path.abspath(config.get('Dir','olddir'))
print self.oldsigneddir
except:
print 'error: parse_old_signed_dir failed!!!'
def parse_backup_dir(self):
'''get backup dir'''
try:
config = ConfigParser.ConfigParser()
config.readfp(open(self.confpath))
self.backupdir=os.path.abspath(config.get('Dir','backupdir'))+'\\'+timedir+'\\'
#print self.backupdir
except:
print 'error: parse_backup_dir failed!!!'
def parse_package_dir(self):
'''get backup dir'''
try:
config = ConfigParser.ConfigParser()
config.readfp(open(self.confpath))
self.packagedir=os.path.abspath(config.get('Dir','packagedir'))
except:
print 'error: parse_package_dir failed!!!'
def parse_signed_dir(self):
'''get backup dir'''
try:
config = ConfigParser.ConfigParser()
config.readfp(open(self.confpath))
self.signeddir=os.path.abspath(config.get('Dir','signeddir'))+'\\'+timedir+'\\'
#print self.signeddir
except:
print 'error: parse_package_dir failed!!!'
def get_signed_dir(self):
return self.signeddir
def get_backup_dir(self):
return self.backupdir
def get_package_dir(self):
return self.packagedir
def get_old_signed_dir(self):
return self.signeddir
def get_unsigned_files(self):
return self.unsignedfilelist
def get_old_signed_files(self):
return self.oldsignedfilelist
def get_unsigned_count(self):
return len(self.unsignedfilelist)
def get_ftp_conf_info(self):
'''get ftp config info'''
ftpconf=FtpConfigInfo(self.confpath)
return ftpconf
def get_setup_conf_info(self):
setupconf=SetupConfigInfo(self.confpath)
return setupconf
class SignFtp:
def __init__(self,FtpConfigInfo):
self.ftp=FTP()
self.ftp.set_debuglevel(2)
self.ftpconfig=FtpConfigInfo
self.bconnect=False
self.localdir=os.path.abspath('.')+'\\'
self.remotedir='//' #root dir
self.currentremotefilelist=[]
self.currentremotedirlist=[]
self.lastlistdir=''
#pass
def __del__(self):
self.disconnect()
def connect(self):
'''connect to sign server and login with config file'''
try:
self.ftp.connect(self.ftpconfig.get_ip(),self.ftpconfig.get_port())
self.ftp.login(self.ftpconfig.get_user(),self.ftpconfig.get_pswd())
self.bconnect=True
print self.ftp.getwelcome()
self.ftp.set_pasv(False)
#self.ftp.retrlines('LIST')
#self.ftp.nlst()
except:
return False
return True
def disconnect(self):
'''disconnect with server'''
if self.bconnect==True:
self.ftp.close()
def delete_file(self,filename):
'''delete file from server'''
try:
self.ftp.delete(filename)
except:
return False
return True
def delete_all_files(self):
try:
#if len(self.currentremotefilelist)==0:
print self.get_remote_file_list()
for i in self.currentremotefilelist:
self.delete_file(i)
except:
print 'except: delete all files'
return False
return True
def get_file(self,filename):
'''get file from server and store to local dir'''
try:
print 'get file: ',self.get_local_dir()+filename
file_handler = open(self.get_local_dir()+filename,'wb').write
self.ftp.retrbinary('RETR '+filename,file_handler)
except:
print 'except: get file ',filename
return False
return True
pass
def put_file(self,filepath):
'''put local file to server'''
try:
print 'put file:',filepath
if os.path.exists(filepath)==False:
print '%s not exist'%filepath
return False
file_com=os.path.split(filepath)
if len(file_com)==2:
file_name=file_com[1]
file_handler=open(filepath,'rb')
self.ftp.storbinary('STOR '+file_name,file_handler)
#self.ftp.retrlines('LIST')
else:
print 'put_file:',filepath
return False
except:
print ''
return False
return True
def set_local_dir(self,localdir):
'''set local work dir,default use current dir'''
print localdir
olddir=self.localdir
if localdir.endswith('\\')==False:
self.localdir=localdir+'\\'
else:
self.localdir=localdir
if os.path.exists(self.localdir)==False:
os.makedirs(self.localdir)
print self.localdir
return olddir
def set_remote_dir(self,remotedir):
'''change remote server dir'''
self.ftp.cwd(remotedir)
#self.ftp.retrlines('LIST')
self.remotedir=remotedir
self.lastlistdir=''
pass
def get_dir(self):
'''get dir files to local'''
self.get_remote_file_list()
bsucceed=True
for i in self.currentremotefilelist:
bsucceed = bsucceed and self.get_file(i)
return bsucceed
def put_dir(self,dirpath):
'''put local dir files to server'''
file_list=list_dir(dirpath)
bsucceed=True
for i in file_list:
print i #notes: make dir
bsucceed = bsucceed and self.put_file(i)
return bsucceed
pass
def get_remote_dir(self):
'''get current remote dir'''
return self.remotedir
def get_local_dir(self):
'''get current local dir'''
return self.localdir
def get_last_list_dir(self):
return self.lastlistdir
def get_remote_file_list(self,rdir='.'):
'''get specified dir's file list'''
#if rdir!=self.lastlistdir:
self.lastlistdir=rdir
self.currentremotefilelist=[]
self.currentremotedirlist=[]
self.ftp.dir(rdir,self.list_callback)
return self.currentremotefilelist
pass
def get_remote_dir_list(self,rdir='.'):
'''get specified dir's dir list'''
#if rdir!=self.lastlistdir:
self.lastlistdir=rdir
self.currentremotefilelist=[]
self.currentremotedirlist=[]
self.ftp.dir(rdir,self.list_callback)
return self.currentremotedirlist
def list_callback(self,line):
'''list call'''
file_attr=line.split()
if len(file_attr)>2:
if self.__is_remote_dir(line)==True:
self.currentremotedirlist.append(file_attr[-1])
else:
self.currentremotefilelist.append(file_attr[-1])
else:
raise Exception
def __is_remote_dir(self,line):
'''internal use'''
file_attr=line.split()
if len(file_attr)>2:
if file_attr[-2].upper()=='<DIR>':
return True
return False
#def get_current_pwd(self)
class MakeSetup:
def __init__(self,configfilepath):
self.confinfo=SignConfigInfo(configfilepath)
if self.confinfo.is_succeed()==False:
print 'Error:MakeSetup->__init__->SignConfigInfo'
raise Exception
def ready(self):
'''check everyting is ready'''
#copy files to backup dir
unsignedfilelist=self.confinfo.get_unsigned_files()
backupdir=self.confinfo.get_backup_dir()
signeddir=self.confinfo.get_signed_dir()
if os.path.exists(signeddir)==False:
os.makedirs(signeddir)
if os.path.exists(backupdir)==False:
os.makedirs(backupdir)
for i in unsignedfilelist:
shutil.copy(i,backupdir)
pass
def make(self):
print os.path.abspath('..\..\tools\NSIS\makensis.exe')
ftpconfinfo = self.confinfo.get_ftp_conf_info()
setupconfinfo = self.confinfo.get_setup_conf_info()
signconfinfo = self.confinfo
backupdir=self.confinfo.get_backup_dir()
packagedir=self.confinfo.get_package_dir()
signeddir=self.confinfo.get_signed_dir()
oldsignedfilelist=self.confinfo.get_old_signed_files()
print 'old signed files:',oldsignedfilelist
if signconfinfo.get_unsigned_count()==0:
return 'no file need sign'
filelist=[]
filelist=signconfinfo.get_old_signed_files()
#print 'signed file:',filelist
unsignedfilelist=[]
unsignedfilelist=signconfinfo.get_unsigned_files()
#print 'unsigned files:',unsignedfilelist
ftpsign = SignFtp(ftpconfinfo)
ftpsign.connect()
ftpsign.delete_all_files()
print 'sign files:',backupdir
if self.sign_dir(ftpsign,backupdir)==False:
return False
signeddir=self.confinfo.get_signed_dir()
self.get_signed_files(ftpsign,signeddir)
#
ftpsign.delete_all_files()
#copy signed files
print 'copy sign files to ',packagedir
signedlist = []
signedlist=list_dir(signeddir)
for i in signedlist:
file_com=os.path.split(i)
if len(file_com)==2:
if file_com[1].find('results.txt')!=-1 or file_com[1].find('ok.txt')!=-1:
print 'signed file:',file_com[1]
continue
shutil.copy(i,packagedir)
#copy old signed files to package dir
print 'copy old signed file to ',packagedir
for i in oldsignedfilelist:
print 'copy signed file:',i
shutil.copy(i,packagedir)
signtool=setupconfinfo.get_setup_tool_path()
setupconfinfo.display()
signscriptfilelist=[]
signscriptfilelist=setupconfinfo.get_setup_script_files()
setupoutfilelist=setupconfinfo.get_output_files()
uninstallerfilelist=setupconfinfo.get_uninstaller_files()
print 'making setup'
#remove old output files
for i in setupoutfilelist:
if os.path.exists(i)==True:
os.remove(i)
#make new setup files
for i in range(0,len(signscriptfilelist)):
#copy uninstaller to package dir
#print packagedir+'\\'+'Uninstaller.exe'
if os.path.exists(packagedir+'\\'+'Uninstall.exe')==True:
os.remove(packagedir+'\\'+'Uninstall.exe')
shutil.copy(uninstallerfilelist[i],packagedir+'\\'+'Uninstall.exe')
print signtool + ' '+signscriptfilelist[i]
os.popen(signtool + ' '+signscriptfilelist[i])
#system
print 'sign setup files'
ftpsign.delete_all_files()
#sign setup files
self.sign_files(ftpsign,setupoutfilelist)
#get signed setup files
print 'get signed setup files'
self.get_signed_files(ftpsign,signeddir)
ftpsign.delete_all_files()
ftpsign.disconnect()
return True
def wait_sign_finish(self,ftpsign):
wait_count=0
while ftpsign.get_file('results.txt')==False and wait_count < 10:
print 'waiting sign finish...%d'%wait_count
time.sleep(10)
wait_count = wait_count+1
if wait_count>=10:
print 'error: not find results.txt'
raise Exception
def sign_files(self,ftpsign,filelist):
succeed = True
for i in filelist:
print 'sign:',i
succeed = succeed and ftpsign.put_file(i)
if succeed==False:
break
okfile=os.path.abspath('ok.txt')
if os.path.exists(okfile)==False:
open(okfile,'wb')
succeed = succeed and ftpsign.put_file(okfile)
return succeed
def sign_dir(self,ftpsign,dirpath):
return ftpsign.put_dir(dirpath)
def get_signed_files(self,ftpsign,localdirpath):
self.wait_sign_finish(ftpsign)
#print localdirpath
olddir = ftpsign.set_local_dir(localdirpath)
ftpsign.get_dir()
ftpsign.set_local_dir(olddir)
def notify(self,msg):
'''notify developer make info'''
print msg
pass
#test
if __name__=='__main__':
makesetup=MakeSetup('build.ini')
if makesetup.ready()==False:
makesetup.notify('ready failed')
else:
if makesetup.make()==False:
makesetup.notify('make failed')
else:
makesetup.notify('make succeed')
#print 'make succeed'