import time from flask import Flask, request import requests from PIL import ImageFile, Image import os import shutil import subprocess from zipfile import ZipFile ImageFile.SAFEBLOCK = 2048 * 2048 app = Flask(__name__) app.base_project = "/apps/3ps/build_apk/PalioLite" # app.base_project = "/Users/easysoft/Documents/PalioLite" app.temp_folder = "/apps/3ps/build_apk/BuildApk" # app.temp_folder = "/Users/easysoft/BuildApk" app.apk_folder = "/var/www/html/palio.io/dashboardv2/uploads" # app.apk_folder = "/Users/easysoft/" app.verbose = True app.ssl =('/etc/ssl/star.newuniverse.io/star.newuniverse.io.crt', '/etc/ssl/star.newuniverse.io/STAR_newuniverse_io.key') #app.ssl =('/etc/ssl/STAR_palio_io/STAR_palio_io.crt', '/etc/ssl/STAR_palio_io/STAR_palio_io.pem') # app.ssl = None app.keytool = '/usr/bin/keytool' app.base_project_name = os.path.basename(app.base_project) def vprint(*data): if app.verbose: print(*data) def create_folder(package_id): path = os.path.join(app.temp_folder, package_id) if not os.path.exists(path): os.mkdir(path) else: shutil.rmtree(path) os.mkdir(path) vprint(path) path_dest = os.path.join(path, app.base_project_name) if not os.path.exists(path_dest): shutil.copytree(app.base_project, path_dest) code_path = "app/src/main/java/" orig_code = "com/example/qmeralitesamplecode" path_package_id = package_id.replace(".", "/") c_code_path = os.path.join(path_dest, code_path, path_package_id) orig_code_path = os.path.join(path_dest, code_path, orig_code) if not os.path.exists(c_code_path): shutil.copytree(orig_code_path, c_code_path) shutil.rmtree(orig_code_path) return path_dest, c_code_path def change_acc(c_code_path, acc): main_activity = os.path.join(c_code_path, "MainActivity.java") with open(main_activity, "r") as f: file_source = f.read() replaced = file_source.replace("***REPLACE***WITH***YOUR***QMERA***ACCOUNT***", acc) with open(main_activity, "w") as f: f.write(replaced) def change_url(c_code_path, url): main_activity = os.path.join(c_code_path, "MainActivity.java") with open(main_activity, "r") as f: file_source = f.read() replaced = file_source.replace("https://www.google.com", url) with open(main_activity, "w") as f: f.write(replaced) def change_name(path_dest, name): manifest = os.path.join(path_dest, "app/src/main/AndroidManifest.xml") string_res = os.path.join(path_dest, "app/src/main/res/values/strings.xml") with open(manifest, "r") as f: file_source = f.read() replaced = file_source.replace("NexilisLite", name) with open(manifest, "w") as f: f.write(replaced) with open(string_res, "r") as f: file_source = f.read() replaced = file_source.replace("Nexilis Sport", name) with open(string_res, "w") as f: f.write(replaced) def change_font(path_dest, font, package): if font == 1: path_package_id = package.replace(".", "/") code_path = "app/src/main/java/" code_path = os.path.join(path_dest, code_path, path_package_id) res_path = "app/src/main/res/" res_path = os.path.join(path_dest, res_path) javas = [os.path.join(dp, f) for dp, dn, filenames in os.walk(code_path) for f in filenames] res = [os.path.join(dp, f) for dp, dn, filenames in os.walk(res_path) for f in filenames if "xml" in f] button_apps_code_path = os.path.join(path_dest, "palio-button-app/src/main/java") button_apps_res_path = os.path.join(path_dest, "palio-button-app/src/main/res-pba/") lib_javas = [os.path.join(dp, f) for dp, dn, filenames in os.walk(button_apps_code_path) for f in filenames] lib_res = [os.path.join(dp, f) for dp, dn, filenames in os.walk(button_apps_res_path) for f in filenames if "xml" in f] for j in javas: print(j) if "ForumFragment.java" in j: with open(j, "r") as f: file_source = f.read() replaced = file_source.replace("pb_poppins", "roboto") with open(j, "w") as f: f.write(replaced) for j in res: print(j) with open(j, "r") as f: file_source = f.read() replaced = file_source.replace("pb_poppins", "roboto") with open(j, "w") as f: f.write(replaced) for j in lib_javas: print(j) with open(j, "r") as f: file_source = f.read() replaced = file_source.replace("pb_poppins", "roboto") with open(j, "w") as f: f.write(replaced) for j in lib_res: print(j) with open(j, "r") as f: file_source = f.read() replaced = file_source.replace("pb_poppins", "roboto") with open(j, "w") as f: f.write(replaced) def change_package(path_dest, package): build_gradle = os.path.join(path_dest, 'app/build.gradle') with open(build_gradle, "r") as f: file_source = f.read() replaced = file_source.replace("com.example.qmeralitesamplecode", package) with open(build_gradle, "w") as f: f.write(replaced) proguard = os.path.join(path_dest, 'app/proguard-rules.pro') with open(proguard, "r") as f: file_source = f.read() replaced = file_source.replace("com.example.qmeralitesamplecode", package) with open(proguard, "w") as f: f.write(replaced) manifest = os.path.join(path_dest, "app/src/main/AndroidManifest.xml") with open(manifest, "r") as f: file_source = f.read() replaced = file_source.replace("com.example.qmeralitesamplecode", package) with open(manifest, "w") as f: f.write(replaced) path_package_id = package.replace(".", "/") code_path = "app/src/main/java/" code_path = os.path.join(path_dest, code_path, path_package_id) res_path = "app/src/main/res/" res_path = os.path.join(path_dest, res_path) javas = [os.path.join(dp, f) for dp, dn, filenames in os.walk(code_path) for f in filenames] res = [os.path.join(dp, f) for dp, dn, filenames in os.walk(res_path) for f in filenames if "xml" in f] for j in javas: print(j) with open(j, "r") as f: file_source = f.read() replaced = file_source.replace("com.example.qmeralitesamplecode", package) with open(j, "w") as f: f.write(replaced) for j in res: print(j) with open(j, "r") as f: file_source = f.read() replaced = file_source.replace("com.example.qmeralitesamplecode", package) with open(j, "w") as f: f.write(replaced) def change_logo(path_dest, logo, logo_float=None): img_path = "app/src/main/res/drawable/ic_launcher.png" img_path = os.path.join(path_dest, img_path) img_notif = "app/src/main/res/drawable-v24/pb_ball.png" img_notif = os.path.join(path_dest, img_notif) img_path_float = "app/src/main/res/drawable/pb_button.png" img_path_float = os.path.join(path_dest, img_path_float) if isinstance(logo, str): logo = requests.get('https://newuniverse.io/dashboardv2/uploads/logo/{}'.format(logo)) with open(img_path, "wb") as f: f.write(logo.content) with open(img_path, "rb") as f: logo = Image.open(f) logo = logo.resize((512, 512)) if logo_float: logo_float = requests.get('https://newuniverse.io/dashboardv2/uploads/logofloat/{}'.format(logo_float)) with open(img_path_float, "wb") as f: f.write(logo_float.content) with open(img_path_float, "rb") as f: logo_float = Image.open(f) logo_float = logo_float.resize((150, 150)) else: logo = Image.open(logo) logo = logo.resize((512, 512)) if logo_float: logo_float = Image.open(logo_float) logo_float = logo_float.resize((150, 150)) logo.save(img_path, "PNG") if logo_float: logo_float.save(img_path_float, "PNG") logo_float.save(img_notif, "PNG") def change_tab(path_dest, tabs, tab_icon, package, tab3_mode, tab_amount): default_tab_icon = ["tab1.png", "tab2.png", "tab3.png", "tab4.png"] for i in range(4): if not tab_icon[i]: continue img_path = "app/src/main/res/drawable-v24" img_path = os.path.join(path_dest, img_path, default_tab_icon[i]) if isinstance(tab_icon[i], str): logo = requests.get('https://newuniverse.io/dashboardv2/uploads/tab_icon/{}'.format(tab_icon[i])) with open(img_path, "wb") as f: f.write(logo.content) with open(img_path, "rb") as f: logo = Image.open(f) logo = logo.resize((150, 150)) logo.save(img_path, "PNG") else: logo = Image.open(tab_icon[i]) logo = logo.resize((150, 150)) logo.save(img_path, "PNG") path_package_id = package.replace(".", "/") code_path = "app/src/main/java/" sobj_code_path = os.path.join(path_dest, code_path, path_package_id, "SObj.java") print(sobj_code_path) with open(sobj_code_path, "r") as f: file_source = f.read() replaced = file_source.replace("1,2,3,4", ",".join(tabs)) with open(sobj_code_path, "w") as f: f.write(replaced) main_code_path = os.path.join(path_dest, code_path, path_package_id, "MainActivity.java") with open(main_code_path, "r") as f: file_source = f.read() replaced = file_source.replace('tab3 = "0"', 'tab3 = "{}"'.format(tab3_mode)) with open(main_code_path, "w") as f: f.write(replaced) prefs_code_path = os.path.join(path_dest, code_path, path_package_id, "util/PrefsUtil.java") with open(prefs_code_path, "r") as f: file_source = f.read() replaced = file_source.replace('DEFAULT_TAB_AMOUNT = "4"', 'DEFAULT_TAB_AMOUNT = "{}"'.format(tab_amount)) with open(prefs_code_path, "w") as f: f.write(replaced) def change_fb(path_dest, fb_icon): default_fb_icon = ["pb_button_chat.png", "pb_button_call.png", "pb_button_cc.png", "pb_button_stream.png", "nexilis_fb_04.png"] for i in range(5): if not fb_icon[i]: continue img_path = "app/src/main/res/drawable-nodpi" img_path = os.path.join(path_dest, img_path, default_fb_icon[i]) if isinstance(fb_icon[i], str): logo = requests.get('https://newuniverse.io/dashboardv2/uploads/fb_icon/{}'.format(fb_icon[i])) with open(img_path, "wb") as f: f.write(logo.content) with open(img_path, "rb") as f: logo = Image.open(f) logo = logo.resize((150, 150)) logo.save(img_path, "PNG") else: logo = Image.open(fb_icon[i]) logo = logo.resize((150, 150)) logo.save(img_path, "PNG") def change_background(path_dest, background): if isinstance(background, str): background = background.split(",") for i,b in enumerate(background): n = i+1 img_path = "app/src/main/res/drawable-nodpi-v4/pb_lbackground_{}.png".format(n) img_path = os.path.join(path_dest, img_path) logo = requests.get('https://newuniverse.io/dashboardv2/uploads/background/{}'.format(b)) with open(img_path, "wb") as f: f.write(logo.content) with open(img_path, "rb") as f: logo = Image.open(f) logo = logo.resize((600, 1250)) logo.save(img_path, "PNG") else: img_path = "app/src/main/res/drawable-nodpi-v4/pb_lbackground_1.png" logo = Image.open(background) logo = logo.resize((600, 1250)) logo.save(img_path, "PNG") def change_access(path_dest, access_model, package): access = ["CPAAS_MODE_FLOATING", "CPAAS_MODE_DOCKED", "CPAAS_MODE_BURGER"] path_package_id = package.replace(".", "/") code_path = "app/src/main/java/" code_path = os.path.join(path_dest, code_path, path_package_id, "util", "PrefsUtil.java") print(code_path) with open(code_path, "r") as f: file_source = f.read() replaced = file_source.replace("= CPAAS_MODE_DOCKED", "= {}".format(access[access_model])) with open(code_path, "w") as f: f.write(replaced) pass def change_certificate(path_dest, key, keyfile, keytool): keyfile_name = "{}.keystore".format(key["alias"]) keyfile_path = os.path.join(path_dest, keyfile_name) if keyfile: keyfile.save(keyfile_path) else: vprint("keytool run") os.chdir(path_dest) vprint("current working directory: ", os.getcwd()) dname = "CN={}, OU={}, O={}, L={}, S={}, C={}".format(key["common_name"], key["organization_unit"], key["organization_name"], key["locality_name"], key["state_name"], key["country"]) cmd = [keytool, "-genkey", "-v", "-keystore", keyfile_path, "-alias", key["alias"], "-keyalg", "RSA", "-keysize", "2048", "-validity", "10000", "-dname", dname, "-storepass", key["store_password"], "-keypass", key["key_password"]] vprint(cmd) subprocess.run(cmd) vprint("keytool end") build_gradle = os.path.join(path_dest, 'app/build.gradle') with open(build_gradle, "r") as f: file_source = f.read() replaced = file_source.replace("allyourbase", key["store_password"]) replaced = replaced.replace("arebelongto", key["key_password"]) replaced = replaced.replace("key-qmeralite", key["alias"]) with open(build_gradle, "w") as f: f.write(replaced) def run_build(path_dest): gradlew = os.path.join(path_dest, "gradlew") ret = subprocess.run([gradlew, 'assembleRelease']) if ret.returncode == 0: ret = subprocess.run([gradlew, 'bundleRelease']) return ret.returncode def deliver_apk(path_dest, package_id, key, key_exists): apk_dir = os.path.join(path_dest, 'app/build/outputs/apk/release/app-release.apk') aab_dir = os.path.join(path_dest, 'app/build/outputs/bundle/release/app-release.aab') keystore_name = '{}.keystore'.format(key["alias"]) keystore_dir = os.path.join(path_dest, keystore_name) timenow = time.time() apk_name = "{}{}.apk".format(package_id, timenow) aab_name = "{}{}.aab".format(package_id, timenow) zip_name = "{}{}.zip".format(package_id, timenow) new_apk_dir = os.path.join(app.apk_folder, apk_name) new_aab_dir = os.path.join(app.apk_folder, aab_name) new_dir = os.path.join(app.apk_folder, zip_name) vprint(apk_dir) try: shutil.move(apk_dir, new_apk_dir) shutil.move(aab_dir, new_aab_dir) with ZipFile(new_dir, 'w') as zip_file: zip_file.write(new_apk_dir, os.path.basename(new_apk_dir)) zip_file.write(new_aab_dir, os.path.basename(new_aab_dir)) if not key_exists: zip_file.write(keystore_dir, os.path.basename(keystore_dir)) os.remove(new_apk_dir) os.remove(new_aab_dir) project_path = os.path.join(app.temp_folder, package_id) shutil.rmtree(project_path) return {"name": zip_name} except Exception as e: return str(e) def change_version(path_dest, version_code, version_name): build_gradle = os.path.join(path_dest, 'app/build.gradle') with open(build_gradle, "r") as f: file_source = f.read() replaced = file_source.replace("versionCode 3", "versionCode {}".format(version_code)) replaced = replaced.replace('versionName "3.0"', 'versionName "{}"'.format(version_name)) with open(build_gradle, "w") as f: f.write(replaced) @app.route('/', methods=["GET", "POST"]) def build_apk(): vprint('==============================================================') if request.method == 'POST': logo = None logo_float = None app_name = "NexilisLite" package_id = "com.app.nexilis" acc = None url = None keystore = None key_exists = False # tabs = ["1", "2", "3", "4"] tabs = [] tab3_mode = "0" tab_icon = [None, None, None, None] fb_icon = [None, None, None, None, None] background = None version_code = "1" version_name = "1.0.0" font = 0 tab_amount = 4 key = {"alias": "nexilislite", "store_password": "allyourbase", "key_password": "arebelongto", "common_name": "all", "organization_unit": "your", "organization_name": "base", "locality_name": "are", "state_name": "belong", "country": "to"} if 'logo' in request.files: logo = request.files['logo'] vprint(type(logo)) elif 'logo' in request.form: logo = request.form['logo'] vprint(type(logo)) if 'logofloat' in request.files: logo_float = request.files['logofloat'] vprint(type(logo_float)) elif 'logofloat' in request.form: logo_float = request.form['logofloat'] vprint(type(logo_float)) if 'app_name' in request.files: app_name = request.files['app_name'] vprint(app_name) elif 'app_name' in request.form: app_name = request.form['app_name'] vprint(app_name) if 'package_id' in request.files: package_id = request.files['package_id'] vprint(package_id) elif 'package_id' in request.form: package_id = request.form['package_id'] vprint(package_id) if 'acc' in request.files: acc = request.files['acc'] vprint(acc) elif 'acc' in request.form: acc = request.form['acc'] vprint(acc) if 'url' in request.files: url = request.files['url'] vprint(url) elif 'url' in request.form: url = request.form['url'] vprint(url) if 'keystore' in request.files: keystore = request.files['keystore'] key_exists = True elif 'keystore' in request.form: keystore = request.form['keystore'] key_exists = True if 'alias' in request.form: if request.form['alias']: key["alias"] = request.form['alias'] if 'store_password' in request.form: if request.form['store_password']: key["store_password"] = request.form['store_password'] if 'key_password' in request.form: if request.form['key_password']: key["key_password"] = request.form['key_password'] if keystore: if 'common_name' in request.form: if request.form['common_name']: key["common_name"] = request.form['common_name'] if 'organization_unit' in request.form: if request.form['organization_unit']: key["organization_unit"] = request.form['organization_unit'] if 'organization_name' in request.form: if request.form['organization_name']: key["organization_name"] = request.form['organization_name'] if 'locality_name' in request.form: if request.form['locality_name']: key["locality_name"] = request.form['locality_name'] if 'state_name' in request.form: if request.form['state_name']: key["state_name"] = request.form['state_name'] if 'country' in request.form: if request.form['country']: key["country"] = request.form['country'] tabs.append(request.form["tab1"]) tabs.append(request.form["tab2"]) if request.form['tab3']: tabs.append(request.form["tab3"]) if request.form['tab4']: tabs.append(request.form["tab4"]) if 'tab1_icon' in request.files: tab_icon[0] = request.files['tab1_icon'] elif 'tab1_icon' in request.form: tab_icon[0] = request.form['tab1_icon'] if 'tab2_icon' in request.files: tab_icon[1] = request.files['tab2_icon'] elif 'tab2_icon' in request.form: tab_icon[1] = request.form['tab2_icon'] if 'tab3_icon' in request.files: tab_icon[2] = request.files['tab3_icon'] elif 'tab3_icon' in request.form: tab_icon[2] = request.form['tab3_icon'] if 'tab4_icon' in request.files: tab_icon[3] = request.files['tab4_icon'] elif 'tab4_icon' in request.form: tab_icon[3] = request.form['tab4_icon'] if 'fb1_icon' in request.files: fb_icon[0] = request.files['fb1_icon'] elif 'fb1_icon' in request.form: fb_icon[0] = request.form['fb1_icon'] if 'fb2_icon' in request.files: fb_icon[1] = request.files['fb2_icon'] elif 'fb2_icon' in request.form: fb_icon[1] = request.form['fb2_icon'] if 'fb3_icon' in request.files: fb_icon[2] = request.files['fb3_icon'] elif 'fb3_icon' in request.form: fb_icon[2] = request.form['fb3_icon'] if 'fb4_icon' in request.files: fb_icon[3] = request.files['fb4_icon'] elif 'fb4_icon' in request.form: fb_icon[3] = request.form['fb4_icon'] if 'fb5_icon' in request.files: fb_icon[4] = request.files['fb5_icon'] elif 'fb5_icon' in request.form: fb_icon[4] = request.form['fb5_icon'] vprint("fb_icon: {}".format(fb_icon)) access_model = int(request.form['access_model']) if 'tab3_mode' in request.form: tab3_mode = request.form['tab3_mode'] if 'tab_amount' in request.form: tab_amount = int(request.form['tab_amount']) if 'font' in request.form: font = int(request.form['font']) if 'background' in request.files: background = request.files['background'] elif 'background' in request.form: background = request.form['background'] if 'version_code' in request.form: version_code = request.form['version_code'] if 'version_name' in request.form: version_name = request.form['version_name'] else: version_name = "1.0.{}".format(version_code) path_dest, c_code_path = create_folder(package_id) vprint("path_dest: " + path_dest) vprint("c_code_path: " + c_code_path) if acc: change_acc(c_code_path, acc) if url: change_url(c_code_path, url) change_name(path_dest, app_name) change_certificate(path_dest, key, keystore, app.keytool) change_package(path_dest, package_id) change_version(path_dest, version_code,version_name) change_font(path_dest, font, package_id) if logo: change_logo(path_dest, logo, logo_float) if background: change_background(path_dest, background) change_fb(path_dest, fb_icon) change_access(path_dest, access_model, package_id) change_tab(path_dest, tabs, tab_icon, package_id, tab3_mode, tab_amount) os.chdir(path_dest) return_code = run_build(path_dest) if (return_code == 0): return deliver_apk(path_dest, package_id, key, key_exists) return "h" else: if 'e' in request.args: return request.args['e'] return "Hello World!" if __name__ == '__main__': app.run(host='0.0.0.0', port=8092, debug=app.verbose, ssl_context=app.ssl)