kevin 1 vuosi sitten
vanhempi
commit
a254aa8d15

+ 7 - 0
src/.dockerignore

@@ -0,0 +1,7 @@
+venv
+.dockerignore
+Dockerfile
+docker-compose.yaml
+AndroidSdk
+*.sh
+!check_jdk.sh

+ 26 - 0
src/Dockerfile

@@ -0,0 +1,26 @@
+# pull official base image
+FROM python:3.10-slim-buster
+
+# set work directory
+WORKDIR /usr/src/app
+
+# set environment variables
+ENV PYTHONDONTWRITEBYTECODE=1 \
+    PYTHONUNBUFFERED=1 \
+    ANDROID_SDK_ROOT=/usr/src/app/AndroidSdk
+
+# create user
+COPY ./check_jdk.sh ./requirements.txt ./
+RUN addgroup --gid 1000 user && \
+    adduser --disabled-password --gecos '' --uid 1000 --gid 1000 user && \
+    apt-get update && \
+    apt-get install -y apt-utils wget && \
+    bash check_jdk.sh && \
+    apt-get clean -y && \
+    pip install -r requirements.txt && \
+    pip cache purge && rm jdk-17.0.9_linux-x64_bin.deb
+
+# copy project
+COPY . .
+RUN chown -R user:user .
+USER user

+ 5 - 0
src/check_jdk.sh

@@ -0,0 +1,5 @@
+# For use in docker only
+while [ ! -f jdk-17.0.9_linux-x64_bin.deb ]; do
+    wget -c https://download.oracle.com/java/17/archive/jdk-17.0.9_linux-x64_bin.deb
+done
+apt-get install -y ./jdk-17.0.9_linux-x64_bin.deb

+ 88 - 0
src/docker-compose.yaml

@@ -0,0 +1,88 @@
+version: '3'
+services:
+  main_palio:
+    build: .
+    image: main_palio
+    container_name: main_palio
+    ports:
+      - "8054:8053"
+    command: python mainPalio-async.py
+    volumes:
+      - /apps/3ps/build_apk/PalioLite:/usr/src/app/PalioLite
+      - /apps/3ps/build_apk/BuildApk:/usr/src/app/BuildApk
+      - /var/www/html/palio.io/dashboardv2/uploads:/usr/src/app/uploads
+      - /etc/ssl/star.newuniverse.io:/usr/src/app/ssl
+      - ${ANDROID_SDK_ROOT}:/usr/src/app/AndroidSdk
+    environment:
+      - USER_ID=1000
+      - GROUP_ID=1000
+      - FLASK_DEBUG=1
+      - CELERY_BROKER_URL=redis://redis:6379/0
+      - CELERY_RESULT_BACKEND=redis://redis:6379/0
+      - ANDROID_SDK_ROOT=/usr/src/app/AndroidSdk
+  worker_palio:
+    build: .
+    image: main_palio
+    container_name: worker_palio
+    command: celery --app taskPalio.celery worker --loglevel=info
+    volumes:
+      - /apps/3ps/build_apk/PalioLite:/usr/src/app/PalioLite
+      - /apps/3ps/build_apk/BuildApk:/usr/src/app/BuildApk
+      - /var/www/html/palio.io/dashboardv2/uploads:/usr/src/app/uploads
+      - /etc/ssl/star.newuniverse.io:/usr/src/app/ssl
+      - ${ANDROID_SDK_ROOT}:/usr/src/app/AndroidSdk
+      - /home/easysoft/.gradle:/home/user/.gradle
+    environment:
+      - USER_ID=1000
+      - GROUP_ID=1000
+      - FLASK_DEBUG=1
+      - CELERY_BROKER_URL=redis://redis:6379/0
+      - CELERY_RESULT_BACKEND=redis://redis:6379/0
+      - ANDROID_SDK_ROOT=/usr/src/app/AndroidSdk
+    depends_on:
+      - main_palio
+      - redis
+  main_palio_sa:
+    build: .
+    image: main_palio
+    container_name: main_palio_sa
+    ports:
+      - "8014:8013"
+    command: python mainPalioSA-async.py
+    volumes:
+      - /apps/3ps/build_apk/PalioLiteSA:/usr/src/app/PalioLiteSA
+      - /apps/3ps/build_apk/BuildApkSA:/usr/src/app/BuildApkSA
+      - /var/www/html/palio.io/dashboardv2/uploads:/usr/src/app/uploads
+      - /etc/ssl/star.newuniverse.io:/usr/src/app/ssl
+      - ${ANDROID_SDK_ROOT}:/usr/src/app/AndroidSdk
+    environment:
+      - USER_ID=1000
+      - GROUP_ID=1000
+      - FLASK_DEBUG=1
+      - CELERY_BROKER_URL=redis://redis:6379/0
+      - CELERY_RESULT_BACKEND=redis://redis:6379/0
+      - ANDROID_SDK_ROOT=/usr/src/app/AndroidSdk
+  worker_palio_sa:
+    build: .
+    image: main_palio
+    container_name: worker_palio_sa
+    command: celery --app taskPalioSA.celery worker --loglevel=info
+    volumes:
+      - /apps/3ps/build_apk/PalioLiteSA:/usr/src/app/PalioLiteSA
+      - /apps/3ps/build_apk/BuildApkSA:/usr/src/app/BuildApkSA
+      - /var/www/html/palio.io/dashboardv2/uploads:/usr/src/app/uploads
+      - /etc/ssl/star.newuniverse.io:/usr/src/app/ssl
+      - ${ANDROID_SDK_ROOT}:/usr/src/app/AndroidSdk
+      - /home/easysoft/.gradle:/home/user/.gradle
+    environment:
+      - USER_ID=1000
+      - GROUP_ID=1000
+      - FLASK_DEBUG=1
+      - CELERY_BROKER_URL=redis://redis:6379/0
+      - CELERY_RESULT_BACKEND=redis://redis:6379/0
+      - ANDROID_SDK_ROOT=/usr/src/app/AndroidSdk
+    depends_on:
+      - main_palio_sa
+      - redis
+  redis:
+    image: redis:6-buster

+ 9 - 0
src/docker_build_test.sh

@@ -0,0 +1,9 @@
+#!/bin/bash
+
+docker build --build-arg USER_ID=1000 \
+  --build-arg GROUP_ID=1000 \
+  -t test_permission .
+docker run -it --rm -v /apps/3ps/build_apk/PalioLite:/usr/src/app/PalioLite \
+  -v /apps/3ps/build_apk/BuildApk:/usr/src/app/BuildApk \
+  -v $ANDROID_SDK_ROOT:/usr/src/app/AndroidSdk \
+  test_permission bash

