# -*- coding: UTF-8 -*- import ConfigParser import json import os import re import sys import time # from compare_dependency import CompareDependency from encrypt_tool.encrypt_app import CryptApp DIR_PATH = os.path.split(os.path.realpath(__file__))[0] BASE_PATH = os.path.split(DIR_PATH)[0] class Package(object): def __init__(self): # 第一步:初始化一些变量,获取app fold name 版本等等 self.__svn_up() self.app_name = self.__get_app_name() self.version = '1.0.0' self.work_path_base = '/tmp' # 输出的dat包放置的位置,默认与package.py 放在同级目录 self.package_out_path = DIR_PATH # 打包的临时目录 self.app_work_path = os.path.normpath(os.path.join(self.work_path_base, self.app_name)) print self.app_work_path # 清理tmp目录下面的已有的 os.system("rm -rf " + self.app_work_path) # 不加密的py目录 self.py_not_encnrypt_list = self.__get_py_not_encrypt() # 第二步:选择编译前端代码,npm run build self.packageFrontEnd() # 第三步:获取svn版本号 # self.build_version = self.__get_svn() self.build_version = 23000 self.package_name = "%s.%s.%s.tar.gz" % (self.app_name, self.version, self.build_version) # 第五步:拷贝需要打包进组件的目录和文件到临时目录 self.do_copy_work_dir() # 第六步:检查加密的包配置 self.__get_encrypt_conf() # 第七步:把build_version 写到文件里面 self.__set_build_version() # 第八步:检查加密py的配置 self.__do_encrypt_file() # 第九步:加密py self.run_encrypt() def __get_app_name(self): with open(os.path.join(BASE_PATH, "package.json"), "r+") as f: pkgConfig = json.load(f) return pkgConfig["name"] def __get_py_not_encrypt(self): return { 'files': [ # os.path.normpath(APP_WORK_PATH + os.sep + 'install.py'), # os.path.normpath(APP_WORK_PATH + os.sep + "bin" + os.sep + "start.py"), # os.path.normpath(APP_WORK_PATH + os.sep + "bin" + os.sep + "check.py"), ], 'paths': [ os.path.normpath(self.app_work_path + os.sep + 'target'), os.path.normpath(self.app_work_path + os.sep + 'static'), ], } def __svn_up(self): # 更新svn到最新 # cmd = "cd %s && git pull " % BASE_PATH # os.system(cmd) pass def __get_svn(self): return 10000 # svnPath = BASE_PATH # try: # cmd = 'cd %s && svn info' % svnPath # svnContent = os.popen(cmd).read() # lang = os.popen('echo $LANG').read() # if 'en_US' in lang: # revision = 'Rev' # elif 'zh_CN' in lang: # revision = '最后修改的版本' # else: # print 'system language is not found' # sys.exit(1) # svnRe = re.compile('%s: (\d*?)\n' % revision) # svn_revision = svnRe.findall(svnContent)[0] # print 'svn_revision : %s cmd : %s' % (svn_revision, cmd) # except Exception, e: # print 'get SVN revision Failed. %s' % (str(e)) # sys.exit(1) # return svn_revision def do_copy_work_dir(self): print '拷贝数据到临时目录' os.chdir(BASE_PATH) cmd = 'rsync -az * --include="static/dist" --include="static/icon" --exclude="static/*" %s' % ( self.app_work_path) print cmd os.system(cmd) print '拷贝完成' def __get_encrypt_conf(self): sections_dict = dict() conf_path = os.path.normpath(os.path.join(self.app_work_path, 'target', 'encrypt_conf')) if not os.path.exists(conf_path): print 'conf file is not exists...' return try: cf = ConfigParser.ConfigParser() cf.read(conf_path) sections = cf.sections() for section in sections: options = cf.options(section) options_dic = dict() for option in options: try: value = cf.get(section, option).decode('utf-8', 'ignore') except Exception, e: value = cf.get(section, option) options_dic[option] = value sections_dict[section] = options_dic except Exception, e: print 'error', str(e) try: self.is_dat = int(sections_dict['encrypt'].get('is_dat', 0)) except: pass try: self.is_pyc = int(sections_dict['encrypt'].get('is_pyc', 0)) except: pass try: self.is_front_pac = int(sections_dict['encrypt'].get('is_front_pac', 0)) except: pass try: self.is_front_enc = int(sections_dict['encrypt'].get('is_front_enc', 0)) except: pass def __set_build_version(self): print "set package name ..." try: app_version_file = os.path.normpath(os.path.join(self.app_work_path, 'conf', 'buildversion')) with open(app_version_file, 'w') as fw: fw.write(self.build_version) except Exception, e: print e print "set package name done" def __do_encrypt_file(self): encrypt_pt_path = os.path.normpath(os.path.join(DIR_PATH, 'encrypt_tool', 'pyprotect.py')) print "start encrypt python file ..." for root, dirs, files in os.walk(self.app_work_path): if root in self.py_not_encnrypt_list['paths']: continue for fname in files: pyPath = os.path.normpath(os.path.join(root, fname)) if not fname.endswith('.py'): continue if pyPath in self.py_not_encnrypt_list['files']: continue cmd = "python '%s' '%s'" % (encrypt_pt_path, pyPath) os.system(cmd) # print cmd os.remove(pyPath) print "encrypt python file done" def packageFrontEnd(self): st = time.time() print "package static folder start ..." os.system('cd %s/static && npm install && npm run build' % BASE_PATH) et = time.time() print "package static folder done" print 'take time for %sS' % (et - st) def run_encrypt(self): print "package ..." install_py = "" os.chdir(self.work_path_base) # 把install 挪到和app 目录同级 # 判断install.py 存不存在,如果不存在,不必拷贝 if os.path.exists(os.path.join(self.app_work_path, "install.py")) or os.path.exists( os.path.join(self.app_work_path, "install.pyc")): install_py = "install.pyc" os.system("mv %s/%s ." % (self.app_name, install_py)) os.system("tar -zcf %s %s/ %s --exclude=.svn --exclude=%s/target --exclude=%s/java " "> /dev/null " % (self.package_name, self.app_name, install_py, self.app_name, self.app_name)) else: print "tar -zcf %s %s/ --exclude=.svn --exclude=%s/target --exclude=%s/java > /dev/null " % ( self.package_name, self.app_name, self.app_name, self.app_name) os.system("tar -zcf %s %s/ --exclude=.svn --exclude=%s/target --exclude=%s/java > /dev/null " % ( self.package_name, self.app_name, self.app_name, self.app_name)) print '执行成功' replace_reg = re.compile(r'tar.gz$') output_name = replace_reg.sub('dat', self.package_name) do_encrypt = CryptApp(self.package_name, output_name) do_encrypt.encrypt_app() # 删除 tar包 保留加密包 os.system("rm -rf %s " % self.package_name) if install_py: os.system("mv %s %s" % (install_py, self.app_name)) os.system("mv %s %s -f" % (output_name, DIR_PATH)) self.package_name = output_name print "package done" self.__info() def __info(self): print '\033[0;33m' print "*********************************" print "package ok. " print "package name:", self.package_name outputfile = os.path.join(self.package_out_path, self.package_name) md5 = os.popen("md5sum %s" % outputfile).readlines()[0].strip() print "package path:", md5.split(' ')[-1] print "package md5:", md5.split(' ')[0] print '>>>>>>', 'is_dat:', 'yes' if self.is_dat else 'no' print '>>>>>>', 'is_pyc:', 'yes' if self.is_pyc else 'no' print '>>>>>>', 'is_front_enc:', 'yes' if self.is_front_enc else 'no' print '>>>>>>', 'is_front_pac:', 'yes' if self.is_front_pac else 'no' print "*********************************" print '\033[0m' def do_remove_work_dir(self): cmd = 'rm %s -rf' % self.app_work_path os.system(cmd) # print 'remove %s successfully...' % (APP_WORK_PATH) def usage(): print "usage:" print "python package.py ---- run script without a parameter, make a encrypted package" if __name__ == '__main__': ''' "python package.py ---- run script without a parameter, make a encrypted package" ''' main_param = sys.argv # 清除已经安装的包 for fileitem in os.listdir(BASE_PATH + "/target"): if fileitem.endswith(".dat"): os.remove(BASE_PATH + "/target/" + fileitem) if len(main_param) == 1: Package() else: usage()