Replace.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. # -*-coding:utf-8-*-
  2. import json
  3. import os,shutil
  4. import re
  5. import xml.etree.ElementTree as ET
  6. from V1 import Exec_Cmd_Utils, ChannelReplace, File, apk_utils
  7. from V1.PrintLog import printlog
  8. def replaceAM_Meta_data(am_path, key, value):
  9. lines = open(am_path).readlines()
  10. fp = open(am_path, 'w')
  11. for s in lines:
  12. if (s.find('android:name=\"' + key + '\"') != -1):
  13. printlog("Before replaceAM: %s" % s)
  14. s = re.sub('android:name=\"' + key + '\" android:value=\".*\"',
  15. 'android:name=\"' + key + '\" android:value=\"' + value + '\"', s)
  16. printlog("After replaceAM: %s" % s)
  17. fp.write(s)
  18. fp.close()
  19. pass
  20. def replaceAM_VersionCode(yml_path, value):
  21. if not os.path.exists(yml_path):
  22. return False, "yml is not exists in :%s" % yml_path
  23. replaceVersionCodeShell = "/bin/sed -i -E \"s/(versionCode: ).*/\\1'%s'/\" %s" % (value, yml_path)
  24. printlog("replace version code shell:%s" % replaceVersionCodeShell)
  25. ret, msg = Exec_Cmd_Utils.exeCommonCmd(replaceVersionCodeShell)
  26. if ret != 0:
  27. return False, msg
  28. return True, ""
  29. pass
  30. def replaceAM_VersionName(yml_path, value):
  31. if not os.path.exists(yml_path):
  32. return False, "yml is not exists in :%s" % yml_path
  33. replaceVersionNameShell = "/bin/sed -i -E \"s/(versionName:).*/\\1 %s/\" %s" % (value, yml_path)
  34. ret, msg = Exec_Cmd_Utils.exeCommonCmd(replaceVersionNameShell)
  35. if ret != 0:
  36. return False, msg
  37. return True, ""
  38. pass
  39. def replaceLP_AppVersion(localproperties_path, value):
  40. lines = open(localproperties_path).readlines()
  41. fp = open(localproperties_path, 'w')
  42. for s in lines:
  43. s = re.sub('app.version=.*', 'app.version=' + value, s)
  44. fp.write(s)
  45. fp.close()
  46. pass
  47. def replaceAM_ScreenOrientation(am_path, value):
  48. lines = open(am_path).readlines()
  49. fp = open(am_path, 'w')
  50. for s in lines:
  51. if (s.find("<!-- replace screenOrientation -->") != -1):
  52. s = re.sub('android:screenOrientation=\".*\"', 'android:screenOrientation=\"' + value + '\"', s)
  53. fp.write(s)
  54. fp.close()
  55. pass
  56. def replaceAssets_Param(assets_param_path, key, value):
  57. lines = open(assets_param_path).readlines()
  58. fp = open(assets_param_path, 'w')
  59. for s in lines:
  60. s = re.sub(key + '=.*', key + '=' + value, s)
  61. fp.write(s)
  62. fp.close()
  63. pass
  64. def replaceAM_Debuggable(am_path):
  65. lines = open(am_path).readlines()
  66. fp = open(am_path, "w")
  67. isReplaced = False
  68. for l in lines:
  69. if isReplaced == False and l.find("android:debuggable=") >= 0:
  70. l = re.sub("android:debuggable=\"true\"", "android:debuggable=\"false\"", l)
  71. fp.write(l)
  72. fp.close()
  73. pass
  74. def replaceAM_AllowBackup(am_path):
  75. lines = open(am_path).readlines()
  76. fp = open(am_path, "w")
  77. isReplaced = False
  78. for l in lines:
  79. if isReplaced == False and l.find("android:allowBackup=") >= 0:
  80. l = re.sub("android:allowBackup=\"true\"", "android:allowBackup=\"false\"", l)
  81. fp.write(l)
  82. fp.close()
  83. pass
  84. def replaceString_Appname(prj_path, key, value):
  85. if value == None or value == "":
  86. return
  87. # 命名空间,用于获取对应的值
  88. namespace = "http://schemas.android.com/apk/res/android"
  89. amTree = ET.parse("%s/AndroidManifest.xml" % prj_path)
  90. if amTree == None:
  91. return
  92. amRoot = amTree.getroot()
  93. applicationNode = amRoot.find("application")
  94. nameLabelAttrib = applicationNode.attrib.get("{%s}label" % namespace)[1:]
  95. nameLabelArr = nameLabelAttrib.split("/")
  96. nameLabelFile = nameLabelArr[0]
  97. nameLabel = nameLabelArr[1]
  98. modifyFileTree = ET.parse("%s/res/values/%ss.xml" % (prj_path, nameLabelFile))
  99. if modifyFileTree == None:
  100. return False, "cant not parse manifest.xml"
  101. modifyFileRoot = modifyFileTree.getroot()
  102. for child in modifyFileRoot.getchildren():
  103. if child.attrib["name"] == nameLabel:
  104. child.text = value
  105. modifyFileTree.write("%s/res/values/%ss.xml" % (prj_path, nameLabelFile), "utf-8", xml_declaration=True)
  106. return True, ""
  107. pass
  108. def replaceXmlValue(xml_path, name, value):
  109. tree = ET.parse(xml_path)
  110. if tree == None:
  111. return
  112. for child in list(tree.getroot()):
  113. if child.attrib["name"] == name:
  114. child.text = value
  115. tree.write(xml_path, "utf-8", xml_declaration=True)
  116. pass
  117. def replaceAM_package_name(temp_xml_path):
  118. printlog("begin replace AndroidManifest.xml key : package_name")
  119. manifestRoot = ET.parse(temp_xml_path).getroot()
  120. pkgName = manifestRoot.attrib["package"]
  121. replacePkgNameShell = '/bin/sed -i "1,\\$s/package_name/%s/g" %s' % (pkgName, temp_xml_path)
  122. printlog("replacePkgNameShell:%s" % replacePkgNameShell)
  123. os.system(replacePkgNameShell)
  124. pass
  125. def special_replace(sdk_name, prj_path, dir_split, key, value):
  126. # 获取特殊替换
  127. replaceFun = ChannelReplace.getSpecilReplace(sdk_name)
  128. if replaceFun is None:
  129. printlog("no such channel: %s" % sdk_name)
  130. else:
  131. printlog("begin special replace: %s" % sdk_name)
  132. replaceFun(prj_path, dir_split, key, value)
  133. pass
  134. def replaceYml_targetSdkVersion(apkYmlPath, code):
  135. lines = open(apkYmlPath).readlines()
  136. fp = open(apkYmlPath, 'w')
  137. for s in lines:
  138. if 'targetSdkVersion' in s:
  139. newTargetVersion = " targetSdkVersion: '%s'" % code + '\n'
  140. printlog("oldTargetVersion:%snewTargetVersion:%s" % (s, newTargetVersion))
  141. s = re.sub(s, newTargetVersion, s)
  142. fp.write(s)
  143. fp.close()
  144. pass
  145. def replaceYml_minSdkVersion(apkYmlPath):
  146. lines = open(apkYmlPath).readlines()
  147. fp = open(apkYmlPath, 'w')
  148. code = "19"
  149. for s in lines:
  150. if 'minSdkVersion' in s:
  151. versionCode = s.split(":")[1].replace("'", "").strip()
  152. if versionCode < code:
  153. newMinSdkVersion = " minSdkVersion: '%s'" % code + '\n'
  154. printlog("oldMinSdkVersion:%snewMinSdkVersion:%s" % (s, newMinSdkVersion))
  155. s = re.sub(s, newMinSdkVersion, s)
  156. fp.write(s)
  157. fp.close()
  158. pass
  159. def replaceJsonValue(path, root, key, value):
  160. if root == "":
  161. with open(path, 'r') as fp:
  162. jsonData = json.load(fp)
  163. jsonData[key] = value
  164. newJsonData = jsonData
  165. fp.close()
  166. with open(path, 'w') as fp:
  167. json.dump(newJsonData, fp)
  168. fp.close()
  169. else:
  170. with open(path, 'r') as fp:
  171. jsonData = json.load(fp)
  172. jsonData[root][key] = value
  173. newJsonData = jsonData
  174. fp.close()
  175. with open(path, 'w') as fp:
  176. json.dump(newJsonData, fp)
  177. fp.close()
  178. pass
  179. def replaceGameActivityLaunchAttribute(splash_activity, manifest_path):
  180. namespace = '{http://schemas.android.com/apk/res/android}'
  181. ET.register_namespace('android', "http://schemas.android.com/apk/res/android")
  182. tree = ET.parse(manifest_path)
  183. game_activity = ""
  184. activitys = tree.getroot().find("application").findall("activity")
  185. for activity in activitys:
  186. filters = activity.findall('intent-filter')
  187. for filter in filters:
  188. categorys = filter.findall('category')
  189. actions = filter.findall('action')
  190. for category in categorys:
  191. category_name = category.attrib[namespace + "name"]
  192. if category_name == "android.intent.category.LAUNCHER":
  193. action_name = activity.attrib[namespace + "name"]
  194. if action_name != splash_activity:
  195. game_activity = activity.attrib[namespace + "name"]
  196. printlog("delete :%s" % category_name)
  197. category.attrib[namespace + "name"] = "android.intent.category.DEFAULT"
  198. printlog("LAUNCHER replace DEFAULT :%s" % category.attrib[namespace + "name"])
  199. for action in actions:
  200. action_name = action.attrib[namespace + "name"]
  201. if action_name == "android.intent.action.MAIN":
  202. printlog("delete :%s" % action_name)
  203. filter.remove(action)
  204. tree.write(manifest_path, "UTF-8", xml_declaration=True, method='xml')
  205. return game_activity
  206. pass
  207. def getLauchActivityName(apkPath):
  208. sdkAM = "%s/AndroidManifest.xml" % apkPath
  209. tree = ET.parse(sdkAM)
  210. namespace = '{http://schemas.android.com/apk/res/android}'
  211. ET.register_namespace('android', "http://schemas.android.com/apk/res/android")
  212. activitys = tree.getroot().find("application").findall("activity");
  213. for activity in activitys:
  214. filters = activity.findall('intent-filter')
  215. for filter in filters:
  216. categorys = filter.findall('category')
  217. for category in categorys:
  218. categoryname = category.attrib[namespace + "name"]
  219. if (categoryname == "android.intent.category.LAUNCHER"):
  220. actname = activity.attrib[namespace + "name"]
  221. return actname
  222. pass
  223. def modifyRfileSmaliPath(channel, prj_path):
  224. printlog("start copy and modify R.smali-------")
  225. manifestRoot = ET.parse("%s/AndroidManifest.xml" % prj_path).getroot()
  226. pkgName = manifestRoot.attrib["package"]
  227. sdk_root_dir = apk_utils.getCutSdkRootHome()
  228. sdkRfilePath = "%s/%s/%s/extension/smali" % (sdk_root_dir, channel, channel)
  229. printlog("sdkRfilePath:%s" % sdkRfilePath)
  230. if os.path.exists(sdkRfilePath):
  231. printlog("begin copy R.smali to apkpath---------")
  232. apkPkgDir = ET.parse("%s/AndroidManifest.xml" % prj_path).getroot().attrib["package"].replace(".", "/")
  233. apkRfilePath = "%s/smali/%s" % (prj_path, apkPkgDir)
  234. if not os.path.exists(apkRfilePath):
  235. os.makedirs(apkRfilePath)
  236. os.system("/bin/cp -r %s/* %s" % (sdkRfilePath, apkRfilePath))
  237. for parent, dirnames, filenames in os.walk(apkRfilePath):
  238. printlog("replace apkRfile dirnames:%s" % dirnames)
  239. for filename in filenames:
  240. filepath = "'%s/%s'" % (apkRfilePath, filename)
  241. replacePkgShell = 'sed -i "s#%s#%s#g" %s' % ("package_path", apkPkgDir, filepath)
  242. os.system(replacePkgShell)
  243. replacePkgShell = 'sed -i "s#%s#%s#g" %s' % ("package_name", pkgName, filepath)
  244. os.system(replacePkgShell)
  245. printlog("end copy R.smali file -------------------------------")
  246. def createRFile2Sdk(pkgAbsoluteRpath, sdkAbsoluteRpath, pkgRpath, sdkRpath):
  247. if os.path.exists(sdkAbsoluteRpath):
  248. File.del_file(sdkAbsoluteRpath)
  249. else:
  250. os.mkdir(sdkAbsoluteRpath)
  251. File.copyAllFile(pkgAbsoluteRpath, sdkAbsoluteRpath)
  252. printlog("pkgRpath: -------------%s" % pkgRpath)
  253. printlog("sdkRpath: -------------%s" % sdkRpath)
  254. for root, dirs, files in os.walk(sdkAbsoluteRpath):
  255. for file in files:
  256. if "$" in file:
  257. file = file.split('$', 1)[0] + "\$" + file.split('$', 1)[1]
  258. replaceKeyword(pkgRpath, sdkRpath, os.path.join(root, file))
  259. def replaceKeyword(key, value, file):
  260. replaceShell = 'sed -i "s#%s#%s#g" %s' % (key, value, file)
  261. printlog("replaceShell:%s" % replaceShell)
  262. os.system(replaceShell)
  263. pass
  264. def add_point_smali(sdkPath, apkPath):
  265. printlog("--------------------------- start to merge resources ---------------------------")
  266. ret = 0
  267. # merge res
  268. # sdk_root_dir = apk_utils.getCutSdkRootHome() + "/" + os.path.basename(sdkPath)
  269. ret = ret | File.copyFiles("%s/res" % sdkPath, "%s/res" % apkPath)
  270. # copy lib and assets
  271. # 避免由于架构导致复制无用架构
  272. ret = ret | mergeLibs(sdkPath, apkPath)
  273. ret = ret | File.copyFiles("%s/assets" % sdkPath, "%s/assets" % apkPath)
  274. ret = ret | File.mergeDir("%s/smali" % sdkPath, "%s/smali" % apkPath)
  275. def mergeLibs(sdkPath, apkPath):
  276. printlog("--------------------------- start to merge lib --------------------------------")
  277. apkLib = "%s/lib" % apkPath
  278. sdkLib = "%s/lib" % sdkPath
  279. ret = 0
  280. if not os.path.exists(apkLib) and os.path.exists(sdkLib):
  281. shutil.copytree(sdkLib, apkLib)
  282. printlog("finished merging lib --------------------------------")
  283. return ret
  284. apkFiles = os.listdir(apkLib)
  285. sdkFiles = os.listdir(sdkLib)
  286. for cpFile in sdkFiles:
  287. if os.path.isfile(cpFile) == False and cpFile not in apkFiles:
  288. continue
  289. ret = ret | File.copyFiles("%s/lib/%s" % (sdkPath, cpFile), "%s/lib/%s" % (apkPath, cpFile))
  290. printlog("--------------------------- finished merging lib --------------------------------")
  291. return ret
  292. if __name__ == "__main__":
  293. # replaceAM_Meta_data("/sdk/develop/921sdk_cut/sdk_config/P0000001/anzhi/P0000004/AndroidManifest.xml", "QHOPENSDK_APPKEY", "20151219")
  294. # replaceLP_AppVersion(sys.argv[1], sys.argv[2])
  295. # replaceAssets_Param("/var/root/shortcuts/921sdkcut/tools/param.cnf", "SECRET_KEY", "20151226")
  296. # special_replace("wdj", "/sdk/develop/tools/outputs/mxd/package/0.01.150608/360/test", "/", "APPKEY_ID", "20151228")
  297. pass