+ 270 - 0
src/mainPalio-async.py

@@ -0,0 +1,270 @@
+import os
+import traceback
+
+from PIL import ImageFile
+from celery.result import AsyncResult
+from flask import Flask, request
+
+import project_config
+from taskPalio import create_task
+
+ImageFile.SAFEBLOCK = 2048 * 2048
+
+app = Flask(__name__)
+app.base_project_name = os.path.basename(project_config.base_project)
+
+
+def vprint(*data):
+    if project_config.verbose:
+        print(*data)
+
+
+@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
+        huawei_file = None
+        fms_enable = 1
+        use_adblock = 0
+        key_exists = False
+        # tabs = ["1", "2", "3", "4"]
+        fb_order = "1,2,3,4,5"
+        tabs = []
+        tab3_mode = "0"
+        tab_amount = 6
+        tab_icon = [None, None, None, None, None, None]
+        fb_icon = [None, None, None, None, None]
+        background = None
+        version_code = "1"
+        version_name = "1.0.0"
+        font = 0
+        enable_sms = 0
+        enable_location = 0
+        key = {"alias": "nexilislite", "store_password": "allyourbase", "key_password": "allyourbase",
+               "common_name": "all", "organization_unit": "your",
+               "organization_name": "base", "locality_name": "are", "state_name": "belong", "country": "to"}
+        try:
+            if 'logo' in request.files:
+                logo = request.files['logo'].read()
+                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'].read()
+                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'].read()
+                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'].read()
+                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'].read()
+                vprint(acc)
+            elif 'acc' in request.form:
+                acc = request.form['acc']
+                vprint(acc)
+
+            if 'url' in request.files:
+                url = request.files['url'].read()
+                vprint(url)
+            elif 'url' in request.form:
+                url = request.form['url']
+                vprint(url)
+
+            if 'keystore' in request.files:
+                keystore = request.files['keystore'].read()
+                key_exists = True
+            elif 'keystore' in request.form:
+                keystore = request.form['keystore']
+                key_exists = True
+
+            if 'huawei_file' in request.files:
+                huawei_file = request.files['huawei_file'].read()
+            elif 'huawei_file' in request.form:
+                huawei_file = request.form['huawei_file']
+
+            if 'fms_enable' in request.form:
+                fms_enable = int(request.form['fms_enable'])
+
+            if 'use_adblock' in request.form:
+                use_adblock = int(request.form['use_adblock'])
+
+            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'].read()
+            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'].read()
+            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'].read()
+            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'].read()
+            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'].read()
+            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'].read()
+            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'].read()
+            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'].read()
+            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'].read()
+            elif 'fb5_icon' in request.form:
+                fb_icon[4] = request.form['fb5_icon']
+            if 'fb_icon' in request.form:
+                fb_icon = request.form['fb_icon'].split(",")
+            if 'fb_order' in request.form:
+                fb_order = request.form['fb_order']
+            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'].read()
+            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)
+            if 'enable_sms' in request.form:
+                enable_sms = int(request.form['enable_sms'])
+            if 'enable_location' in request.form:
+                enable_location = int(request.form['enable_location'])
+        except BaseException as e:
+            vprint(traceback.format_exc())
+            return {"status": "1", "message": "Parameter mismatch\n{}\n".format(str(e))}, 400
+        try:
+            vprint("package_id: ", type(package_id))
+            vprint("enable_sms: ", type(enable_sms))
+            vprint("app_name: ", type(app_name))
+            vprint("key: ", type(key))
+            vprint("keystore: ", type(keystore))
+            vprint("access_model: ", type(access_model))
+            vprint("version_code: ", type(version_code))
+            vprint("version_name: ", type(version_name))
+            vprint("enable_location: ", type(enable_location))
+            vprint("font: ", type(font))
+            vprint("fb_order: ", type(fb_order))
+            vprint("tabs: ", type(tabs))
+            vprint("tab_icon: ", type(tab_icon))
+            vprint("fb_icon: ", type(fb_icon))
+            vprint("tab3_mode: ", type(tab3_mode))
+            vprint("tab_amount: ", type(tab_amount))
+            vprint("huawei_file: ", type(huawei_file))
+            vprint("fms_enable: ", type(fms_enable))
+            vprint("use_adblock: ", type(use_adblock))
+            vprint("key_exists: ", type(key_exists))
+            vprint("acc: ", type(acc))
+            vprint("logo: ", type(logo))
+            vprint("logo_float: ", type(logo_float))
+            vprint("background: ", type(background))
+            vprint("url: ", type(url))
+            task = create_task.delay(package_id, enable_sms, app_name, key, keystore, access_model,
+                                     version_code, version_name, enable_location, font, fb_order, fb_icon, tabs,
+                                     tab_icon, tab3_mode,
+                                     tab_amount, huawei_file, fms_enable, use_adblock, key_exists,
+                                     acc=acc, logo=logo, logo_float=logo_float, background=background, url=url)
+            return {"status": "0", "task_id": f"{task.id}"}, 200
+        except BaseException as e:
+            vprint(traceback.format_exc())
+            return {"status": "2", "message": "Process failure\n{}\n".format(str(e))}, 200
+    else:
+        if 'e' in request.args:
+            return request.args['e']
+        return "Hello World!"
+
+
+@app.route('/task/<task_id>', methods=['GET'])
+def get_task(task_id):
+    task_result = AsyncResult(task_id)
+    if task_result.state == 'SUCCESS':
+        if task_result.result is None:
+            return {"status": "2", "message": "Process failure"}, 200
+        elif task_result.result['status'] == '0':
+            return task_result.result, 200
+        else:
+            return task_result.result, 200
+    elif task_result.state == 'FAILURE':
+        return {"status": "2", "message": "Process failure"}, 200
+    else:
+        return {"status": "5", "message": f"Process is in {task_result.state} state."}, 200
+
+
+if __name__ == '__main__':
+    app.run(host='0.0.0.0', port=8053, debug=project_config.verbose, ssl_context=project_config.ssl)

+ 270 - 0
src/mainPalioSA-async.py

