# coding:utf-8 import json import os import shutil from core.config import settings class MakeTool: MakeDir = os.path.join(settings.ROOT_DIR, 'ApkTool') def __init__(self, channel_path): self.channel_path = channel_path self.apkName = '' self.apkNameSuffix = '0' self.easyName = '' self.easyNameSuffix = '0' self.packageId = '' self.packageIdSuffix = '0' self.keystore = '' self.storepass = '' self.alianame = '' self.keypass = '' self.owner = '' self.packNum = 0 self.start = 0 self.appid = '' self.gism_id = '' self.gism_name = '' self.gism_channel = '' self.lg_ad_id = '' self.lg_ad_name = '' self.gactionId = '' self.gappSecretKey = '' self.baiduId = '' self.baiduSecretKey = '' self.lg_reyun_game_appkey = '' self.lg_reyun_game_channelId = '' self.lg_reyun_io_appkey = '' self.lg_reyun_io_channelId = '' self.eventType = '' self.master_package = '' def _init_props(self): # 提取参数 props = dict() with open(self.channel_path, 'r') as f: props = json.load(f) # 母包路径 self.apkName = props.get('apkname', {}).get('value') or self.apkName self.apkNameSuffix = props.get('apkname', {}).get('suffix') or self.apkNameSuffix self.easyName = props.get('leguChannel', {}).get('value') or self.easyName self.easyNameSuffix = props.get('leguChannel', {}).get('suffix') or self.easyNameSuffix self.packageId = props.get('packageId', {}).get('value') or self.packageId self.packageIdSuffix = props.get('packageId', {}).get('suffix') or self.packageIdSuffix self.keystore = props.get('keystore', {}).get('filename') or self.keystore self.storepass = props.get('keystore', {}).get('storepass') or self.storepass self.alianame = props.get('keystore', {}).get('alianame') or self.alianame self.keypass = props.get('keystore', {}).get('keypass') or self.keypass self.owner = props.get('owner', {}).get('value') or self.owner self.packNum = props.get('num', {}).get('value') or self.packNum self.start = props.get('num', {}).get('start') or self.start self.start = int(self.start) self.packNum = int(self.packNum) + self.start self.appid = props.get('appid', {}).get('value') or self.appid self.gism_id = props.get('gism_id', {}).get('value') or self.gism_id self.gism_name = props.get('gism_name', {}).get('value') or self.gism_name self.gism_channel = props.get('gism_channel', {}).get('value') or self.gism_channel self.lg_ad_id = props.get('lg_ad_id', {}).get('value') or self.lg_ad_id self.lg_ad_name = props.get('lg_ad_name', {}).get('value') or self.lg_ad_name self.gactionId = props.get('gactionId', {}).get('value') or self.gactionId self.gappSecretKey = props.get('gappSecretKey', {}).get('value') or self.gappSecretKey self.baiduId = props.get('baiduId', {}).get('value') or self.baiduId self.baiduSecretKey = props.get('baiduSecretKey', {}).get('value') or self.baiduSecretKey self.lg_reyun_game_appkey = props.get('lg_reyun_game_appkey', {}).get('value') or self.lg_reyun_game_appkey self.lg_reyun_game_channelId = props.get('lg_reyun_game_channelId', {}).get( 'value') or self.lg_reyun_game_channelId self.lg_reyun_io_appkey = props.get('lg_reyun_io_appkey', {}).get('value') or self.lg_reyun_io_appkey self.lg_reyun_io_channelId = props.get('lg_reyun_io_channelId', {}).get('value') or self.lg_reyun_io_channelId self.eventType = props.get('eventType', {}).get('value') or self.eventType self.master_package = props.get('master_package', {}).get('value') or self.master_package def _init_path(self): bin_dir = os.path.join(self.MakeDir, 'bin') if os.path.exists(bin_dir): shutil.rmtree(bin_dir) os.makedirs(bin_dir) def check_props(self): if self.packNum < 1: return False, '打包数不能小于1' if not os.path.exists(self.master_package): return False, '缺少母包路径' if not os.path.exists(self.keystore): return False, '缺少keystore路径' if self.easyName: self.apkName = self.easyName return True, 'ok' def modify_channel(self, value): tempXML = '' with open(os.path.join(self.MakeDir, 'AndroidManifest.xml')) as f: for line in f: if line.find('leguChannel') > 0 and self.easyName != '': if self.easyNameSuffix == "1": line = '' % ( self.easyName, value) else: line = '' % (self.easyName) elif line.find('owner') > 0 and self.owner != '': print('owner====%s' % line) line = '' % (self.owner) elif line.find('package') > 0 and self.packageId != '': print('package====%s' % line) line = '' % ( self.packageId) elif line.find('appid') > 0 and self.appid != '': print('appid====%s' % line) line = '' % (self.appid) elif line.find('gism_id') > 0 and self.gism_id != '': print('gism_id====%s' % line) line = '' % (self.gism_id) elif line.find('gism_name') > 0 and self.gism_name != '': print('gism_name====%s' % line) line = '' % (self.gism_name) elif line.find('gism_channel') > 0 and self.gism_channel != '': print('gism_channel====%s' % line) line = '' % (self.gism_channel) elif line.find('lg_ad_id') > 0 and self.lg_ad_id != '': print('lg_ad_id====%s' % line) line = '' % (self.lg_ad_id) elif line.find('lg_ad_name') > 0 and self.lg_ad_name != '': print('lg_ad_name====%s' % line) line = '' % (self.lg_ad_name) elif line.find('gactionId') > 0 and self.gactionId != '': print('gactionId====%s' % line) line = '' % (self.gactionId) elif line.find('gappSecretKey') > 0 and self.gappSecretKey != '': print('gappSecretKey====%s' % line) line = '' % (self.gappSecretKey) elif line.find('baiduId') > 0 and self.baiduId != '': print('baiduId====%s' % line) line = '' % (self.baiduId) elif line.find('baiduSecretKey') > 0 and self.baiduSecretKey != '': print('baiduSecretKey====%s' % line) line = '' % (self.baiduSecretKey) elif line.find('lg_reyun_game_appkey') > 0 and self.lg_reyun_game_appkey != '': print('lg_reyun_game_appkey====%s' % line) line = '' % ( self.lg_reyun_game_appkey) elif line.find('lg_reyun_game_channelId') > 0 and self.lg_reyun_game_channelId != '': print('lg_reyun_game_channelId====%s' % line) line = '' % ( self.lg_reyun_game_channelId) elif line.find('lg_reyun_io_appkey') > 0 and self.lg_reyun_io_appkey != '': print('lg_reyun_io_appkey====%s' % line) line = '' % ( self.lg_reyun_io_appkey) elif line.find('lg_reyun_io_channelId') > 0 and self.lg_reyun_io_channelId != 0: print('lg_reyun_io_channelId====%s' % line) line = '' % ( self.lg_reyun_io_channelId) elif line.find('eventType') > 0 and self.eventType != '': print('eventType====%s' % line) line = '' % (self.eventType) tempXML += line with open(os.path.join(self.MakeDir, 'temp/AndroidManifest.xml'), 'w') as f: f.write(tempXML) unsignApk = os.path.join(self.MakeDir, f'bin/{self.apkName}_{value}_unsigned.apk') cmdPack = f'cd {self.MakeDir} && java -jar apktool.jar b temp -o {unsignApk}' os.system(cmdPack) signedjar = os.path.join(self.MakeDir, f'bin/{self.apkName}_{value}.apk') unsignedjar = os.path.join(self.MakeDir, f'bin/{self.apkName}_{value}_unsigned.apk') # cmd_sign = f'cd {os.path.join(self.MakeDir,"android-sdk/build-tools/26.0.1")} && ./apksigner sign --ks {self.keystore} --ks-key-alias {self.alianame} {signedjar}' cmd_sign = r'cd %s && java -jar apksigner.jar sign --ks %s --ks-key-alias %s --ks-pass pass:%s --key-pass pass:%s --out %s %s' % ( self.MakeDir, self.keystore, self.alianame, self.storepass, self.keypass, signedjar, unsignedjar) os.system(cmd_sign) os.remove(unsignedjar) def _unpack(self, pack_name): """ 解包 :param pack_name: :return: """ cmd = f'cd {self.MakeDir} && java -jar apktool.jar d -f -s {self.master_package} -o temp' os.system(cmd) androidmanifest_path = os.path.join(self.MakeDir, 'AndroidManifest.xml') if os.path.exists(androidmanifest_path): os.remove(androidmanifest_path) new_androidmanifest_path = os.path.join(self.MakeDir, 'temp/AndroidManifest.xml') shutil.copyfile(new_androidmanifest_path, androidmanifest_path) def _clear(self): path = os.path.join(self.MakeDir, 'temp') if os.path.exists(path): shutil.rmtree(path) path = os.path.join(self.MakeDir, 'AndroidManifest.xml') if os.path.exists(path): os.remove(path) def _make(self): """ 重新编译包 :return: """ for i in range(self.start, self.packNum): self.modify_channel(i) def run(self): try: self._init_props() self._init_path() is_ok, msg = self.check_props() if not is_ok: return False, msg self._unpack(self.master_package) self._make() self._clear() except Exception as e: return False, str(e) else: return True, 'ok'