# -*-coding:utf-8-*- import json import os,shutil import re import xml.etree.ElementTree as ET from V1 import Exec_Cmd_Utils, ChannelReplace, File, apk_utils from V1.PrintLog import printlog def replaceAM_Meta_data(am_path, key, value): lines = open(am_path).readlines() fp = open(am_path, 'w') for s in lines: if (s.find('android:name=\"' + key + '\"') != -1): printlog("Before replaceAM: %s" % s) s = re.sub('android:name=\"' + key + '\" android:value=\".*\"', 'android:name=\"' + key + '\" android:value=\"' + value + '\"', s) printlog("After replaceAM: %s" % s) fp.write(s) fp.close() pass def replaceAM_VersionCode(yml_path, value): if not os.path.exists(yml_path): return False, "yml is not exists in :%s" % yml_path replaceVersionCodeShell = "/bin/sed -i -E \"s/(versionCode: ).*/\\1'%s'/\" %s" % (value, yml_path) printlog("replace version code shell:%s" % replaceVersionCodeShell) ret, msg = Exec_Cmd_Utils.exeCommonCmd(replaceVersionCodeShell) if ret != 0: return False, msg return True, "" pass def replaceAM_VersionName(yml_path, value): if not os.path.exists(yml_path): return False, "yml is not exists in :%s" % yml_path replaceVersionNameShell = "/bin/sed -i -E \"s/(versionName:).*/\\1 %s/\" %s" % (value, yml_path) ret, msg = Exec_Cmd_Utils.exeCommonCmd(replaceVersionNameShell) if ret != 0: return False, msg return True, "" pass def replaceLP_AppVersion(localproperties_path, value): lines = open(localproperties_path).readlines() fp = open(localproperties_path, 'w') for s in lines: s = re.sub('app.version=.*', 'app.version=' + value, s) fp.write(s) fp.close() pass def replaceAM_ScreenOrientation(am_path, value): lines = open(am_path).readlines() fp = open(am_path, 'w') for s in lines: if (s.find("") != -1): s = re.sub('android:screenOrientation=\".*\"', 'android:screenOrientation=\"' + value + '\"', s) fp.write(s) fp.close() pass def replaceAssets_Param(assets_param_path, key, value): lines = open(assets_param_path).readlines() fp = open(assets_param_path, 'w') for s in lines: s = re.sub(key + '=.*', key + '=' + value, s) fp.write(s) fp.close() pass def replaceAM_Debuggable(am_path): lines = open(am_path).readlines() fp = open(am_path, "w") isReplaced = False for l in lines: if isReplaced == False and l.find("android:debuggable=") >= 0: l = re.sub("android:debuggable=\"true\"", "android:debuggable=\"false\"", l) fp.write(l) fp.close() pass def replaceAM_AllowBackup(am_path): lines = open(am_path).readlines() fp = open(am_path, "w") isReplaced = False for l in lines: if isReplaced == False and l.find("android:allowBackup=") >= 0: l = re.sub("android:allowBackup=\"true\"", "android:allowBackup=\"false\"", l) fp.write(l) fp.close() pass def replaceString_Appname(prj_path, key, value): if value == None or value == "": return # 命名空间,用于获取对应的值 namespace = "http://schemas.android.com/apk/res/android" amTree = ET.parse("%s/AndroidManifest.xml" % prj_path) if amTree == None: return amRoot = amTree.getroot() applicationNode = amRoot.find("application") nameLabelAttrib = applicationNode.attrib.get("{%s}label" % namespace)[1:] nameLabelArr = nameLabelAttrib.split("/") nameLabelFile = nameLabelArr[0] nameLabel = nameLabelArr[1] modifyFileTree = ET.parse("%s/res/values/%ss.xml" % (prj_path, nameLabelFile)) if modifyFileTree == None: return False, "cant not parse manifest.xml" modifyFileRoot = modifyFileTree.getroot() for child in modifyFileRoot.getchildren(): if child.attrib["name"] == nameLabel: child.text = value modifyFileTree.write("%s/res/values/%ss.xml" % (prj_path, nameLabelFile), "utf-8", xml_declaration=True) return True, "" pass def replaceXmlValue(xml_path, name, value): tree = ET.parse(xml_path) if tree == None: return for child in list(tree.getroot()): if child.attrib["name"] == name: child.text = value tree.write(xml_path, "utf-8", xml_declaration=True) pass def replaceAM_package_name(temp_xml_path): printlog("begin replace AndroidManifest.xml key : package_name") manifestRoot = ET.parse(temp_xml_path).getroot() pkgName = manifestRoot.attrib["package"] replacePkgNameShell = '/bin/sed -i "1,\\$s/package_name/%s/g" %s' % (pkgName, temp_xml_path) printlog("replacePkgNameShell:%s" % replacePkgNameShell) os.system(replacePkgNameShell) pass def special_replace(sdk_name, prj_path, dir_split, key, value): # 获取特殊替换 replaceFun = ChannelReplace.getSpecilReplace(sdk_name) if replaceFun is None: printlog("no such channel: %s" % sdk_name) else: printlog("begin special replace: %s" % sdk_name) replaceFun(prj_path, dir_split, key, value) pass def replaceYml_targetSdkVersion(apkYmlPath, code): lines = open(apkYmlPath).readlines() fp = open(apkYmlPath, 'w') for s in lines: if 'targetSdkVersion' in s: newTargetVersion = " targetSdkVersion: '%s'" % code + '\n' printlog("oldTargetVersion:%snewTargetVersion:%s" % (s, newTargetVersion)) s = re.sub(s, newTargetVersion, s) fp.write(s) fp.close() pass def replaceYml_minSdkVersion(apkYmlPath): lines = open(apkYmlPath).readlines() fp = open(apkYmlPath, 'w') code = "19" for s in lines: if 'minSdkVersion' in s: versionCode = s.split(":")[1].replace("'", "").strip() if versionCode < code: newMinSdkVersion = " minSdkVersion: '%s'" % code + '\n' printlog("oldMinSdkVersion:%snewMinSdkVersion:%s" % (s, newMinSdkVersion)) s = re.sub(s, newMinSdkVersion, s) fp.write(s) fp.close() pass def replaceJsonValue(path, root, key, value): if root == "": with open(path, 'r') as fp: jsonData = json.load(fp) jsonData[key] = value newJsonData = jsonData fp.close() with open(path, 'w') as fp: json.dump(newJsonData, fp) fp.close() else: with open(path, 'r') as fp: jsonData = json.load(fp) jsonData[root][key] = value newJsonData = jsonData fp.close() with open(path, 'w') as fp: json.dump(newJsonData, fp) fp.close() pass def replaceGameActivityLaunchAttribute(splash_activity, manifest_path): namespace = '{http://schemas.android.com/apk/res/android}' ET.register_namespace('android', "http://schemas.android.com/apk/res/android") tree = ET.parse(manifest_path) game_activity = "" activitys = tree.getroot().find("application").findall("activity") for activity in activitys: filters = activity.findall('intent-filter') for filter in filters: categorys = filter.findall('category') actions = filter.findall('action') for category in categorys: category_name = category.attrib[namespace + "name"] if category_name == "android.intent.category.LAUNCHER": action_name = activity.attrib[namespace + "name"] if action_name != splash_activity: game_activity = activity.attrib[namespace + "name"] printlog("delete :%s" % category_name) category.attrib[namespace + "name"] = "android.intent.category.DEFAULT" printlog("LAUNCHER replace DEFAULT :%s" % category.attrib[namespace + "name"]) for action in actions: action_name = action.attrib[namespace + "name"] if action_name == "android.intent.action.MAIN": printlog("delete :%s" % action_name) filter.remove(action) tree.write(manifest_path, "UTF-8", xml_declaration=True, method='xml') return game_activity pass def getLauchActivityName(apkPath): sdkAM = "%s/AndroidManifest.xml" % apkPath tree = ET.parse(sdkAM) namespace = '{http://schemas.android.com/apk/res/android}' ET.register_namespace('android', "http://schemas.android.com/apk/res/android") activitys = tree.getroot().find("application").findall("activity"); for activity in activitys: filters = activity.findall('intent-filter') for filter in filters: categorys = filter.findall('category') for category in categorys: categoryname = category.attrib[namespace + "name"] if (categoryname == "android.intent.category.LAUNCHER"): actname = activity.attrib[namespace + "name"] return actname pass def modifyRfileSmaliPath(channel, prj_path): printlog("start copy and modify R.smali-------") manifestRoot = ET.parse("%s/AndroidManifest.xml" % prj_path).getroot() pkgName = manifestRoot.attrib["package"] sdk_root_dir = apk_utils.getCutSdkRootHome() sdkRfilePath = "%s/%s/%s/extension/smali" % (sdk_root_dir, channel, channel) printlog("sdkRfilePath:%s" % sdkRfilePath) if os.path.exists(sdkRfilePath): printlog("begin copy R.smali to apkpath---------") apkPkgDir = ET.parse("%s/AndroidManifest.xml" % prj_path).getroot().attrib["package"].replace(".", "/") apkRfilePath = "%s/smali/%s" % (prj_path, apkPkgDir) if not os.path.exists(apkRfilePath): os.makedirs(apkRfilePath) os.system("/bin/cp -r %s/* %s" % (sdkRfilePath, apkRfilePath)) for parent, dirnames, filenames in os.walk(apkRfilePath): printlog("replace apkRfile dirnames:%s" % dirnames) for filename in filenames: filepath = "'%s/%s'" % (apkRfilePath, filename) replacePkgShell = 'sed -i "s#%s#%s#g" %s' % ("package_path", apkPkgDir, filepath) os.system(replacePkgShell) replacePkgShell = 'sed -i "s#%s#%s#g" %s' % ("package_name", pkgName, filepath) os.system(replacePkgShell) printlog("end copy R.smali file -------------------------------") def createRFile2Sdk(pkgAbsoluteRpath, sdkAbsoluteRpath, pkgRpath, sdkRpath): if os.path.exists(sdkAbsoluteRpath): File.del_file(sdkAbsoluteRpath) else: os.mkdir(sdkAbsoluteRpath) File.copyAllFile(pkgAbsoluteRpath, sdkAbsoluteRpath) printlog("pkgRpath: -------------%s" % pkgRpath) printlog("sdkRpath: -------------%s" % sdkRpath) for root, dirs, files in os.walk(sdkAbsoluteRpath): for file in files: if "$" in file: file = file.split('$', 1)[0] + "\$" + file.split('$', 1)[1] replaceKeyword(pkgRpath, sdkRpath, os.path.join(root, file)) def replaceKeyword(key, value, file): replaceShell = 'sed -i "s#%s#%s#g" %s' % (key, value, file) printlog("replaceShell:%s" % replaceShell) os.system(replaceShell) pass def add_point_smali(sdkPath, apkPath): printlog("--------------------------- start to merge resources ---------------------------") ret = 0 # merge res # sdk_root_dir = apk_utils.getCutSdkRootHome() + "/" + os.path.basename(sdkPath) ret = ret | File.copyFiles("%s/res" % sdkPath, "%s/res" % apkPath) # copy lib and assets # 避免由于架构导致复制无用架构 ret = ret | mergeLibs(sdkPath, apkPath) ret = ret | File.copyFiles("%s/assets" % sdkPath, "%s/assets" % apkPath) ret = ret | File.mergeDir("%s/smali" % sdkPath, "%s/smali" % apkPath) def mergeLibs(sdkPath, apkPath): printlog("--------------------------- start to merge lib --------------------------------") apkLib = "%s/lib" % apkPath sdkLib = "%s/lib" % sdkPath ret = 0 if not os.path.exists(apkLib) and os.path.exists(sdkLib): shutil.copytree(sdkLib, apkLib) printlog("finished merging lib --------------------------------") return ret apkFiles = os.listdir(apkLib) sdkFiles = os.listdir(sdkLib) for cpFile in sdkFiles: if os.path.isfile(cpFile) == False and cpFile not in apkFiles: continue ret = ret | File.copyFiles("%s/lib/%s" % (sdkPath, cpFile), "%s/lib/%s" % (apkPath, cpFile)) printlog("--------------------------- finished merging lib --------------------------------") return ret if __name__ == "__main__": # replaceAM_Meta_data("/sdk/develop/921sdk_cut/sdk_config/P0000001/anzhi/P0000004/AndroidManifest.xml", "QHOPENSDK_APPKEY", "20151219") # replaceLP_AppVersion(sys.argv[1], sys.argv[2]) # replaceAssets_Param("/var/root/shortcuts/921sdkcut/tools/param.cnf", "SECRET_KEY", "20151226") # special_replace("wdj", "/sdk/develop/tools/outputs/mxd/package/0.01.150608/360/test", "/", "APPKEY_ID", "20151228") pass