@@ -0,0 +1,270 @@
+import os
+import traceback
+
+from PIL import ImageFile
+from celery.result import AsyncResult
+from flask import Flask, request
+
+import project_config_SA
+from taskPalioSA import create_task
+
+ImageFile.SAFEBLOCK = 2048 * 2048
+
+app = Flask(__name__)
+app.base_project_name = os.path.basename(project_config_SA.base_project)
+
+
+def vprint(*data):
+    if project_config_SA.verbose:
+        print(*data)
+
+
+@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
+        huawei_file = None
+        fms_enable = 1
+        use_adblock = 0
+        key_exists = False
+        # tabs = ["1", "2", "3", "4"]
+        fb_order = "1,2,3,4,5"
+        tabs = []
+        tab3_mode = "0"
+        tab_amount = 6
+        tab_icon = [None, None, None, None, None, None]
+        fb_icon = [None, None, None, None, None]
+        background = None
+        version_code = "1"
+        version_name = "1.0.0"
+        font = 0
+        enable_sms = 0
+        enable_location = 0
+        key = {"alias": "nexilislite", "store_password": "allyourbase", "key_password": "allyourbase",
+               "common_name": "all", "organization_unit": "your",
+               "organization_name": "base", "locality_name": "are", "state_name": "belong", "country": "to"}
+        try:
+            if 'logo' in request.files:
+                logo = request.files['logo'].read()
+                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'].read()
+                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'].read()
+                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'].read()
+                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'].read()
+                vprint(acc)
+            elif 'acc' in request.form:
+                acc = request.form['acc']
+                vprint(acc)
+
+            if 'url' in request.files:
+                url = request.files['url'].read()
+                vprint(url)
+            elif 'url' in request.form:
+                url = request.form['url']
+                vprint(url)
+
+            if 'keystore' in request.files:
+                keystore = request.files['keystore'].read()
+                key_exists = True
+            elif 'keystore' in request.form:
+                keystore = request.form['keystore']
+                key_exists = True
+
+            if 'huawei_file' in request.files:
+                huawei_file = request.files['huawei_file'].read()
+            elif 'huawei_file' in request.form:
+                huawei_file = request.form['huawei_file']
+
+            if 'fms_enable' in request.form:
+                fms_enable = int(request.form['fms_enable'])
+
+            if 'use_adblock' in request.form:
+                use_adblock = int(request.form['use_adblock'])
+
+            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'].read()
+            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'].read()
+            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'].read()
+            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'].read()
+            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'].read()
+            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'].read()
+            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'].read()
+            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'].read()
+            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'].read()
+            elif 'fb5_icon' in request.form:
+                fb_icon[4] = request.form['fb5_icon']
+            if 'fb_icon' in request.form:
+                fb_icon = request.form['fb_icon'].split(",")
+            if 'fb_order' in request.form:
+                fb_order = request.form['fb_order']
+            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'].read()
+            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)
+            if 'enable_sms' in request.form:
+                enable_sms = int(request.form['enable_sms'])
+            if 'enable_location' in request.form:
+                enable_location = int(request.form['enable_location'])
+        except BaseException as e:
+            vprint(traceback.format_exc())
+            return {"status": "1", "message": "Parameter mismatch\n{}\n".format(str(e))}, 400
+        try:
+            vprint("package_id: ", type(package_id))
+            vprint("enable_sms: ", type(enable_sms))
+            vprint("app_name: ", type(app_name))
+            vprint("key: ", type(key))
+            vprint("keystore: ", type(keystore))
+            vprint("access_model: ", type(access_model))
+            vprint("version_code: ", type(version_code))
+            vprint("version_name: ", type(version_name))
+            vprint("enable_location: ", type(enable_location))
+            vprint("font: ", type(font))
+            vprint("fb_order: ", type(fb_order))
+            vprint("tabs: ", type(tabs))
+            vprint("tab_icon: ", type(tab_icon))
+            vprint("fb_icon: ", type(fb_icon))
+            vprint("tab3_mode: ", type(tab3_mode))
+            vprint("tab_amount: ", type(tab_amount))
+            vprint("huawei_file: ", type(huawei_file))
+            vprint("fms_enable: ", type(fms_enable))
+            vprint("use_adblock: ", type(use_adblock))
+            vprint("key_exists: ", type(key_exists))
+            vprint("acc: ", type(acc))
+            vprint("logo: ", type(logo))
+            vprint("logo_float: ", type(logo_float))
+            vprint("background: ", type(background))
+            vprint("url: ", type(url))
+            task = create_task.delay(package_id, enable_sms, app_name, key, keystore, access_model,
+                                     version_code, version_name, enable_location, font, fb_order, fb_icon, tabs,
+                                     tab_icon, tab3_mode,
+                                     tab_amount, huawei_file, fms_enable, use_adblock, key_exists,
+                                     acc=acc, logo=logo, logo_float=logo_float, background=background, url=url)
+            return {"status": "0", "task_id": f"{task.id}"}, 200
+        except BaseException as e:
+            vprint(traceback.format_exc())
+            return {"status": "2", "message": "Process failure\n{}\n".format(str(e))}, 200
+    else:
+        if 'e' in request.args:
+            return request.args['e']
+        return "Hello World!"
+
+
+@app.route('/task/<task_id>', methods=['GET'])
+def get_task(task_id):
+    task_result = AsyncResult(task_id)
+    if task_result.state == 'SUCCESS':
+        if task_result.result is None:
+            return {"status": "2", "message": "Process failure"}, 200
+        elif task_result.result['status'] == '0':
+            return task_result.result, 200
+        else:
+            return task_result.result, 200
+    elif task_result.state == 'FAILURE':
+        return {"status": "2", "message": "Process failure"}, 200
+    else:
+        return {"status": "5", "message": f"Process is in {task_result.state} state."}, 200
+
+
+if __name__ == '__main__':
+    app.run(host='0.0.0.0', port=8013, debug=project_config_SA.verbose, ssl_context=project_config_SA.ssl)

+ 10 - 0
src/project_config.py

@@ -0,0 +1,10 @@
+import os
+
+base_project = "/usr/src/app/PalioLite"
+temp_folder = "/usr/src/app/BuildApk"
+apk_folder = "/usr/src/app/uploads"
+ssl = ('/usr/src/app/ssl/STAR_newuniverse_io.crt', '/usr/src/app/ssl/STAR_newuniverse.io.key')
+# ssl = None
+keytool = '/usr/bin/keytool'
+verbose = True
+base_project_name = os.path.basename(base_project)

+ 10 - 0
src/project_config_SA.py

@@ -0,0 +1,10 @@
+import os
+
+base_project = "/usr/src/app/PalioLiteSA"
+temp_folder = "/usr/src/app/BuildApkSA"
+apk_folder = "/usr/src/app/uploads"
+ssl = ('/usr/src/app/ssl/STAR_newuniverse_io.crt', '/usr/src/app/ssl/STAR_newuniverse.io.key')
+# ssl = None
+keytool = '/usr/bin/keytool'
+verbose = True
+base_project_name = os.path.basename(base_project)

+ 2 - 11
src/requirements.txt

@@ -1,16 +1,7 @@
-certifi==2021.10.8
-charset-normalizer==2.0.7
-click==8.0.3
+celery==5.2.3
+redis==4.1.4
 Flask==2.0.2
