def convert_verses(self, verses_dir: Path, remote_dir: Path): """ Convert verse wav file and copy to remote directory """ for f in verses_dir.iterdir(): if f.is_dir(): continue mp3_exists = check_file_exists(f, remote_dir, 'mp3') cue_exists = check_file_exists(f, remote_dir, 'cue') if mp3_exists or cue_exists: logging.debug('Files exist. Skipping...') continue logging.debug(f'Converting file: {f}') convert_to_mp3(f, self.verbose) # Copy converted verse files mp3_file = f.with_suffix('.mp3') if mp3_file.exists(): logging.debug( f'Copying verse mp3 {mp3_file} into {remote_dir}' ) m_file = copy_file(mp3_file, remote_dir) self.resources_created.append(str(rel_path(m_file, self.__ftp_dir))) cue_file = f.with_suffix('.cue') if cue_file.exists(): logging.debug( f'Copying verse cue {mp3_file} into {remote_dir}' ) c_file = copy_file(cue_file, remote_dir) self.resources_created.append(str(rel_path(c_file, self.__ftp_dir)))
def convert_chapter(self, chapter_file: Path, remote_dir: Path, grouping: str): """ Convert chapter wav file and copy to remote directory""" # Check if filed exist remotely chapter_mp3_exists = check_file_exists(chapter_file, remote_dir, 'mp3', grouping) chapter_cue_exists = check_file_exists(chapter_file, remote_dir, 'cue', grouping) if not chapter_mp3_exists and not chapter_cue_exists: logging.debug(f'Converting chapter: {chapter_file}') convert_to_mp3(chapter_file, self.verbose) # Copy converted chapter files mp3_file = chapter_file.with_suffix('.mp3') if mp3_file.exists(): logging.debug( f'Copying chapter mp3 {mp3_file} into {remote_dir}' ) m_file = copy_file(mp3_file, remote_dir, grouping) self.resources_created.append(str(rel_path(m_file, self.__ftp_dir))) cue_file = chapter_file.with_suffix('.cue') if cue_file.exists(): logging.debug( f'Copying chapter cue {cue_file} into {remote_dir}' ) c_file = copy_file(cue_file, remote_dir, grouping) self.resources_created.append(str(rel_path(c_file, self.__ftp_dir))) else: logging.debug('Files exist. Skipping...')
def copySplashToUnityResFolder(workDir, channel, decompileDir): splashPath = file_utils.getSplashPath() resPath = workDir + "/sdk/" + channel['name'] + "/splash/" + channel['splash'] + "/%s/u8_splash.png" resTargetPath = decompileDir + "/assets/bin/Data/splash.png" paths = ['drawable', 'drawable-hdpi', 'drawable-ldpi', 'drawable-mdpi', 'drawable-xhdpi'] bFound = False for path in paths: imgPath = resPath % path if os.path.exists(imgPath): resPath = imgPath bFound = True break if not bFound: log_utils.error("the u8_splash is not found.path:%s", resPath) return 1 if not os.path.exists(resTargetPath): log_utils.error("the unity splash is not exists. path:%s", resTargetPath) return 1 file_utils.copy_file(resPath, resTargetPath) return 0
def merge_jni(self, targetLibs): if not os.path.exists(self.aarDir): log_utils.warning("the aar is not unarchived:" + self.aarFile) return False jniPath = os.path.join(self.aarDir, "jni") if not os.path.exists(jniPath): log_utils.debug( "aar jni merge completed. there is no jni folder in " + self.aarFile) return True for f in os.listdir(jniPath): cpuPath = os.path.join(jniPath, f) for c in os.listdir(cpuPath): cpuTargetPath = os.path.join(targetLibs, f, c) if os.path.exists(cpuTargetPath): log_utils.error("jni in aar " + self.aarFile + " merge failed. " + c + " already exists in " + targetLibs) return False file_utils.copy_file(os.path.join(cpuPath, c), cpuTargetPath) log_utils.debug(f + "/" + c + " in aar " + self.aarFile + " copied to " + targetLibs) return True
def handleWXPayActivity(channel, decompileDir, packageName, className, oldPackageName): sdkDir = decompileDir + '/../sdk/' + channel['sdk'] if not os.path.exists(sdkDir): file_utils.printF("The sdk temp folder is not exists. path:" + sdkDir) return 1 extraFilesPath = sdkDir + '/extraFiles' relatedJar = os.path.join(extraFilesPath, 'vivoUnionSDK.jar') relatedJar2 = os.path.join(extraFilesPath, 'libammsdk.jar') WXPayEntryActivity = os.path.join(extraFilesPath, className + '.java') file_utils.modifyFileContent(WXPayEntryActivity, oldPackageName, packageName + ".wxapi") splitdot = ';' if platform.system() == 'Darwin': splitdot = ':' cmd = '"%sjavac" -source 1.7 -target 1.7 "%s" -classpath "%s"%s"%s"%s"%s"' % ( file_utils.getJavaBinDir(), WXPayEntryActivity, relatedJar, splitdot, relatedJar2, splitdot, file_utils.getFullToolPath('android.jar')) ret = file_utils.execFormatCmd(cmd) if ret: return 1 packageDir = packageName.replace('.', '/') srcDir = sdkDir + '/tempDex' classDir = srcDir + '/' + packageDir + '/wxapi' if not os.path.exists(classDir): os.makedirs(classDir) sourceClassFilePath = os.path.join(extraFilesPath, className + '.class') targetClassFilePath = classDir + '/' + className + '.class' file_utils.copy_file(sourceClassFilePath, targetClassFilePath) targetDexPath = os.path.join(sdkDir, className + '.dex') dxTool = file_utils.getFullToolPath("/lib/dx.jar") cmd = file_utils.getJavaCMD( ) + ' -jar -Xmx512m -Xms512m "%s" --dex --output="%s" "%s"' % ( dxTool, targetDexPath, srcDir) ret = file_utils.execFormatCmd(cmd) if ret: return 1 ret = sdk_helper.dex2smali(targetDexPath, decompileDir + '/smali', "baksmali.jar") if ret: return 1 return 0
def generateNewChannelApk(sourceApkFile, empty_file, channelID): file_utils.printF("Now to generate channel %s", channelID) targetApk = file_utils.getFullPath("channels/u8-"+channelID+".apk") file_utils.copy_file(sourceApkFile, targetApk) zipped = zipfile.ZipFile(targetApk, 'a', zipfile.ZIP_DEFLATED) emptyChannelFile = "META-INF/u8channel_{channel}".format(channel=channelID) zipped.write(empty_file, emptyChannelFile) zipped.close()
def generateNewChannelApk(sourceApkFile, empty_file, channelID): file_utils.printF("Now to generate channel %s", channelID) targetApk = file_utils.getFullPath("channels/u8-" + channelID + ".apk") file_utils.copy_file(sourceApkFile, targetApk) zipped = zipfile.ZipFile(targetApk, 'a', zipfile.ZIP_DEFLATED) emptyChannelFile = "META-INF/u8channel_{channel}".format(channel=channelID) zipped.write(empty_file, emptyChannelFile) zipped.close()
def addSplashScreen(workDir, channel, decompileDir): """ if the splash attrib is not zero ,then set the splash activity if the splash_copy_to_unity attrib is set, then copy the splash img to unity res fold ,replace the default splash.png. """ if channel['splash'] =='0': return 0 if channel['splash_copy_to_unity'] == '1': return copySplashToUnityResFolder(workDir, channel, decompileDir) splashPath = file_utils.getSplashPath() smaliPath = splashPath + "/smali" smaliTargetPath = decompileDir + "/smali" copyResToApk(smaliPath, smaliTargetPath) splashLayoutPath = splashPath + "/u8_splash.xml" splashTargetPath = decompileDir + "/res/layout/u8_splash.xml" file_utils.copy_file(splashLayoutPath, splashTargetPath) resPath = workDir + "/sdk/" + channel['name'] + "/splash/" + channel['splash'] resTargetPath = decompileDir + "/res" copyResToApk(resPath, resTargetPath) #remove original launcher activity of the game activityName = removeStartActivity(decompileDir) #append the launcher activity with the splash activity appendSplashActivity(decompileDir, channel['splash']) splashActivityPath = smaliTargetPath + "/com/u8/sdk/SplashActivity.smali" f = open(splashActivityPath, 'r+') content = str(f.read()) f.close() replaceTxt = '{U8SDK_Game_Activity}' idx = content.find(replaceTxt) if idx == -1: log_utils.error("modify splash file failed.the {U8SDK_Game_Activity} not found in SplashActivity.smali") return 1 content = content[:idx] + activityName + content[(idx + len(replaceTxt)):] f2 = open(splashActivityPath, 'w') f2.write(content) f2.close() log_utils.info("modify splash file success.") return 0
def copy_mobi(lib_dir, dest_dir, make_author_dir=True): for src, author, book in find_book_and_author(lib_dir): if make_author_dir: dst = os.path.abspath(os.path.join(dest_dir, author, book)) try: os.makedirs(os.path.split(dst)[0]) except OSError: pass else: dst = os.path.abspath(os.path.join(dest_dir, book)) copy_file(src, dst)
def compileWXEntryActivity(channel, decompileDir, packageName): sdkDir = decompileDir + '/../sdk/' + channel['sdk'] if not os.path.exists(sdkDir): file_utils.printF("The sdk temp folder is not exists. path:"+sdkDir) return 1 extraFilesPath = sdkDir + '/extraFiles' relatedJar = os.path.join(extraFilesPath, 'MSDK_Android.jar') WXPayEntryActivity = os.path.join(extraFilesPath, 'WXEntryActivity.java') file_utils.modifyFileContent(WXPayEntryActivity, 'com.example.wegame.wxapi', packageName+".wxapi") splitdot = ';' if platform.system() == 'Darwin': splitdot = ':' cmd = '"%sjavac" -source 1.7 -target 1.7 "%s" -classpath "%s"%s"%s"' % (file_utils.getJavaBinDir(), WXPayEntryActivity, relatedJar, splitdot, file_utils.getFullToolPath('android.jar')) ret = file_utils.execFormatCmd(cmd) if ret: return 1 packageDir = packageName.replace('.', '/') srcDir = sdkDir + '/tempDex' classDir = srcDir + '/' + packageDir + '/wxapi' if not os.path.exists(classDir): os.makedirs(classDir) sourceClassFilePath = os.path.join(extraFilesPath, 'WXEntryActivity.class') targetClassFilePath = classDir + '/WXEntryActivity.class' file_utils.copy_file(sourceClassFilePath, targetClassFilePath) targetDexPath = os.path.join(sdkDir, 'WXEntryActivity.dex') dxTool = file_utils.getFullToolPath("/lib/dx.jar") cmd = file_utils.getJavaCMD() + ' -jar -Xmx512m -Xms512m "%s" --dex --output="%s" "%s"' % (dxTool, targetDexPath, srcDir) ret = file_utils.execFormatCmd(cmd) if ret: return 1 ret = apk_utils.dex2smali(targetDexPath, decompileDir+'/smali', "baksmali.jar") if ret: return 1
def flush(self): """flush all blocks to files""" # remove all [remove marked] blocks from origin file removedBlocks = self.get_removed_blocks() for f in removedBlocks: removedLst = removedBlocks[f] if len(removedLst) == 1 and removedLst[0].is_single_file(): log_utils.debug("remove duplicated file %s", f) file_utils.del_file_folder(f) else: ValueResourceParser.remove_blocks(f, removedLst) # merge styleable attrs. styleableBlocks = self.get_styleable_merged_blocks() for f in styleableBlocks: mergedLst = styleableBlocks[f] ValueResourceParser.merge_styleable_blocks(mergedLst) for b in mergedLst: if b.is_merged(): b.mark_removed() ValueResourceParser.remove_blocks(b.path(), [b]) # copy added files addedBlocks = self.get_added_blocks() for f in addedBlocks: addedLst = addedBlocks[f] targetFile = os.path.join(self.filePath, os.path.basename(f)) if os.path.exists(targetFile): log_utils.error("resource flush error. file already exists:%s", targetFile) continue file_utils.copy_file(f, targetFile) # log_utils.debug("copy a new file from %s to %s", f, targetFile) # merge blocks from files with same name. mergedBlocks = self.get_merged_blocks() for f in mergedBlocks: mergedLst = mergedBlocks[f] ValueResourceParser.merge_val_files( f, os.path.join(self.filePath, os.path.basename(f)))
def checkApkForU8SDK(workDir, decompileDir): """ 检查母包中接入U8SDK抽象层是否正确 不正确,则自动修正 """ ret = 0 log_utils.info("now to check the u8.apk is correct?") manifestFile = decompileDir + "/AndroidManifest.xml" manifestFile = file_utils.getFullPath(manifestFile) ET.register_namespace('android', androidNS) tree = ET.parse(manifestFile) root = tree.getroot() key = '{'+androidNS+'}name' applicationNode = root.find('application') name = applicationNode.get(key) if not name or name != "com.u8.sdk.U8Application": log_utils.error("the android:name in application element must be 'com.u8.sdk.U8Application'. now change it to com.u8.sdk.U8Application, but maybe something will be wrong .") applicationNode.set(key, 'com.u8.sdk.U8Application') tree.write(manifestFile, 'UTF-8') smaliName = file_utils.getFullPath(decompileDir + "/smali/com/u8/sdk/U8SDK.smali") if not os.path.exists(smaliName): log_utils.error("the u8sdk2.jar is not packaged to the u8.apk. now merge it. but maybe something will be wrong .") u8sdkJarPath = file_utils.getFullPath('config/local/u8sdk2.jar') if not os.path.exists(u8sdkJarPath): log_utils.error("the u8sdk2.jar is not in config/local path. correct failed") return 1 targetPath = file_utils.getFullPath(workDir + "/local") if not os.path.exists(targetPath): os.makedirs(targetPath) file_utils.copy_file(u8sdkJarPath, targetPath+"/u8sdk2.jar") jar2dex(targetPath, targetPath) smaliPath = file_utils.getFullPath(decompileDir + "/smali") ret = dex2smali(targetPath + '/classes.dex', smaliPath) # if not ret: # ret = mergeJar(workDir, decompileDir) log_utils.info("check u8.apk successfully") return ret
def mergeJar(workDir, decompileDir): u8sdkJarPath = file_utils.getFullPath('config/local/u8sdkanelib.jar') if not os.path.exists(u8sdkJarPath): log_utils.error("the file is not exists:"+u8sdkJarPath) return 1 targetPath = file_utils.getFullPath(workDir + "/ane") if not os.path.exists(targetPath): os.makedirs(targetPath) file_utils.copy_file(u8sdkJarPath, targetPath+"/u8sdkanelib.jar") jar2dex(targetPath, targetPath) smaliPath = file_utils.getFullPath(decompileDir + "/smali") return dex2smali(targetPath + '/classes.dex', smaliPath)
def merge_jars(self, targetLibs): if not os.path.exists(self.aarDir): log_utils.warning("the aar is not unarchived:" + self.aarFile) return False classesPath = os.path.join(self.aarDir, "classes.jar") if os.path.exists(classesPath): targetPath = os.path.join(targetLibs, self.aarName + ".jar") file_utils.copy_file(classesPath, targetPath) log_utils.debug("classes.jar in aar " + self.aarFile + " copied to " + targetPath) libsPath = os.path.join(self.aarDir, "libs") if not os.path.exists(libsPath): log_utils.debug( "aar libs merge completed. there is no libs folder in " + self.aarFile) return True for f in os.listdir(libsPath): if f.endswith(".jar"): targetName = self.aarName + "." + f targetName = targetName.replace(" ", "") # //remove spaces in name targetPath = os.path.join( targetLibs, targetName ) # rename jar in aar libs folder with aar name prefix. if os.path.exists(targetPath): log_utils.error("libs in aar " + self.aarFile + " merge failed. " + f + " already exists in " + targetLibs) return False file_utils.copy_file(os.path.join(libsPath, f), targetPath) log_utils.debug(f + " in aar " + self.aarFile + " copied to " + targetLibs) return True
def convert_verse(self, verse_file: Path, remote_dir: Path, grouping: str): """ Convert verse wav file and copy to remote directory """ logging.debug(f'Converting verse: {verse_file}') convert_to_mp3(verse_file, self.verbose) # Copy converted verse file (mp3 and cue) mp3_file = verse_file.with_suffix('.mp3') logging.debug(f'Copying verse mp3 {mp3_file} into {remote_dir}') if mp3_file.exists(): m_file = copy_file(mp3_file, remote_dir, grouping) self.resources_created.append(str(rel_path(m_file, self.__ftp_dir))) cue_file = verse_file.with_suffix('.cue') logging.debug(f'Copying verse cue {cue_file} into {remote_dir}') if cue_file.exists(): c_file = copy_file(cue_file, remote_dir, grouping) self.resources_created.append(str(rel_path(c_file, self.__ftp_dir)))
def data_excel_statistic_info(file_name, init_file_dir=origin_file_url, work_file_dir=working_file_url): """ get the simple statistic info for one data file, the info will be stored under statistic_data_file_url with the same file name with file_name, every sheet is one column's info with sheet name be the column's name. :param work_file_dir: :param init_file_dir: :param file_name: the file name of the excel, e.g. data.xls :return: """ init_file = init_file_dir + file_name if work_file_dir is not None: work_file = work_file_dir + file_name file_utils.copy_file(init_file, work_file) print('copy file: ' + file_name) print(init_file) data = file_utils.read_file_to_df(init_file_dir, file_name) writer = pandas.ExcelWriter( unicode( file_utils.check_file_url(statistic_data_file_url) + file_name)) for column in data.columns: described_data = data[column].describe() print(described_data) # to name a sheet, there's some rules need to adopt m = openpyxl_child.INVALID_TITLE_REGEX.search(column) if m: for item in m.group(): scolumn = column.encode('utf-8').replace( item.encode('utf-8'), '-') column = scolumn if len(unicode(column)) > 10: column = unicode(column)[0:10] file_utils.write_file_without_save(described_data, writer, sheet_name=column, index=True) writer.save()
def merge_val_files(cls, filePath, targetFilePath): # log_utils.debug("merge val files:" + filePath + " and " + targetFilePath) if not os.path.exists(targetFilePath): log_utils.warning("merge_val_files. but target file not exists:" + targetFilePath + ". just copy " + filePath) file_utils.copy_file(filePath, targetFilePath) return oldTree = ET.parse(filePath) oldRoot = oldTree.getroot() tree = ET.parse(targetFilePath) root = tree.getroot() for node in list(oldRoot): log_utils.debug("merge res node %s from %s to %s", node.attrib.get('name'), filePath, targetFilePath) root.append(node) tree.write(targetFilePath, "UTF-8")
def generate_icon_with_mark(targetDir, iconPath, maskPath): if not os.path.exists(iconPath): log_utils.error("icon path is not exists:" + iconPath) return 1 if os.path.exists(targetDir): file_utils.del_file_folder(targetDir) if not os.path.exists(targetDir): os.makedirs(targetDir) log_utils.debug("begin generate_icon_with_mark:" + iconPath) baseName = os.path.basename(iconPath) targetIconPath = os.path.join(targetDir, baseName) file_utils.copy_file(iconPath, targetIconPath) if os.path.exists(maskPath): rlImg = Image.open(targetIconPath) maskTypes = [ "left-top.png", "left-bottom.png", "right-top.png", "right-bottom.png" ] for maskType in maskTypes: rPath = os.path.join(maskPath, maskType) log_utils.debug("handle mask:" + rPath) if os.path.exists(rPath): markIcon = Image.open(rPath) maskedIcon = image_utils.append_icon_mark( rlImg, markIcon, (0, 0)) maskedIcon.save(os.path.join(targetDir, maskType), "PNG") return 0
def generate_scaled_cached_splash(targetDir, splashPath, scaleSize): if not os.path.exists(splashPath): log_utils.error("splash path is not exists:" + splashPath) return 1 if os.path.exists(targetDir): file_utils.del_file_folder(targetDir) if not os.path.exists(targetDir): os.makedirs(targetDir) baseName = os.path.basename(splashPath) targetSplashPath = os.path.join(targetDir, baseName) file_utils.copy_file(splashPath, targetSplashPath) rlImg = Image.open(targetSplashPath) scaledImg = rlImg.resize(scaleSize, Image.ANTIALIAS) scaledImg.save(targetSplashPath, "PNG") return 0
def merge_files(src, dest): if not os.path.exists(src): log_utils.warning("the path is not exists.path:%s", src) return if os.path.exists(dest) and os.path.isfile(dest): log_utils.warning("assets merge igored file:" + src + " already exists in " + dest) return if os.path.isfile(src): file_utils.copy_file(src, dest) return for f in os.listdir(src): sourcefile = os.path.join(src, f) targetfile = os.path.join(dest, f) if os.path.isfile(sourcefile): file_utils.copy_file(sourcefile, targetfile) else: merge_files(sourcefile, targetfile)
def copy_built_files(entries): file_utils.remove_dir(__Packing_Dir) for entry in entries: entry_type = entry["entry_type"] if entry_type["type"] == "java": class_filepath = entry["path"].replace(".java", ".class") built_file = os.path.join(entry["entry_type"]["targetDir"], class_filepath); copy_to = os.path.join(__Packing_Dir, "webroot\\WEB-INF\\classes\\", class_filepath) file_utils.copy_file(built_file, copy_to) elif entry_type["type"] == "jsp": built_file = os.path.join(entry["entry_type"]["targetDir"], entry["path"]); copy_to = os.path.join(__Packing_Dir, "webroot\\jsp\\", entry["path"]) file_utils.copy_file(built_file, copy_to) elif entry_type["type"] == "js": built_file = os.path.join(entry["entry_type"]["targetDir"], entry["path"]); copy_to = os.path.join(__Packing_Dir, "webroot\\js\\", entry["path"]) file_utils.copy_file(built_file, copy_to)
if package_dic.has_key('target_apk') and len( package_dic['target_apk']) > 0: target_apk_path = package_dic['target_apk'] else: print '{"status":0}' if package_dic.has_key('jy_ad') and len(package_dic['jy_ad']) > 0: jy_ad = package_dic['jy_ad'] else: print '{"status":0}' if os.path.exists(target_apk_path + '/' + jy_ad): file_utils.del_file_folder(target_apk_path + '/' + jy_ad) #创建目标临时文件 temp_apk = target_apk_path + '/' + jy_ad + '/' + jy_ad + '.apk' file_utils.copy_file(source_apk_path, temp_apk) #获取配置文件 ret, cmd, result = unrar(source_apk_path, 'assets/jy_public_config.json', target_apk_path + '/' + jy_ad) json_path = target_apk_path + '/' + jy_ad + '/jy_public_config.json' #修改配置参数 m_json_data = get_new_json(json_path, 'JY_AD', jy_ad) rewrite_json_file(json_path, m_json_data) #将配置文件当道新的assets目录下并删除原有配置文件 new_assets = target_apk_path + '/' + jy_ad + '/assets' file_utils.copy_file(json_path, new_assets + '/' + 'jy_public_config.json') file_utils.del_file_folder(json_path)
def create_tr_file(self, dic: str, files: List[Path]): """ Create tr file and copy it to the remote directory""" parts = json.loads(dic) lang = parts['lang'] resource = parts['resource'] book = parts['book'] chapter = parts['chapter'] if 'chapter' in parts else None media = parts['media'] quality = parts['quality'] grouping = parts['grouping'] root_dir = self.__temp_dir.joinpath('root') target_dir = root_dir.joinpath(lang, resource, book) if chapter is not None: remote_dir = self.__ftp_dir.joinpath(lang, resource, book, chapter, "CONTENTS") else: remote_dir = self.__ftp_dir.joinpath(lang, resource, book, "CONTENTS") for file in files: target_chapter = chapter if target_chapter is None: match = re.search(r'_c([0-9]+)_v[0-9]+', file.name) if not match: raise Exception( 'Could not define chapter from the file name.') target_chapter = match.group(1) target_chapter_dir = target_dir.joinpath( self.zero_pad_chapter(target_chapter, book)) target_chapter_dir.mkdir(parents=True, exist_ok=True) target_file = target_chapter_dir.joinpath(file.name) # Copy source file to temp dir logging.debug(f'Copying file {file} to {target_file}') target_file.write_bytes(file.read_bytes()) # Create TR file logging.debug('Creating TR file') create_tr(root_dir, self.verbose) tr = self.__temp_dir.joinpath('root.tr') if chapter is not None: new_tr = Path(tr.parent, f'{lang}_{resource}_{book}_c{chapter}.tr') else: new_tr = Path(tr.parent, f'{lang}_{resource}_{book}.tr') tr.rename(new_tr) # Copy tr file to remote dir logging.debug(f'Copying {new_tr} to {remote_dir}') t_file = copy_file(new_tr, remote_dir, grouping, quality, media) self.resources_created.append(str(rel_path(t_file, self.__ftp_dir))) rm_tree(root_dir) new_tr.unlink()
def compileJava2Smali(channel, decompileDir, packageName, className, dependencyLibs): sdkDir = decompileDir + '/../sdk/' + channel['sdk'] if not os.path.exists(sdkDir): file_utils.printF("The sdk temp folder is not exists. path:" + sdkDir) return 1 extraFilesPath = sdkDir + '/extraFiles' # relatedJar = os.path.join(extraFilesPath, 'vivoUnionSDK.jar') # relatedJar2 = os.path.join(extraFilesPath, 'libammsdk.jar') if not os.path.exists(extraFilesPath): log_utils.error("compileJava2Smali failed. please put java file and related jars in extraFiles folder") return 1 javaFile = os.path.join(extraFilesPath, className + '.java') replaceJavaPackage(javaFile, packageName) splitdot = ';' if platform.system() == 'Darwin' or platform.system() == 'Linux': splitdot = ':' cmd = '"%sjavac" -source 1.7 -target 1.7 "%s" -classpath ' % (file_utils.getJavaBinDir(), javaFile) for lib in dependencyLibs: cmd = cmd + '"' + os.path.join(extraFilesPath, lib) + '"' + splitdot cmd = cmd + '"' + file_utils.getFullToolPath('android.jar') + '"' ret = file_utils.execFormatCmd(cmd) if ret: return 1 packageDir = packageName.replace('.', '/') srcDir = sdkDir + '/tempDex' classDir = srcDir + '/' + packageDir if not os.path.exists(classDir): os.makedirs(classDir) classFiles = file_utils.list_files_with_ext(extraFilesPath, [], '.class') for cf in classFiles: targetClassFilePath = os.path.join(classDir, os.path.basename(cf)) file_utils.copy_file(cf, targetClassFilePath) targetDexPath = os.path.join(sdkDir, className + '.dex') dxTool = file_utils.getFullToolPath("/lib/dx.jar") cmd = file_utils.getJavaCMD() + ' -jar -Xmx512m -Xms512m "%s" --dex --output="%s" "%s"' % ( dxTool, targetDexPath, srcDir) ret = file_utils.execFormatCmd(cmd) if ret: return 1 ret = dex2smali(targetDexPath, decompileDir + '/smali', "baksmali.jar") if ret: return 1 return 0
def gather_epub(lib_dir=cfg['CALIBRE_LIBRARY'], target_dir='.'): for src in ifind_files(lib_dir, pattern='*.epub'): dst = os.path.abspath(os.path.join(target_dir, os.path.split(src)[0])) copy_file(src, dst)
def generateWXEntryActivity(channel, pluginInfo, decompileDir, packageName): sdkDir = decompileDir + '/../plugins/' + pluginInfo['name'] if not os.path.exists(sdkDir): file_utils.printF("The plugin temp folder is not exists. path:" + sdkDir) return 1 extraFilesPath = sdkDir + '/extraFiles' relatedJar = os.path.join(extraFilesPath, 'ShareSDK-Wechat-Core.jar') WXPayEntryActivity = os.path.join(extraFilesPath, 'WXEntryActivity.java') file_utils.modifyFileContent(WXPayEntryActivity, 'cn.sharesdk.socialization.sample.wxapi', packageName + ".wxapi") splitdot = ';' if platform.system() == 'Darwin': splitdot = ':' cmd = '"%sjavac" -source 1.7 -target 1.7 "%s" -classpath "%s"%s"%s"' % ( file_utils.getJavaBinDir(), WXPayEntryActivity, relatedJar, splitdot, file_utils.getFullToolPath('android.jar')) ret = file_utils.execFormatCmd(cmd) if ret: return 1 packageDir = packageName.replace('.', '/') srcDir = sdkDir + '/tempDex' classDir = srcDir + '/' + packageDir + '/wxapi' if not os.path.exists(classDir): os.makedirs(classDir) sourceClassFilePath = os.path.join(extraFilesPath, 'WXEntryActivity.class') targetClassFilePath = classDir + '/WXEntryActivity.class' file_utils.copy_file(sourceClassFilePath, targetClassFilePath) targetDexPath = os.path.join(sdkDir, 'WXEntryActivity.dex') dxTool = file_utils.getFullToolPath("/lib/dx.jar") cmd = file_utils.getJavaCMD( ) + ' -jar -Xmx512m -Xms512m "%s" --dex --output="%s" "%s"' % ( dxTool, targetDexPath, srcDir) ret = file_utils.execFormatCmd(cmd) if ret: return 1 ret = apk_utils.dex2smali(targetDexPath, decompileDir + '/smali') if ret: return 1 manifest = decompileDir + '/AndroidManifest.xml' ET.register_namespace('android', androidNS) name = '{' + androidNS + '}name' theme = '{' + androidNS + '}theme' configChanges = '{' + androidNS + '}configChanges' exported = '{' + androidNS + '}exported' screenOrientation = '{' + androidNS + '}screenOrientation' tree = ET.parse(manifest) root = tree.getroot() appNode = root.find('application') if appNode is None: return 1 activityNode = SubElement(appNode, 'activity') activityNode.set(name, packageName + '.wxapi.WXEntryActivity') activityNode.set(theme, '@android:style/Theme.Translucent.NoTitleBar') activityNode.set(configChanges, 'keyboardHidden|orientation') activityNode.set(exported, 'true') activityNode.set(screenOrientation, 'portrait') tree.write(manifest, 'UTF-8') return 0
def execute(channel, decompileDir, packageName): sdkDir = decompileDir + '/../sdk/' + channel['sdk'] if not os.path.exists(sdkDir): file_utils.printF("The sdk temp folder is not exists. path:" + sdkDir) return 1 extraFilesPath = sdkDir + '/extraFiles' relatedJar = os.path.join(extraFilesPath, '360SDK.jar') WXPayEntryActivity = os.path.join(extraFilesPath, 'WXEntryActivity.java') file_utils.modifyFileContent(WXPayEntryActivity, 'com.u8.sdk.qh360.wxapi', packageName + ".wxapi") splitdot = ';' if platform.system() == 'Darwin': splitdot = ':' cmd = '"%sjavac" -source 1.7 -target 1.7 "%s" -classpath "%s"%s"%s"' % ( file_utils.getJavaBinDir(), WXPayEntryActivity, relatedJar, splitdot, file_utils.getFullToolPath('android.jar')) ret = file_utils.execFormatCmd(cmd) if ret: return 1 packageDir = packageName.replace('.', '/') srcDir = sdkDir + '/tempDex' classDir = srcDir + '/' + packageDir + '/wxapi' if not os.path.exists(classDir): os.makedirs(classDir) sourceClassFilePath = os.path.join(extraFilesPath, 'WXEntryActivity.class') targetClassFilePath = classDir + '/WXEntryActivity.class' file_utils.copy_file(sourceClassFilePath, targetClassFilePath) targetDexPath = os.path.join(sdkDir, 'WXEntryActivity.dex') dxTool = file_utils.getFullToolPath("/lib/dx.jar") cmd = file_utils.getJavaCMD( ) + ' -jar -Xmx512m -Xms512m "%s" --dex --output="%s" "%s"' % ( dxTool, targetDexPath, srcDir) ret = file_utils.execFormatCmd(cmd) if ret: return 1 ret = apk_utils.dex2smali(targetDexPath, decompileDir + '/smali') if ret: return 1 manifest = decompileDir + '/AndroidManifest.xml' ET.register_namespace('android', androidNS) name = '{' + androidNS + '}name' hostKey = '{' + androidNS + '}host' configChanges = '{' + androidNS + '}configChanges' exported = '{' + androidNS + '}exported' screenOrientation = '{' + androidNS + '}screenOrientation' authoritiesKey = '{' + androidNS + '}authorities' tree = ET.parse(manifest) root = tree.getroot() appNode = root.find('application') if appNode is None: return 1 activityNode = SubElement(appNode, 'activity') activityNode.set(name, packageName + '.wxapi.WXEntryActivity') activityNode.set(configChanges, 'keyboardHidden|orientation') activityNode.set(exported, 'true') activityNode.set(screenOrientation, 'portrait') # appkey = "" # if 'params' in channel: # params = channel['params'] # for param in params: # if param['name'] == 'QHOPENSDK_APPKEY': # appkey = param['value'] # break #append host activityNodeLst = appNode.findall('activity') if activityNodeLst is not None and len(activityNodeLst) > 0: for activityNode in activityNodeLst: activityName = activityNode.get(name) if activityName == 'com.qihoo.gamecenter.sdk.activity.ContainerActivity': intentNodeLst = activityNode.findall('intent-filter') if intentNodeLst is not None: for itNode in intentNodeLst: dataNode = SubElement(itNode, 'data') dataNode.set(hostKey, packageName) # elif activityName == 'com.qihoo.gamecenter.sdk.activity.QhDeepLinkActivity': # intentNodeLst = activityNode.findall('intent-filter') # if intentNodeLst is not None: # for itNode in intentNodeLst: # dataNodeLst = itNode.findall('data') # if dataNodeLst is not None: # for dNode in dataNodeLst: # dNode.set(hostKey, appkey) # break providerNodeLst = appNode.findall("provider") if providerNodeLst is not None and len(providerNodeLst) > 0: for pNode in providerNodeLst: pName = pNode.get(name) if pName == 'com.qihoo.pushsdk.keepalive.account.SyncProvider': pNode.set(authoritiesKey, packageName + ".cx.accounts.syncprovider") tree.write(manifest, 'UTF-8') #modify res/xml/qihoo_game_sdk_sync_adapter.xml resXml = decompileDir + '/res/xml/qihoo_game_sdk_sync_adapter.xml' if os.path.exists(resXml): file_utils.modifyFileContent( resXml, 'com.qihoo.gamecenter.sdk.demosp.cx.accounts.syncprovider', packageName + ".cx.accounts.syncprovider") return 0
def pack(game, channel, sourcepath, isPublic): sourcepath = sourcepath.replace('\\', '/') if not os.path.exists(sourcepath): return 1 appID = game['appID'] appKey = game['appKey'] appName = game['appName'] channelId = channel["id"] channelName = channel["name"] sdkName = channel["sdk"] log_utils.info("now to package %s...", channelName) workDir = 'workspace/' + appName + '/' + channelName workDir = file_utils.getFullPath(workDir) file_utils.del_file_folder(workDir) tempApkSource = workDir + "/temp.apk" file_utils.copy_file(sourcepath, tempApkSource) decompileDir = workDir + "/decompile" ret = apk_utils.decompileApk(tempApkSource, decompileDir) if ret: return 2 #检查母包接入是否正确 # ret = apk_utils.checkApkForU8SDK(workDir, decompileDir) # if ret: # return 1 #检查multidex那个jar包 apk_utils.checkMultiDexJar(workDir, decompileDir) #更改XML配置等 newPackageName = apk_utils.renamePackageName(channel, decompileDir, channel['suffix'], isPublic) #复制第三插件资源。注意:这第三个插件必须在主SDK之前运行。 ret = apk_utils.handleThirdPlugins(workDir, decompileDir, game, channel, newPackageName) if ret: return 3 #将SDK代码复制到反编译程序 sdkSourceDir = file_utils.getFullPath('config/sdk/' + sdkName) smaliDir = decompileDir + "/smali" sdkDestDir = workDir + "/sdk/" + sdkName file_utils.copy_files(sdkSourceDir, sdkDestDir) if (not os.path.exists(sdkSourceDir + "/classes.dex")): ret = apk_utils.jar2dex(sdkSourceDir, sdkDestDir) if ret: return 4 ret = apk_utils.dexes2smali(sdkDestDir, smaliDir, "baksmali.jar") if ret: return 5 #复制主SDK资源。 ret = apk_utils.copyResource(game, channel, newPackageName, sdkDestDir, decompileDir, channel['operations'], channelName) if ret: return 6 #自动处理图标 apk_utils.appendChannelIconMark(game, channel, decompileDir) #复制渠道专用资源 ret = apk_utils.copyChannelResources(game, channel, decompileDir) if ret: return 7 #复制游戏根资源和资源 apk_utils.copyAppResources(game, decompileDir) apk_utils.copyAppRootResources(game, decompileDir) #生成APK运行的配置文件。 apk_utils.writeDevelopInfo(game, channel, decompileDir) apk_utils.writePluginInfo(channel, decompileDir) apk_utils.writeManifestMetaInfo(channel, decompileDir) apk_utils.writeLogConfig(game, decompileDir) #如果主SDK具有特殊逻辑。执行特殊的逻辑脚本。 ret = apk_utils.doSDKScript(channel, decompileDir, newPackageName, sdkDestDir) if ret: return 8 #如果游戏有一些特殊的逻辑。执行特殊的逻辑脚本。 post_script.py ret = apk_utils.doGamePostScript(game, channel, decompileDir, newPackageName) if ret: return 9 #here to config the splash screen. ret = apk_utils.addSplashScreen(workDir, channel, decompileDir) if ret: return 10 #检查CPU支持 apk_utils.checkCpuSupport(game, decompileDir) #如果指定频道,修改游戏名称。 apk_utils.modifyGameName(channel, decompileDir) #修改YML apk_utils.modifyYml(game, newPackageName, decompileDir) #到达复制sdk到临时目录 #生成新的R.java print('生成新的R.java') print(newPackageName) print(decompileDir) print(channel) print('===================================') ret = apk_utils.generateNewRFile(newPackageName, decompileDir, channel) if ret: return 11 #检查分离DEX apk_utils.splitDex(workDir, decompileDir) targetApk = workDir + "/output.apk" log_utils.debug("现在重新编译APK....") ret = apk_utils.recompileApk(decompileDir, targetApk) if ret: return 12 apk_utils.copyRootResFiles(targetApk, decompileDir) #复制根目录 ### #destApkName = channelName + '.apk' channelNameStr = channelName.replace(' ', '') if isPublic: # 获取最终apk包名 #destApkName = channelNameStr + '-' + time.strftime('%Y%m%d%H') + '.apk' destApkName = apk_utils.getOutputApkName(game, channel, newPackageName, decompileDir) else: destApkName = channelNameStr + '-' + time.strftime( '%Y%m%d%H') + '-debug.apk' destApkPath = file_utils.getFullOutputPath(appName, channelName) destApkPath = os.path.join(destApkPath, destApkName) ret = apk_utils.alignApk(targetApk, destApkPath) if ret: return 13 if 'signApk' not in channel or channel['signApk'] != '0': ret = apk_utils.signApk(workDir, game, channel, destApkPath) #对已经输出的安装包进行签名 if ret: return 14 else: log_utils.debug("APK设置为未签名。") #clear workspace #file_utils.del_file_folder(workDir) log_utils.info("游戏 %s 渠道 %s 打包成功.", appName, channelName) return 0
def doPack(package_info): channelConfig, logger, logfilepath = getChannelConfig(package_info) workDirCls = dir_utils.WorkDirCls( rootDir, channelConfig['game_info']['game_id'], channelConfig['game_info']['game_bundle_id'], channelConfig['game_info']['channel_flag'], channelConfig['game_info']['channel_version']) logger.info(channelConfig) workDir = workDirCls.workRootDir if not os.path.exists(workDir): os.makedirs(workDir) # 反编译apk logger.info('clean workdir') file_utils.del_file_folder(workDir) logger.info("copy sourceapk to workdir") apkSource = os.path.join(workDir, 'temp.apk') file_utils.copy_file(channelConfig['game_info']['source_apk'], apkSource) logger.info("decompile apk") ret, cmd, result = apk_utils.decompileApk(apkSource, workDirCls.workDecompileDir, apktoolPath) ###反编译 logger.info(cmd) logger.info(str(ret) + "======" + result) #删除原SDK相关内容 logger.info("delete default sdk info") ret, result = apk_utils.removeDefaultSDKInfo(workDirCls.workDecompileDir, defaultSDKInfoConfigFile) logger.info(str(ret) + "======" + result) # 对资源进行特殊处理(删除layout-v26/abc_screen_toolbar.xml中的android:keyboardNavigationCluster、删除drawable-v24/ic_launcher_foreground.xml中的android:fillType) logger.info("handle special resource") ret, result = apk_utils.handleSpecialResource(workDirCls.workDecompileDir) logger.info(str(ret) + "======" + result) #拷贝sdk插件到工作目录 logger.info("copy sdk plugin to workdir") #拷贝渠道SDK到工作目录 channelSdk = os.path.join(channelSdkPath, channelConfig['game_info']['channel_flag'], channelConfig['game_info']['channel_version']) file_utils.copy_files(channelSdk, workDirCls.workSDKDir) #拷贝媒体SDK到工作目录 if channelConfig['ad_sdk'].has_key( 'media_flag') and channelConfig['ad_sdk']['media_flag'] > 0: madiaSdk = os.path.join(mediaSdkPath, channelConfig['ad_sdk']['media_flag'], channelConfig['game_info']['media_version']) file_utils.copy_files(madiaSdk, workDirCls.workSDKDir) #copy头条aar #logger.info("if has toutiao, copy toutiao plugin to workdir") #if channelConfig['ad_sdk'].has_key('tt_id') and len(channelConfig['ad_sdk']['tt_id']) > 0: # toutiaoPluginDir = os.path.join(workDirCls.channelsDir, 'toutiao') # file_utils.copy_files(toutiaoPluginDir, workDirCls.workSDKDir) #copy广点通aar #logger.info("if has gdt, copy gdt plugin to workdir") #if channelConfig['ad_sdk'].has_key('gdt_id') and channelConfig['ad_sdk'].has_key('gdt_secret_key') and len(channelConfig['ad_sdk']['gdt_id']) > 0 and len(channelConfig['ad_sdk']['gdt_secret_key']) > 0: # gdtPluginDir = os.path.join(workDirCls.channelsDir, 'gdt') # file_utils.copy_files(gdtPluginDir, workDirCls.workSDKDir) #copy快手aar #logger.info("if has kuaishou, copy kuaishou plugin to workdir") #if channelConfig['ad_sdk'].has_key('ks_id') and len(channelConfig['ad_sdk']['ks_id']) > 0 and channelConfig['ad_sdk'].has_key('ks_name') and len(channelConfig['ad_sdk']['ks_name']) > 0: # kuaishouPluginDir = os.path.join(workDirCls.channelsDir, 'kuaishou') # file_utils.copy_files(kuaishouPluginDir, workDirCls.workSDKDir) #copy独代aar #logger.info("if has dudai, copy dudai plugin to workdir") #if channelConfig['game_info'].has_key('is_dudai') and channelConfig['game_info']['is_dudai'] == 'true': # dudaiPluginDir = os.path.join(workDirCls.channelsDir, 'dudai') # file_utils.copy_files(dudaiPluginDir, workDirCls.workSDKDir) #aar模式需进行解压和资源合并 logger.info("in workdir, unzip aar and zip, then merge") if apk_utils.isAarMode(workDirCls.workSDKDir): apk_utils.unzipAarFiles(workDirCls.workSDKDir) apk_utils.mergeAarFiles(workDirCls.workSDKDir) # copy libs(.jar除外) logger.info("copy sdk libs(except jar) to decompile dir") ret, result = apk_utils.copyLibs( os.path.join(workDirCls.workSDKDir, 'libs'), os.path.join(workDirCls.workDecompileDir, 'lib')) logger.info(str(ret) + "======" + result) # 处理lib文件夹,仅保留一个,防止不一致导致部分机型崩溃 logger.info("handle lib dir(cpu type)") ret, result = apk_utils.deleteOtherLibDir( os.path.join(workDirCls.workDecompileDir, 'lib'), channelConfig['game_info']['partner_id']) logger.info(str(ret) + "======" + result) #copy 渠道res logger.info("copy sdk res to decompile res dir") ret, result = apk_utils.copyResToApk( os.path.join(workDirCls.workSDKDir, 'res'), os.path.join(workDirCls.workDecompileDir, 'res')) logger.info(str(ret) + "======" + result) #copy 渠道assets logger.info("copy sdk assets to decompile assets dir") ret, result = apk_utils.copyResToApk( os.path.join(workDirCls.workSDKDir, 'assets'), os.path.join(workDirCls.workDecompileDir, 'assets')) logger.info(str(ret) + "======" + result) #copy 其他资源 logger.info("copy sdk other res to decompile dir") ret, result = apk_utils.copyOtherResToApk(workDirCls.workSDKDir, workDirCls.workDecompileDir) logger.info(str(ret) + "======" + result) #配置写入 独代配置暂时写死,没有更新 logger.info("update conf file()") apk_utils.updateConfFile(channelConfig, workDirCls.workDecompileDir) #修改apktool.yml 版本号 targetSdkVersion logger.info( "update apktool.yml, include targetSdkVersion, version_code etc.") apk_utils.updateApktoolYmlFile(channelConfig, workDirCls.workDecompileDir) #修改包名,合并manifest 2019-08-01新增:应用宝渠道,在主activity里面添加url scheme 格式:scheme://host/path(path为分包名) logger.info("merge manifest") ret, result, oldPackageName = apk_utils.mergeManifest( os.path.join(workDirCls.workDecompileDir, 'AndroidManifest.xml'), os.path.join(workDirCls.workSDKDir, 'sdkmanifest.xml'), channelConfig) logger.info(str(ret) + "======" + result) #替换AndroidManifest里面的占位符 logger.info("replace placeholder in manifest") apk_utils.replaceSpecialString( os.path.join(workDirCls.workDecompileDir, 'AndroidManifest.xml'), channelConfig, oldPackageName) #修改应用名称 logger.info("update app display name") ret, result = apk_utils.updateAppDisplayName( workDirCls.workDecompileDir, channelConfig['game_info']['game_name']) logger.info(str(ret) + "======" + result) apk_utils.handle_drawable_v4(workDirCls.workDecompileDir) #修改icon if channelConfig['game_info'].has_key( 'icon_file') and channelConfig['game_info'].has_key('icon_name'): logger.info("handle app icon") ret, result = apk_utils.handlePackageIcon( channelConfig['game_info']['icon_file'], workDirCls.workDecompileDir, channelConfig['game_info']['icon_name']) logger.info(str(ret) + "======" + result) #替换游戏素材(闪屏、loading、登录背景图) logger.info("replace app resource") if channelConfig['game_info'].has_key('game_resources') and len( channelConfig['game_info']['game_resources'] ) > 0 and channelConfig['game_info'].has_key('resource_path') and len( channelConfig['game_info']['resource_path']) > 0: oldGameResourcePath = os.path.join( workDirCls.workDecompileDir, channelConfig['game_info']['resource_path'].replace('/', os.sep)) for newGameResourcePath in channelConfig['game_info'][ 'game_resources']: file_utils.copy_file( newGameResourcePath, os.path.join(oldGameResourcePath, os.path.basename(newGameResourcePath))) #重新生成R文件,编译,然后生成jar包搭配渠道的libs目录下 logger.info("generate R file") ret, cmd, result = apk_utils.generateNewRFile( oldPackageName, channelConfig['game_info']['game_bundle_id'], workDirCls.workDecompileDir, toolsDir, channelConfig) logger.info(cmd) logger.info(str(ret) + "======" + result) #jar to dex logger.info("convert jar to dex") if not os.path.exists( os.path.join(workDirCls.currentChannelDir, "classes.dex")): ret, cmd, result = apk_utils.jar2dex(workDirCls.workSDKDir, workDirCls.workSDKDir, channelConfig) logger.info(cmd) logger.info(str(ret) + "======" + result) #dex to smali logger.info("convert dex to smali") sdkDexFile = os.path.join(workDirCls.workSDKDir, "classes.dex") ret, cmd, result = apk_utils.dex2smali(sdkDexFile, workDirCls.workDecompileSmaliDir, baksmaliJarPath) logger.info(cmd) logger.info(str(ret) + "======" + result) #应用宝/小米 多Dex处理 if channelConfig['game_info']['partner_id'] == '3' or channelConfig[ 'game_info']['partner_id'] == '9': logger.info("handle multi dex") apk_utils.splitDex(workDirCls.workDecompileDir) # 处理需要特殊处理的smali文件 apk_utils.handleSmali(channelConfig, workDirCls.workDecompileDir) #重新编译 logger.info("compile new apk") targetApkFile = os.path.join(workDirCls.workTempDir, "output.apk") ret, cmd, result = apk_utils.recompileApk(workDirCls.workTempDir, workDirCls.workDecompileDir, targetApkFile, apktoolPath) logger.info(cmd) logger.info(str(ret) + "======" + result) #签名 logger.info("sign apk") signInfo = { "keystore": os.path.join(commonConfigDir, '7yol_default.keystore'), "password": "******", "aliaskey": "7yol_default", "aliaspwd": "Aa314159" } ret, cmd, result = apk_utils.signApk(targetApkFile, signInfo) logger.info(cmd) logger.info(str(ret) + "======" + result) #对齐 logger.info("align apk") targetZApk = os.path.join(workDirCls.workTempDir, "outputZ.apk") ret, cmd, result = apk_utils.alignApk(zipalignToolPath, targetApkFile, targetZApk) logger.info(cmd) logger.info(str(ret) + "======" + result) #copy到target目录 logger.info("copy apk to target dir") targetApkFileName = os.path.splitext(os.path.basename(logfilepath))[0] targetApkFilePath = os.path.join( channelConfig['game_info']['target_apk'], channelConfig['game_info']['game_id'], channelConfig['game_info']['channel_flag'], channelConfig['game_info']['game_bundle_id'], targetApkFileName + '.apk') file_utils.copy_file(targetZApk, targetApkFilePath) if os.path.exists(targetApkFilePath): logger.info("pack success!!!===target apk is: %s" % targetApkFilePath) print '{"status":1, "apkPath":"%s", "logPath": "%s"}' % ( targetApkFilePath, logfilepath) else: logger.info("pack fail") print '{"status":0, "logPath": "%s"}' % (logfilepath)
def execute(channel, decompileDir, packageName): sdkDir = decompileDir + '/../sdk/' + channel['sdk'] if not os.path.exists(sdkDir): file_utils.printF("The sdk temp folder is not exists. path:"+sdkDir) return 1 extraFilesPath = sdkDir + '/extraFiles' relatedJar = os.path.join(extraFilesPath, '360SDK.jar') WXPayEntryActivity = os.path.join(extraFilesPath, 'WXEntryActivity.java') file_utils.modifyFileContent(WXPayEntryActivity, 'com.u8.sdk.qh360.wxapi', packageName+".wxapi") splitdot = ';' if platform.system() == 'Darwin': splitdot = ':' cmd = '"%sjavac" -source 1.7 -target 1.7 "%s" -classpath "%s"%s"%s"' % (file_utils.getJavaBinDir(), WXPayEntryActivity, relatedJar, splitdot, file_utils.getFullToolPath('android.jar')) ret = file_utils.execFormatCmd(cmd) if ret: return 1 packageDir = packageName.replace('.', '/') srcDir = sdkDir + '/tempDex' classDir = srcDir + '/' + packageDir + '/wxapi' if not os.path.exists(classDir): os.makedirs(classDir) sourceClassFilePath = os.path.join(extraFilesPath, 'WXEntryActivity.class') targetClassFilePath = classDir + '/WXEntryActivity.class' file_utils.copy_file(sourceClassFilePath, targetClassFilePath) targetDexPath = os.path.join(sdkDir, 'WXEntryActivity.dex') dxTool = file_utils.getFullToolPath("/lib/dx.jar") cmd = file_utils.getJavaCMD() + ' -jar -Xmx512m -Xms512m "%s" --dex --output="%s" "%s"' % (dxTool, targetDexPath, srcDir) ret = file_utils.execFormatCmd(cmd) if ret: return 1 ret = apk_utils.dex2smali(targetDexPath, decompileDir+'/smali', "baksmali.jar") if ret: return 1 manifest = decompileDir + '/AndroidManifest.xml' ET.register_namespace('android', androidNS) name = '{' + androidNS + '}name' hostKey = '{'+androidNS+'}host' configChanges = '{' + androidNS + '}configChanges' exported = '{' + androidNS + '}exported' screenOrientation = '{' + androidNS + '}screenOrientation' tree = ET.parse(manifest) root = tree.getroot() appNode = root.find('application') if appNode is None: return 1 activityNode = SubElement(appNode, 'activity') activityNode.set(name, packageName + '.wxapi.WXEntryActivity') activityNode.set(configChanges, 'keyboardHidden|orientation') activityNode.set(exported, 'true') activityNode.set(screenOrientation, 'portrait') #append host activityNodeLst = appNode.findall('activity') if activityNodeLst is not None and len(activityNodeLst) > 0: for activityNode in activityNodeLst: activityName = activityNode.get(name) if activityName == 'com.qihoo.gamecenter.sdk.activity.ContainerActivity': intentNodeLst = activityNode.findall('intent-filter') find = False if intentNodeLst is not None: for itNode in intentNodeLst: dataNodeList = itNode.findall('data') for dataNode in dataNodeList : if dataNode.get(hostKey) == 'com.qihoo.gamecenter.sdk.demosp': dataNode.set(hostKey, packageName) find = True break if find: break tree.write(manifest, 'UTF-8') return 0
def add_block_with_check(self, block): # log_utils.debug("add_block_with_check:"+block.path()) fullName = block.fullname() # check global attr if block.get_res_type() == ResourceBlock.RES_VAL_ATTR: if fullName in self.entries: block.mark_removed() self.internal_add_block(block) return # check in children for k in self.entries: exists = self.entries[k] for b in exists: if b.is_styleable() and b.exists_in_children( fullName, block.get_format()): block.mark_removed() self.internal_add_block(block) return # check styleable attrs if block.get_res_type() == ResourceBlock.RES_VAL_STYLEABLE: children = block.get_children() for k in children: childFullName = children[k].fullname() if childFullName in self.entries and children[k].has_format(): children[k].mark_removed() continue for m in self.entries: exists = self.entries[m] for b in exists: if block.path() == b.path(): # ignore same node in same file. you can remove it by yourself continue if b.is_styleable() and b.exists_in_children( childFullName, children[k].get_format()): children[k].mark_removed() break if fullName in self.entries: if block.get_res_type() == ResourceBlock.RES_VAL_PUBLIC: # pre merge public.xml # ValueResourceParser.merge_val_files_with_check(block.path(), self.entries[fullName][0].path()) #public.xml文件不能直接合并,这里暂时采用新的目录下直接覆盖母包的public.xml文件。 file_utils.copy_file(block.path(), self.entries[fullName][0].path()) log_utils.debug("pre merge public.xml from %s to %s", block.path(), self.entries[fullName][0].path()) return if block.get_res_type() == ResourceBlock.RES_VAL_STYLEABLE: # styable attrs to merge log_utils.debug( "check styable duplicated. name:%s;new_path:%s;exists_path:%s", block.get_name(), block.path(), self.entries[fullName][0].path()) block.mark_merged() else: log_utils.error( "check resource block duplicated. name:%s;new_path:%s;exists_path:%s;", block.get_name(), block.path(), self.entries[fullName][0].path()) block.mark_removed() self.internal_add_block(block)
def pack(game, channel, sourcepath, isPublic): sourcepath = sourcepath.replace("\\", "/") if not os.path.exists(sourcepath): return 1 appID = game["appID"] appKey = game["appKey"] appName = game["appName"] channelId = channel["id"] channelName = channel["name"] sdkName = channel["sdk"] log_utils.info("now to package %s...", channelName) workDir = "workspace/" + appName + "/" + channelName workDir = file_utils.getFullPath(workDir) file_utils.del_file_folder(workDir) tempApkSource = workDir + "/temp.apk" file_utils.copy_file(sourcepath, tempApkSource) decompileDir = workDir + "/decompile" ret = apk_utils.decompileApk(tempApkSource, decompileDir) if ret: return 1 # 检查母包接入是否正确 # ret = apk_utils.checkApkForU8SDK(workDir, decompileDir) # if ret: # return 1 # copy sdk code to decompileDir sdkSourceDir = file_utils.getFullPath("config/sdk/" + sdkName) smaliDir = decompileDir + "/smali" sdkDestDir = workDir + "/sdk/" + sdkName file_utils.copy_files(sdkSourceDir, sdkDestDir) if not os.path.exists(sdkSourceDir + "/classes.dex"): apk_utils.jar2dex(sdkSourceDir, sdkDestDir) sdkDexFile = sdkDestDir + "/classes.dex" ret = apk_utils.dex2smali(sdkDexFile, smaliDir, "baksmali.jar") if ret: return 1 # change xml config and so on newPackageName = apk_utils.renamePackageName(channel, decompileDir, channel["suffix"], isPublic) # copy third-plugins resources. note:The third plugins must be operated before the main sdk. ret = apk_utils.handleThirdPlugins(workDir, decompileDir, game, channel, newPackageName) if ret: return 1 # copy main sdk resources. ret = apk_utils.copyResource( game, channel, newPackageName, sdkDestDir, decompileDir, channel["operations"], channelName ) if ret: return 1 # copy channel special resources ret = apk_utils.copyChannelResources(game, channel, decompileDir) if ret: return 1 # copy game root resources and res resources apk_utils.copyAppResources(game, decompileDir) apk_utils.copyAppRootResources(game, decompileDir) apk_utils.appendChannelIconMark(game, channel, decompileDir) # generate config files for apk to run. apk_utils.writeDevelopInfo(appID, appKey, channel, decompileDir) apk_utils.writePluginInfo(channel, decompileDir) apk_utils.writeManifestMetaInfo(channel, decompileDir) # if the main sdk has special logic. execute the special logic script. ret = apk_utils.doSDKScript(channel, decompileDir, newPackageName, sdkDestDir) if ret: return 1 # if the game has some special logic. execute the special logic script.called post_script.py ret = apk_utils.doGamePostScript(game, channel, decompileDir, newPackageName) if ret: return 1 # here to config the splash screen. ret = apk_utils.addSplashScreen(workDir, channel, decompileDir) if ret: return 1 # check cpu supports apk_utils.checkCpuSupport(game, decompileDir) # modify game name if channel specified. apk_utils.modifyGameName(channel, decompileDir) # generate new R.java ret = apk_utils.generateNewRFile(newPackageName, decompileDir) if ret: return 1 targetApk = workDir + "/output.apk" ret = apk_utils.recompileApk(decompileDir, targetApk) if ret: return 1 apk_utils.copyRootResFiles(targetApk, decompileDir) ret = apk_utils.signApk(appName, channelId, targetApk) if ret: return 1 # destApkName = channelName + '.apk' channelNameStr = channelName.replace(" ", "") if isPublic: destApkName = channelNameStr + "-" + time.strftime("%Y%m%d%H") + ".apk" else: destApkName = channelNameStr + "-" + time.strftime("%Y%m%d%H") + "-debug.apk" destApkPath = file_utils.getFullOutputPath(appName, channelName) destApkPath = os.path.join(destApkPath, destApkName) ret = apk_utils.alignApk(targetApk, destApkPath) if ret: return 1 # clear workspace # file_utils.del_file_folder(workDir) log_utils.info("channel %s package success.", channelName) return 0
def create_proj(projPath, toolPath, u8serverPath, targetName, classPrefix, selectType): # if not targetName.startswith("U8SDK_"): # targetName = "U8SDK_" + targetName print("selectType:" + selectType) selectType = int(selectType) if selectType == 1 or selectType == 2: print("generate client...........") if not os.path.exists(projPath): log_utils.debug("the U8SDK_Projects dir is not exists." + projPath) return if not os.path.exists(toolPath): log_utils.debug("the U8SDKTool-Win-P34 dir is not exists." + toolPath) return templatePath = os.path.join(projPath, "U8SDK_Template") if not os.path.exists(templatePath): log_utils.debug("the template project is not exists." + templatePath) return sdkConfigPath = os.path.join(toolPath, "config/sdk/" + targetName.lower()) if os.path.exists(sdkConfigPath): log_utils.error( "sdk with same name is already exists. please change the name." + targetName) return projTargetName = "U8SDK_" + targetName targetPath = os.path.join(projPath, projTargetName) if os.path.exists(targetPath): log_utils.debug("the target project is already exists." + targetPath) return file_utils.copy_files(templatePath, targetPath) srcPath = os.path.join(targetPath, "src/com/u8/sdk") for f in os.listdir(srcPath): fname = os.path.join(srcPath, f) file_utils.modifyFileContent(fname, "Temp", classPrefix) ftarget = f.replace("Temp", classPrefix) os.rename(fname, os.path.join(srcPath, ftarget)) configPath = os.path.join(targetPath, "config.xml") file_utils.modifyFileContent(configPath, "Temp", classPrefix) projFilePath = os.path.join(targetPath, ".project") file_utils.modifyFileContent(projFilePath, "U8SDK_Template", projTargetName) os.makedirs(sdkConfigPath) if selectType == 1 or selectType == 3: u8serverSDKPath = os.path.join( u8serverPath, "src/main/java/com/u8/server/sdk/" + targetName.lower()) if os.path.exists(u8serverSDKPath): log_utils.error( "sdk with same name is already exists in server. please change the name." + targetName) return u8serverPayPath = os.path.join( u8serverPath, "src/main/java/com/u8/server/web/pay/sdk/" + targetName + "PayCallbackAction.java") if os.path.exists(u8serverPayPath): log_utils.error( "sdk with same name is already exists in server callback. please change the name." + targetName) return serverDemoSDKPath = os.path.join( u8serverPath, "src/main/java/com/u8/server/sdk/demo") file_utils.copy_files(serverDemoSDKPath, u8serverSDKPath) sdkName = os.path.join(u8serverSDKPath, 'DemoSDK.java') targetSDKName = sdkName.replace("Demo", targetName) os.rename(sdkName, targetSDKName) file_utils.modifyFileContent(targetSDKName, "Demo", targetName) file_utils.modifyFileContent(targetSDKName, "demo", targetName.lower()) serverDemoPayPath = os.path.join( u8serverPath, 'src/main/java/com/u8/server/web/pay/sdk/DemoPayCallbackAction.java' ) file_utils.copy_file(serverDemoPayPath, u8serverPayPath) file_utils.modifyFileContent(u8serverPayPath, "demo", targetName.lower()) file_utils.modifyFileContent(u8serverPayPath, "Demo", targetName)
def pack(game, channel, sourcepath, isPublic): sourcepath = sourcepath.replace('\\', '/') if not os.path.exists(sourcepath): return 1 appID = game['appID'] appKey = game['appKey'] appName = game['appName'] channelId = channel["id"] channelName = channel["name"] sdkName = channel["sdk"] log_utils.info("now to package %s...", channelName) workDir = 'workspace/' + appName + '/' + channelName workDir = file_utils.getFullPath(workDir) file_utils.del_file_folder(workDir) tempApkSource = workDir + "/temp.apk" file_utils.copy_file(sourcepath, tempApkSource) decompileDir = workDir + "/decompile" ret = apk_utils.decompileApk(tempApkSource, decompileDir) if ret: return 1 #检查母包接入是否正确 # ret = apk_utils.checkApkForU8SDK(workDir, decompileDir) # if ret: # return 1 #检查multidex那个jar包 apk_utils.checkMultiDexJar(workDir, decompileDir) #change xml config and so on newPackageName = apk_utils.renamePackageName(channel, decompileDir, channel['suffix'], isPublic) #copy third-plugins resources. note:The third plugins must be operated before the main sdk. ret = apk_utils.handleThirdPlugins(workDir, decompileDir, game, channel, newPackageName) if ret: return 1 #copy sdk code to decompileDir sdkSourceDir = file_utils.getFullPath('config/sdk/' + sdkName) smaliDir = decompileDir + "/smali" sdkDestDir = workDir + "/sdk/" + sdkName file_utils.copy_files(sdkSourceDir, sdkDestDir) if (not os.path.exists(sdkSourceDir + "/classes.dex")): ret = apk_utils.jar2dex(sdkSourceDir, sdkDestDir) if ret: return 1 ret = apk_utils.dexes2smali(sdkDestDir, smaliDir, "baksmali.jar") if ret: return 1 #copy main sdk resources. ret = apk_utils.copyResource(game, channel, newPackageName, sdkDestDir, decompileDir, channel['operations'], channelName) if ret: return 1 #auto handle icon apk_utils.appendChannelIconMark(game, channel, decompileDir) #copy channel special resources ret = apk_utils.copyChannelResources(game, channel, decompileDir) if ret: return 1 #copy game root resources and res resources apk_utils.copyAppResources(game, decompileDir) apk_utils.copyAppRootResources(game, decompileDir) #generate config files for apk to run. apk_utils.writeDevelopInfo(game, channel, decompileDir) apk_utils.writePluginInfo(channel, decompileDir) apk_utils.writeManifestMetaInfo(channel, decompileDir) apk_utils.writeLogConfig(game, decompileDir) #if the main sdk has special logic. execute the special logic script. ret = apk_utils.doSDKScript(channel, decompileDir, newPackageName, sdkDestDir) if ret: return 1 #if the game has some special logic. execute the special logic script.called post_script.py ret = apk_utils.doGamePostScript(game, channel, decompileDir, newPackageName) if ret: return 1 #here to config the splash screen. ret = apk_utils.addSplashScreen(workDir, channel, decompileDir) if ret: return 1 #check cpu supports apk_utils.checkCpuSupport(game, decompileDir) #modify game name if channel specified. apk_utils.modifyGameName(channel, decompileDir) #modify yml apk_utils.modifyYml(game, newPackageName, decompileDir) #generate new R.java ret = apk_utils.generateNewRFile(newPackageName, decompileDir, channel) if ret: return 1 #check to split dex apk_utils.splitDex(workDir, decompileDir) targetApk = workDir + "/output.apk" log_utils.debug("now to recompileApk....") ret = apk_utils.recompileApk(decompileDir, targetApk) if ret: return 1 apk_utils.copyRootResFiles(targetApk, decompileDir) if 'signApk' not in channel or channel['signApk'] != '0': ret = apk_utils.signApk(workDir, game, channel, targetApk) if ret: return 1 else: log_utils.debug("the apk is set to unsigned.") #destApkName = channelName + '.apk' channelNameStr = channelName.replace(' ', '') if isPublic: #destApkName = channelNameStr + '-' + time.strftime('%Y%m%d%H') + '.apk' destApkName = apk_utils.getOutputApkName(game, channel, newPackageName, decompileDir) else: destApkName = channelNameStr + '-' + time.strftime( '%Y%m%d%H') + '-debug.apk' destApkPath = file_utils.getFullOutputPath(appName, channelName) destApkPath = os.path.join(destApkPath, destApkName) ret = apk_utils.alignApk(targetApk, destApkPath) if ret: return 1 #clear workspace #file_utils.del_file_folder(workDir) log_utils.info("channel %s package success.", channelName) return 0
def pack(game, channel, sourcepath, isPublic): sourcepath = sourcepath.replace('\\', '/') if not os.path.exists(sourcepath): return 1 appID = game['appID'] appKey = game['appKey'] appName = game['appName'] channelId = channel["id"] channelName = channel["name"] sdkName = channel["sdk"] log_utils.info("now to package %s...", channelName) workDir = 'workspace/' + appName + '/' + channelName workDir = file_utils.getFullPath(workDir) file_utils.del_file_folder(workDir) tempApkSource = workDir + "/temp.apk" file_utils.copy_file(sourcepath, tempApkSource) decompileDir = workDir + "/decompile" smaliDir = decompileDir + "/smali" #反编译APK ret = apk_utils.decompileApk(tempApkSource, decompileDir) if ret: return 1 #检查母包接入是否正确 ret = apk_utils.checkApkForU8SDK(workDir, decompileDir) if ret: return 1 #change xml config and so on newPackageName = apk_utils.renamePackageName(channel, decompileDir, channel['suffix'], isPublic) #copy third-plugins resources. note:The third plugins must be operated before the main sdk. ret = apk_utils.handleThirdPlugins(workDir, decompileDir, game, channel, newPackageName) if ret: return 1 #copy sdk code to decompileDir sdkSourceDir = 'config/sdk/' + sdkName sdkSourceDir = file_utils.getFullPath(sdkSourceDir) sdkDestDir = workDir + "/sdk/" + sdkName file_utils.copy_files(sdkSourceDir, sdkDestDir) #将公共库复制到临时目录,除了moyoihw渠道 if sdkName != 'moyoihw': promptDir = 'config/local/common-release.aar' promptDestDir = sdkDestDir + '/libs/common-release.aar'; file_utils.copy_files(promptDir, promptDestDir) #处理需要Gradle自动下载的库 if 'dependencies' in channel and channel['dependencies'] != None and len(channel['dependencies']) > 0: #将build.gradle复制到临时目录 localSourceDir = 'config/local/build.gradle' file_utils.copy_files(localSourceDir, sdkDestDir + '/build.gradle') #修改build.gradle config_utils.writeGradleDependencies(channel['dependencies'], sdkDestDir) #将SDK中所有aar文件解压,然后将里面各个类型的资源文件合并到SDK对应目录 file_utils.decomAAR(sdkDestDir) ret = apk_utils.jar2dex(sdkDestDir, sdkDestDir) if ret: return 1 ret = apk_utils.dexes2smali(sdkDestDir, smaliDir, "baksmali.jar") if ret: return 1 #copy main sdk resources. ret = apk_utils.copyResource(game, channel, newPackageName, sdkDestDir, decompileDir, channel['operations'], channelName) if ret: return 1 #auto handle icon apk_utils.appendChannelIconMark(game, channel, decompileDir) #copy channel special resources ret = apk_utils.copyChannelResources(game, channel, decompileDir) if ret: return 1 #copy game root resources and res resources apk_utils.copyAppResources(game, decompileDir) apk_utils.copyAppRootResources(game, decompileDir) #generate config files for apk to run. apk_utils.writeDevelopInfo(game, channel, decompileDir) apk_utils.writePluginInfo(channel, decompileDir) apk_utils.writeManifestMetaInfo(channel, decompileDir) apk_utils.writeLogConfig(game, decompileDir) #if the main sdk has special logic. execute the special logic script. ret = apk_utils.doSDKScript(channel, decompileDir, newPackageName, sdkDestDir) if ret: return 1 #if the game has some special logic. execute the special logic script.called post_script.py ret = apk_utils.doGamePostScript(game, channel, decompileDir, newPackageName) if ret: return 1 #here to config the splash screen. ret = apk_utils.addSplashScreen(workDir, channel, decompileDir) if ret: return 1 #check cpu supports apk_utils.checkCpuSupport(game, decompileDir) #modify game name if channel specified. apk_utils.modifyGameName(channel, decompileDir) #modify yml apk_utils.modifyYml(game, newPackageName, decompileDir) #generate new R.java ret = apk_utils.generateNewRFile(newPackageName, decompileDir, channel) if ret: return 1 #check to split dex apk_utils.splitDex(workDir, decompileDir) targetApk = workDir + "/output.apk" log_utils.debug("now to recompileApk....") ret = apk_utils.recompileApk(decompileDir, targetApk) if ret: return 1 apk_utils.copyRootResFiles(targetApk, decompileDir) if 'signApk' not in channel or channel['signApk'] != '0': apk_utils.xsigncode(workDir, game, channel, targetApk) apk_utils.signApk(workDir, game, channel, targetApk) else: log_utils.debug("the apk is set to unsigned.") channelNameStr = channelName.replace(' ', '') if isPublic: destApkName = apk_utils.getOutputApkName(game, channel, newPackageName, decompileDir) else: destApkName = channelNameStr + '-' + time.strftime('%Y%m%d%H') + '-debug.apk' destApkPath = file_utils.getFullOutputPath(appName, channelName) destApkPath = os.path.join(destApkPath, destApkName) ret = apk_utils.alignApk(targetApk, destApkPath) if ret: return 1 log_utils.info("channel %s package success.", channelName) return 0
def make_buildsystem(self): if self.pd.buildSystem=="Scons": self.make_sconstruct_file(self.definitions_dict) copy_file( self.definitions_dict, "options.cache" ) else: raise Exception("Makefile for CLAM needs to be implemented")