-idna==3.3
-importlib-metadata==4.8.1
-itsdangerous==2.0.1
-Jinja2==3.0.2
-MarkupSafe==2.0.1
 Pillow==8.4.0
 requests==2.26.0
-typing-extensions==3.10.0.2
-urllib3==1.26.7
 Werkzeug==2.0.2
-zipp==3.6.0
 gunicorn==20.1.0

+ 4 - 0
src/start_docker.sh

@@ -0,0 +1,4 @@
+#!/bin/bash
+
+docker-compose build && docker-compose up "$@"
+# "./start_docker -d" to run in background

+ 3 - 0
src/stop_docker.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+docker-compose down

+ 693 - 0
src/taskPalio.py

@@ -0,0 +1,693 @@
+from io import BytesIO
+import os
+import shutil
+import subprocess
+import time
+from zipfile import ZipFile
+
+import requests
+from werkzeug.datastructures import FileStorage
+from PIL import Image
+from celery import Celery
+
+import project_config
+
+
+def vprint(*data):
+    if project_config.verbose:
+        print(*data)
+
+
+celery = Celery(__name__)
+celery.conf.broker_url = os.environ.get("CELERY_BROKER_URL", "redis://localhost:6379")
+celery.conf.result_backend = os.environ.get("CELERY_RESULT_BACKEND", "redis://localhost:6379")
+celery.conf.task_track_started = True
+
+
+def create_folder(package_id):
+    path = os.path.join(project_config.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, project_config.base_project_name)
+    if not os.path.exists(path_dest):
+        shutil.copytree(project_config.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, enable_sms):
+    main_activity = os.path.join(c_code_path, "MAB.java")
+    with open(main_activity, "r") as f:
+        file_source = f.read()
+    replaced = file_source.replace("***REPLACE***WITH***YOUR***QMERA***ACCOUNT***", acc)
+    if enable_sms == 1:
+        replaced = replaced.replace("isEnabledSMS = false", "isEnabledSMS = true")
+    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, "MAB.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, enable_sms):
+    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:
+        lines = f.readlines()
+        # file_source = f.read()
+    with open(manifest, "w") as f:
+        for line in lines:
+            if "NexilisLite" in line:
+                line = line.replace("NexilisLite", name)
+            if enable_sms == 0:
+                if "SMS" not in line:
+                    f.write(line)
+            else:
+                f.write(line)
+    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)
+
+    if enable_sms == 0:
+        with open(manifest, "r") as f:
+            lines = f.readlines()
+        with open(manifest, "w") as f:
+            counter = 0
+            for line in lines:
+                if counter == 0:
+                    if "<receiver" in line:
+                        counter = 6
+                    else:
+                        f.write(line)
+                else:
+                    counter = counter - 1
+
+
+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, enable_location):
+    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)
+
+    queue_page = os.path.join(path_dest, code_path, "QueueBank.java")
+    with open(queue_page, "r") as f:
+        lines = f.readlines()
+    with open(queue_page, "w") as f:
+        counter = 0
+        for line in lines:
+            if counter == 0:
+                if enable_location == 0 and "LocationOn1" in line:
+                    counter = 9
+                if enable_location == 0 and "LocationOn2" in line:
+                    counter = 17
+                else:
+                    f.write(line)
+            else:
+                counter = counter - 1
+
+    manifest = os.path.join(path_dest, "app/src/main/AndroidManifest.xml")
+    with open(manifest, "r") as f:
+        lines = f.readlines()
+    with open(manifest, "w") as f:
+        counter = 0
+        for line in lines:
+            if counter == 0:
+                if enable_location == 0 and "<!-- LocationOn/Off -->" in line:
+                    counter = 3
+                else:
+                    f.write(line)
+            else:
+                counter = counter - 1
+
+    if package.__contains__('digipos') or package.__contains__('digisales'):
+        settings_gradle = os.path.join(path_dest, "settings.gradle")
+        with open(settings_gradle, "r") as f:
+            lines = f.readlines()
+        with open(settings_gradle, "w") as f:
+            counter = 0
+            for line in lines:
+                if counter == 0:
+                    if "forallapps" in line:
+                        counter = 5
+                    else:
+                        f.write(line)
+                else:
+                    counter = counter - 1
+
+        mab_path = os.path.join(path_dest, code_path, "MAB.java")
+        with open(mab_path, "r") as f:
+            lines = f.readlines()
+        with open(mab_path, "w") as f:
+            counter1 = 0
+            counter2 = 0
+            for line in lines:
+                if "fordigisales1" in line:
+                    counter1 = 132
+                elif "fordigisales2" in line:
+                    counter2 = 46
+                elif counter1 > 0:
+                    counter1 = counter1 - 1
+                elif counter2 > 0:
+                    counter2 = counter2 - 1
+                else:
+                    f.write(line)
+
+        notif_center = os.path.join(path_dest, code_path, "notificationCenterTab/NotificationCenterFragment.java")
+        with open(notif_center, "r") as f:
+            lines = f.readlines()
+        with open(notif_center, "w") as f:
+            counter = 0
+            for line in lines:
+                if counter == 0:
+                    if "fordigisales" in line:
+                        counter = 14
+                    else:
+                        f.write(line)
+                else:
+                    counter = counter - 1
+    else:
+        settings_gradle = os.path.join(path_dest, "settings.gradle")
+        with open(settings_gradle, "r") as f:
+            lines = f.readlines()
+        with open(settings_gradle, "w") as f:
+            counter = 0
+            for line in lines:
+                if counter == 0:
+                    if "fordigisales" in line:
+                        counter = 5
+                    else:
+                        f.write(line)
+                else:
+                    counter = counter - 1
+        colorValue = os.path.join(path_dest, "app/src/main/res/values/colors.xml")
+        with open(colorValue, "r") as c:
+            lines = c.readlines()
+        with open(colorValue, "w") as c:
+            for lineColor in lines:
+                if "fordigisales" in lineColor:
+                    continue
+                else:
+                    c.write(lineColor)
+
+    if package == "com.nexilis.persija" or package == "io.newuniverse.GoToMalls" or package == "io.qmera.mylab":
+        string_res = os.path.join(path_dest, "app/src/main/res/values/strings.xml")
+        string_en_res = os.path.join(path_dest, "app/src/main/res/values-en/strings.xml")
+        string_id_res = os.path.join(path_dest, "app/src/main/res/values-in/strings.xml")
+        with open(string_res, "r") as f:
+            file_source = f.read()
+        replaced = file_source.replace("Nexilis", "Qmera")
+        with open(string_res, "w") as f:
+            f.write(replaced)
+        with open(string_en_res, "r") as f:
+            file_source = f.read()
+        replaced = file_source.replace("Nexilis", "Qmera")
+        with open(string_en_res, "w") as f:
+            f.write(replaced)
+        with open(string_id_res, "r") as f:
+            file_source = f.read()
+        replaced = file_source.replace("Nexilis", "Qmera")
+        with open(string_id_res, "w") as f:
+            f.write(replaced)
+
+        old_img_powered = "app/src/main/res/drawable/pb_powered_button.png"
+        old_img_powered = os.path.join(path_dest, old_img_powered)
+        old_new_img_powered = "app/src/main/res/drawable/pb_powered_button_temp.png"
+        old_new_img_powered = os.path.join(path_dest, old_new_img_powered)
+        shutil.move(old_img_powered, old_new_img_powered)
+
+        img_powered = "app/src/main/res/drawable/pb_powered_button1.png"
+        img_powered = os.path.join(path_dest, img_powered)
+        new_img_powered = "app/src/main/res/drawable/pb_powered_button.png"
+        new_img_powered = os.path.join(path_dest, new_img_powered)
+        shutil.move(img_powered, new_img_powered)
+
+    if package == "com.telkomsel.smb":
+        string_res = os.path.join(path_dest, "app/src/main/res/values/strings.xml")
+        string_en_res = os.path.join(path_dest, "app/src/main/res/values-en/strings.xml")
+        string_id_res = os.path.join(path_dest, "app/src/main/res/values-in/strings.xml")
+        with open(string_res, "r") as f:
+            file_source = f.read()
+        replaced = file_source.replace("Nexilis", "Telkomsel")
+        with open(string_res, "w") as f:
+            f.write(replaced)
+        with open(string_en_res, "r") as f:
+            file_source = f.read()
+        replaced = file_source.replace("Nexilis", "Telkomsel")
+        with open(string_en_res, "w") as f:
+            f.write(replaced)
+        with open(string_id_res, "r") as f:
+            file_source = f.read()
+        replaced = file_source.replace("Nexilis", "Telkomsel")
+        with open(string_id_res, "w") as f:
+            f.write(replaced)
+
+        old_img_powered = "app/src/main/res/drawable/pb_powered_button.png"
+        old_img_powered = os.path.join(path_dest, old_img_powered)
+        old_new_img_powered = "app/src/main/res/drawable/pb_powered_button_temp.png"
+        old_new_img_powered = os.path.join(path_dest, old_new_img_powered)
+        shutil.move(old_img_powered, old_new_img_powered)
+
+        img_powered = "app/src/main/res/drawable/pb_powered_button2.png"
+        img_powered = os.path.join(path_dest, img_powered)
+        new_img_powered = "app/src/main/res/drawable/pb_powered_button.png"
+        new_img_powered = os.path.join(path_dest, new_img_powered)
+        shutil.move(img_powered, new_img_powered)
+
+
+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/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://digixplatform.com/dashboardv2/uploads/logo/{}'.format(logo), verify=False)
+        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://digixplatform.com/dashboardv2/uploads/logofloat/{}'.format(logo_float),
+                                      verify=False)
+            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(BytesIO(logo))
+        logo = logo.resize((512, 512))
+        if logo_float:
+            logo_float = Image.open(BytesIO(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 = ["tab{}.png".format(x) for x in tabs]
+    for i, icon in enumerate(default_tab_icon):
+        if not tab_icon[i]:
+            continue
+        img_path = "app/src/main/res/drawable"
+        img_path = os.path.join(path_dest, img_path, icon)
+        if isinstance(tab_icon[i], str):
+            logo = requests.get('https://digixplatform.com/dashboardv2/uploads/tab_icon/{}'.format(tab_icon[i]),
+                                verify=False)
+            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(BytesIO(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, "MAB.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_order, package, fb_icon):
+    fb_order_list = [int(x) for x in fb_order.split(",")]
+    default_fb_icon = ["pb_button_chat.png", "pb_button_call.png", "pb_button_cc.png", "pb_button_stream.png",
+                       "nexilis_fb_04.png"]
+    for x, i in enumerate(fb_order_list):
+        if not fb_icon[x]:
+            continue
+        img_path = "app/src/main/res/drawable-nodpi"
+        if i - 1 in range(-len(default_fb_icon), len(default_fb_icon)):
+            img_path = os.path.join(path_dest, img_path, default_fb_icon[i - 1])
+            if isinstance(fb_icon[x], str):
+                logo = requests.get('https://digixplatform.com/dashboardv2/uploads/fb_icon/{}'.format(fb_icon[x]),
+                                    verify=False)
+                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(BytesIO(fb_icon[x]))
+                logo = logo.resize((150, 150))
+                logo.save(img_path, "PNG")
+    path_package_id = package.replace(".", "/")
+    code_path = "app/src/main/java/"
+    main_code_path = os.path.join(path_dest, code_path, path_package_id, "MAB.java")
+    with open(main_code_path, "r") as f:
+        file_source = f.read()
+    replaced = file_source.replace('dockedPlacement = "1,2,3,4,5"', 'dockedPlacement = "{}"'.format(fb_order))
+    with open(main_code_path, "w") as f:
+        f.write(replaced)
+
+
+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/pb_lbackground_{}.png".format(n)
+    #         img_path = os.path.join(path_dest, img_path)
+    #         logo = requests.get('https://digixplatform.com/dashboardv2/uploads/background/{}'.format(b), verify=False)
+    #         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/pb_lbackground_1.png"
+    #     logo = Image.open(BytesIO(background))
+    #     logo = logo.resize((600, 1250))
+    #     logo.save(img_path, "PNG")
+    pass
+
+
+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)
+
+
+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:
+        if isinstance(keyfile, FileStorage):
+            keyfile.save(keyfile_path)
+        else:
+            with open(keyfile_path, 'wb') as f:
+                f.write(keyfile)
+    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 change_huawei_file(path_dest, huawei_file, package_id):
+    huaweifile_name = "agconnect-services.json"
+    huaweifile_path = os.path.join(path_dest, "app/{}".format(huaweifile_name))
+    if huawei_file:
+        huawei_file.save(huaweifile_path)
+        path_package_id = package_id.replace(".", "/")
+        code_path = "app/src/main/java/"
+        main_code_path = os.path.join(path_dest, code_path, path_package_id, "MAB.java")
+        with open(main_code_path, "r") as f:
+            file_source = f.read()
+        replaced = file_source.replace('isHMSEnabled = false', 'isHMSEnabled = true')
+        with open(main_code_path, "w") as f:
+            f.write(replaced)
+
+
+def change_fms_file(path_dest, fms_enable):
+    build_gradle = os.path.join(path_dest, 'app/build.gradle')
+    with open(build_gradle, "r") as f:
+        lines = f.readlines()
+    with open(build_gradle, "w") as f:
+        if fms_enable == 0:
+            for line in lines:
+                if "withfcm" in line:
+                    continue
+                else:
+                    f.write(line)
+        else:
+            for line in lines:
+                if "-nofcm" in line:
+                    continue
+                else:
+                    f.write(line)
+
+
+def change_adblock_file(path_dest, package, use_adblock):
+    if use_adblock == 0:
+        build_gradle = os.path.join(path_dest, 'app/build.gradle')
+        with open(build_gradle, "r") as f:
+            lines = f.readlines()
+        with open(build_gradle, "w") as f:
+            for line in lines:
+                if "removeAdblock" in line:
+                    continue
+                else:
+                    f.write(line)
+
+        path_package_id = package.replace(".", "/")
+        code_path = "app/src/main/java/"
+        code_path = os.path.join(path_dest, code_path, path_package_id)
+        javas = [os.path.join(dp, f) for dp, dn, filenames in os.walk(code_path) for f in filenames]
+        for j in javas:
+            print(j)
+            with open(j, "r") as f:
+                lines = f.readlines()
+            with open(j, "w") as f:
+                counter = 0
+                for line in lines:
+                    if counter == 0:
+                        if "removeAdblock" in line:
+                            continue
+                        elif "import org.adblockplus.libadblockplus.android" in line:
+                            continue
+                        elif "removeAdbMultiLine" in line:
+                            counter = 11
+                        elif "extends AdblockWebView" in line:
+                            replaced = line.replace("extends AdblockWebView", "extends WebView")
+                            f.write(replaced)
+                        else:
+                            f.write(line)
+                    else:
+                        counter = counter - 1
+
+
+def run_build(path_dest):
+    gradlew = os.path.join(path_dest, "gradlew")
+    error = ""
+    ret = subprocess.run([gradlew, 'clean', 'assembleRelease'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    if ret.returncode == 0:
+        ret = subprocess.run([gradlew, 'bundleRelease'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        if ret.returncode != 0:
+            error = "{}\n".format(ret.stderr.decode())
+            vprint(error)
+    else:
+        error = "{}\n".format(ret.stderr.decode())
+        vprint(error)
+    return ret.returncode, error
+
+
+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(project_config.apk_folder, apk_name)
+    new_aab_dir = os.path.join(project_config.apk_folder, aab_name)
+    new_dir = os.path.join(project_config.apk_folder, zip_name)
+    vprint(apk_dir)
+    shutil.move(apk_dir, new_apk_dir)
+    try:
+        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(project_config.temp_folder, package_id)
+        shutil.rmtree(project_path)
+        return {"status": "0", "name": zip_name}
+    except Exception as e:
+        return {"status": "4", "message": "Deliver APK & AAB failed\n{}".format(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)
+
+
+@celery.task(name="create_task")
+def create_task(package_id, enable_sms, app_name, key, keystore, access_model,
+                version_code, version_name, enable_location, font, fb_order, fb_icon, tabs, tab_icon, tab3_mode,
+                tab_amount, huawei_file, fms_enable, use_adblock, key_exists,
+                acc=None, logo=None, logo_float=None, background=None, url=None):
+    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, enable_sms)
+    if url:
+        change_url(c_code_path, url)
+    change_name(path_dest, app_name, enable_sms)
+    change_certificate(path_dest, key, keystore, project_config.keytool)
+    change_package(path_dest, package_id, enable_location)
+    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_order, package_id, fb_icon)
+    change_access(path_dest, access_model, package_id)
+    change_tab(path_dest, tabs, tab_icon, package_id, tab3_mode, tab_amount)
+    change_huawei_file(path_dest, huawei_file, package_id)
+    change_fms_file(path_dest, fms_enable)
+    change_adblock_file(path_dest, package_id, use_adblock)
+    os.chdir(path_dest)
+    return_code, error = run_build(path_dest)
+    if return_code == 0:
+        return deliver_apk(path_dest, package_id, key, key_exists)
+    return {"status": "3", "message": "Build failed\n{}".format(str(error))}

+ 676 - 0
src/taskPalioSA.py

@@ -0,0 +1,676 @@
+from io import BytesIO
+import os
+import shutil
+import subprocess
+import time
+from zipfile import ZipFile
+
+import requests
+from werkzeug.datastructures import FileStorage
+from PIL import Image
+from celery import Celery
+
+import project_config_SA
+
+
+def vprint(*data):
+    if project_config_SA.verbose:
+        print(*data)
+
+
+celery = Celery(__name__)
+celery.conf.broker_url = os.environ.get("CELERY_BROKER_URL", "redis://localhost:6379")
+celery.conf.result_backend = os.environ.get("CELERY_RESULT_BACKEND", "redis://localhost:6379")
+celery.conf.task_track_started = True
+
+
+def create_folder(package_id):
+    path = os.path.join(project_config_SA.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, project_config_SA.base_project_name)
+    if not os.path.exists(path_dest):
+        shutil.copytree(project_config_SA.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, enable_sms):
+    main_activity = os.path.join(c_code_path, "MAB.java")
+    with open(main_activity, "r") as f:
+        file_source = f.read()
+    replaced = file_source.replace("***REPLACE***WITH***YOUR***QMERA***ACCOUNT***", acc)
+    if enable_sms == 1:
+        replaced = replaced.replace("isEnabledSMS = false", "isEnabledSMS = true")
+    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, "MAB.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, enable_sms):
+    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:
+        lines = f.readlines()
+        # file_source = f.read()
+    with open(manifest, "w") as f:
+        for line in lines:
+            if "NexilisLite" in line:
+                line = line.replace("NexilisLite", name)
+            if enable_sms == 0:
+                if "SMS" not in line:
+                    f.write(line)
+            else:
+                f.write(line)
+    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, enable_location):
+    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)
+
+    queue_page = os.path.join(path_dest, code_path, "QueueBank.java")
+    with open(queue_page, "r") as f:
+        lines = f.readlines()
+    with open(queue_page, "w") as f:
+        counter = 0
+        for line in lines:
+            if counter == 0:
+                if enable_location == 0 and "LocationOn1" in line:
+                    counter = 9
+                if enable_location == 0 and "LocationOn2" in line:
+                    counter = 17
+                else:
+                    f.write(line)
+            else:
+                counter = counter - 1
+
+    manifest = os.path.join(path_dest, "app/src/main/AndroidManifest.xml")
+    with open(manifest, "r") as f:
+        lines = f.readlines()
+    with open(manifest, "w") as f:
+        counter = 0
+        for line in lines:
+            if counter == 0:
+                if enable_location == 0 and "<!-- LocationOn/Off -->" in line:
+                    counter = 3
+                else:
+                    f.write(line)
+            else:
+                counter = counter - 1
+
+    if package.__contains__('digipos') or package.__contains__('digisales'):
+        settings_gradle = os.path.join(path_dest, "settings.gradle")
+        with open(settings_gradle, "r") as f:
+            lines = f.readlines()
+        with open(settings_gradle, "w") as f:
+            counter = 0
+            for line in lines:
+                if counter == 0:
+                    if "forallapps" in line:
+                        counter = 5
+                    else:
+                        f.write(line)
+                else:
+                    counter = counter - 1
+
+        mab_path = os.path.join(path_dest, code_path, "MAB.java")
+        with open(mab_path, "r") as f:
+            lines = f.readlines()
+        with open(mab_path, "w") as f:
+            counter1 = 0
+            counter2 = 0
+            for line in lines:
+                if "fordigisales1" in line:
+                    counter1 = 132
+                elif "fordigisales2" in line:
+                    counter2 = 27
+                elif counter1 > 0:
+                    counter1 = counter1 - 1
+                elif counter2 > 0:
+                    counter2 = counter2 - 1
+                else:
+                    f.write(line)
+
+        notif_center = os.path.join(path_dest, code_path, "notificationCenterTab/NotificationCenterFragment.java")
+        with open(notif_center, "r") as f:
+            lines = f.readlines()
+        with open(notif_center, "w") as f:
+            counter = 0
+            for line in lines:
+                if counter == 0:
+                    if "fordigisales" in line:
+                        counter = 14
+                    else:
+                        f.write(line)
+                else:
+                    counter = counter - 1
+    else:
+        settings_gradle = os.path.join(path_dest, "settings.gradle")
+        with open(settings_gradle, "r") as f:
+            lines = f.readlines()
+        with open(settings_gradle, "w") as f:
+            counter = 0
+            for line in lines:
+                if counter == 0:
+                    if "fordigisales" in line:
+                        counter = 5
+                    else:
+                        f.write(line)
+                else:
+                    counter = counter - 1
+        colorValue = os.path.join(path_dest, "app/src/main/res/values/colors.xml")
+        with open(colorValue, "r") as c:
+            lines = c.readlines()
+        with open(colorValue, "w") as c:
+            for lineColor in lines:
+                if "fordigisales" in lineColor:
+                    continue
+                else:
+                    c.write(lineColor)
+
+    if package == "com.nexilis.persija" or package == "io.newuniverse.GoToMalls" or package == "io.qmera.mylab":
+        string_res = os.path.join(path_dest, "app/src/main/res/values/strings.xml")
+        string_en_res = os.path.join(path_dest, "app/src/main/res/values-en/strings.xml")
+        string_id_res = os.path.join(path_dest, "app/src/main/res/values-in/strings.xml")
+        with open(string_res, "r") as f:
+            file_source = f.read()
+        replaced = file_source.replace("Nexilis", "Qmera")
+        with open(string_res, "w") as f:
+            f.write(replaced)
+        with open(string_en_res, "r") as f:
+            file_source = f.read()
+        replaced = file_source.replace("Nexilis", "Qmera")
+        with open(string_en_res, "w") as f:
+            f.write(replaced)
+        with open(string_id_res, "r") as f:
+            file_source = f.read()
+        replaced = file_source.replace("Nexilis", "Qmera")
+        with open(string_id_res, "w") as f:
+            f.write(replaced)
+
+        old_img_powered = "app/src/main/res/drawable/pb_powered_button.png"
+        old_img_powered = os.path.join(path_dest, old_img_powered)
+        old_new_img_powered = "app/src/main/res/drawable/pb_powered_button_temp.png"
+        old_new_img_powered = os.path.join(path_dest, old_new_img_powered)
+        shutil.move(old_img_powered, old_new_img_powered)
+
+        img_powered = "app/src/main/res/drawable/pb_powered_button1.png"
+        img_powered = os.path.join(path_dest, img_powered)
+        new_img_powered = "app/src/main/res/drawable/pb_powered_button.png"
+        new_img_powered = os.path.join(path_dest, new_img_powered)
+        shutil.move(img_powered, new_img_powered)
+
+    if package == "com.telkomsel.smb":
+        string_res = os.path.join(path_dest, "app/src/main/res/values/strings.xml")
+        string_en_res = os.path.join(path_dest, "app/src/main/res/values-en/strings.xml")
+        string_id_res = os.path.join(path_dest, "app/src/main/res/values-in/strings.xml")
+        with open(string_res, "r") as f:
+            file_source = f.read()
+        replaced = file_source.replace("Nexilis", "Telkomsel")
+        with open(string_res, "w") as f:
+            f.write(replaced)
+        with open(string_en_res, "r") as f:
+            file_source = f.read()
+        replaced = file_source.replace("Nexilis", "Telkomsel")
+        with open(string_en_res, "w") as f:
+            f.write(replaced)
+        with open(string_id_res, "r") as f:
+            file_source = f.read()
+        replaced = file_source.replace("Nexilis", "Telkomsel")
+        with open(string_id_res, "w") as f:
+            f.write(replaced)
+
+        old_img_powered = "app/src/main/res/drawable/pb_powered_button.png"
+        old_img_powered = os.path.join(path_dest, old_img_powered)
+        old_new_img_powered = "app/src/main/res/drawable/pb_powered_button_temp.png"
+        old_new_img_powered = os.path.join(path_dest, old_new_img_powered)
+        shutil.move(old_img_powered, old_new_img_powered)
+
+        img_powered = "app/src/main/res/drawable/pb_powered_button2.png"
+        img_powered = os.path.join(path_dest, img_powered)
+        new_img_powered = "app/src/main/res/drawable/pb_powered_button.png"
+        new_img_powered = os.path.join(path_dest, new_img_powered)
+        shutil.move(img_powered, new_img_powered)
+
+
+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/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(BytesIO(logo))
+        logo = logo.resize((512, 512))
+        if logo_float:
+            logo_float = Image.open(BytesIO(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 = ["tab{}.png".format(x) for x in tabs]
+    for i, icon in enumerate(default_tab_icon):
+        if not tab_icon[i]:
+            continue
+        img_path = "app/src/main/res/drawable"
+        img_path = os.path.join(path_dest, img_path, icon)
+        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(BytesIO(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, "MAB.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_order, package, fb_icon):
+    fb_order_list = [int(x) for x in fb_order.split(",")]
+    default_fb_icon = ["pb_button_chat.png", "pb_button_call.png", "pb_button_cc.png", "pb_button_stream.png",
+                       "nexilis_fb_04.png"]
+    for x, i in enumerate(fb_order_list):
+        if not fb_icon[x]:
+            continue
+        img_path = "app/src/main/res/drawable-nodpi"
+        if i - 1 in range(-len(default_fb_icon), len(default_fb_icon)):
+            img_path = os.path.join(path_dest, img_path, default_fb_icon[i - 1])
+            if isinstance(fb_icon[x], str):
+                logo = requests.get('https://newuniverse.io/dashboardv2/uploads/fb_icon/{}'.format(fb_icon[x]))
+                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(BytesIO(fb_icon[x]))
+                logo = logo.resize((150, 150))
+                logo.save(img_path, "PNG")
+    path_package_id = package.replace(".", "/")
+    code_path = "app/src/main/java/"
+    main_code_path = os.path.join(path_dest, code_path, path_package_id, "MAB.java")
+    with open(main_code_path, "r") as f:
+        file_source = f.read()
+    replaced = file_source.replace('dockedPlacement = "1,2,3,4,5"', 'dockedPlacement = "{}"'.format(fb_order))
+    with open(main_code_path, "w") as f:
+        f.write(replaced)
+
+
+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/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/pb_lbackground_1.png"
+    #     logo = Image.open(BytesIO(background))
+    #     logo = logo.resize((600, 1250))
+    #     logo.save(img_path, "PNG")
+    pass
+
+
+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)
+
+
+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:
+        if isinstance(keyfile, FileStorage):
+            keyfile.save(keyfile_path)
+        else:
+            with open(keyfile_path, 'wb') as f:
+                f.write(keyfile)
+    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 change_huawei_file(path_dest, huawei_file, package_id):
+    huaweifile_name = "agconnect-services.json"
+    huaweifile_path = os.path.join(path_dest, "app/{}".format(huaweifile_name))
+    if huawei_file:
+        huawei_file.save(huaweifile_path)
+        path_package_id = package_id.replace(".", "/")
+        code_path = "app/src/main/java/"
+        main_code_path = os.path.join(path_dest, code_path, path_package_id, "MAB.java")
+        with open(main_code_path, "r") as f:
+            file_source = f.read()
+        replaced = file_source.replace('isHMSEnabled = false', 'isHMSEnabled = true')
+        with open(main_code_path, "w") as f:
+            f.write(replaced)
+
+
+def change_fms_file(path_dest, fms_enable):
+    build_gradle = os.path.join(path_dest, 'app/build.gradle')
+    with open(build_gradle, "r") as f:
+        lines = f.readlines()
+    with open(build_gradle, "w") as f:
+        if fms_enable == 0:
+            for line in lines:
+                if "withfcm" in line:
+                    continue
+                else:
+                    f.write(line)
+        else:
+            for line in lines:
+                if "-nofcm" in line:
+                    continue
+                else:
+                    f.write(line)
+
+
+def change_adblock_file(path_dest, package, use_adblock):
+    if use_adblock == 0:
+        build_gradle = os.path.join(path_dest, 'app/build.gradle')
+        with open(build_gradle, "r") as f:
+            lines = f.readlines()
+        with open(build_gradle, "w") as f:
+            for line in lines:
+                if "removeAdblock" in line:
+                    continue
+                else:
+                    f.write(line)
+
+        path_package_id = package.replace(".", "/")
+        code_path = "app/src/main/java/"
+        code_path = os.path.join(path_dest, code_path, path_package_id)
+        javas = [os.path.join(dp, f) for dp, dn, filenames in os.walk(code_path) for f in filenames]
+        for j in javas:
+            print(j)
+            with open(j, "r") as f:
+                lines = f.readlines()
+            with open(j, "w") as f:
+                counter = 0
+                for line in lines:
+                    if counter == 0:
+                        if "removeAdblock" in line:
+                            continue
+                        elif "import org.adblockplus.libadblockplus.android" in line:
+                            continue
+                        elif "removeAdbMultiLine" in line:
+                            counter = 11
+                        elif "extends AdblockWebView" in line:
+                            replaced = line.replace("extends AdblockWebView", "extends WebView")
+                            f.write(replaced)
+                        else:
+                            f.write(line)
+                    else:
+                        counter = counter - 1
+
+
+def run_build(path_dest):
+    gradlew = os.path.join(path_dest, "gradlew")
+    error = ""
+    ret = subprocess.run([gradlew, 'clean', 'assembleRelease'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    if ret.returncode == 0:
+        ret = subprocess.run([gradlew, 'bundleRelease'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        if ret.returncode != 0:
+            error = "{}\n".format(ret.stderr.decode())
+            vprint(error)
+    else:
+        error = "{}\n".format(ret.stderr.decode())
+        vprint(error)
+    return ret.returncode, error
+
+
+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(project_config_SA.apk_folder, apk_name)
+    new_aab_dir = os.path.join(project_config_SA.apk_folder, aab_name)
+    new_dir = os.path.join(project_config_SA.apk_folder, zip_name)
+    vprint(apk_dir)
+    shutil.move(apk_dir, new_apk_dir)
+    try:
+        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(project_config_SA.temp_folder, package_id)
+        #        shutil.rmtree(project_path)
+        return {"status": "0", "name": zip_name}
+    except Exception as e:
+        return {"status": "4", "message": "Deliver APK & AAB failed\n{}".format(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)
+
+
+@celery.task(name="create_task")
+def create_task(package_id, enable_sms, app_name, key, keystore, access_model,
+                version_code, version_name, enable_location, font, fb_order, fb_icon, tabs, tab_icon, tab3_mode,
+                tab_amount, huawei_file, fms_enable, use_adblock, key_exists,
+                acc=None, logo=None, logo_float=None, background=None, url=None):
+    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, enable_sms)
+    if url:
+        change_url(c_code_path, url)
+    change_name(path_dest, app_name, enable_sms)
+    change_certificate(path_dest, key, keystore, project_config_SA.keytool)
+    change_package(path_dest, package_id, enable_location)
+    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_order, package_id, fb_icon)
+    change_access(path_dest, access_model, package_id)
+    change_tab(path_dest, tabs, tab_icon, package_id, tab3_mode, tab_amount)
+    change_huawei_file(path_dest, huawei_file, package_id)
+    change_fms_file(path_dest, fms_enable)
+    change_adblock_file(path_dest, package_id, use_adblock)
+    os.chdir(path_dest)
+    return_code, error = run_build(path_dest)
+    if return_code == 0:
+        return deliver_apk(path_dest, package_id, key, key_exists)
+    return {"status": "3", "message": "Build failed\n{}".format(str(error))}