This commit is contained in:
Rikka
2023-01-17 23:41:33 +08:00
commit 4ccbc05426
15 changed files with 670 additions and 0 deletions

111
.gitignore vendored Normal file
View File

@@ -0,0 +1,111 @@
git
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
.idea/
# celery beat schedule file
celerybeat-schedule
workspace.xml
# SageMath parsed files
*.sage.py
.idea/workspace.xml
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
gapps
magisk
ndk
widevine
houdini

4
Dockerfile Normal file
View File

@@ -0,0 +1,4 @@
FROM redroid/redroid:11.0.0-latest
COPY gapps /
COPY ndk /
COPY magisk /

7
LICENSE Normal file
View File

@@ -0,0 +1,7 @@
Copyright © 2023 <copyright holders>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

80
README.md Normal file
View File

@@ -0,0 +1,80 @@
# Remote-Android Script
This script adds Gapps, Magisk and libndk to redroid **without recompiling the entire image**
## Specify an Android version
Use `-a` or `--android-version` to specify the Android version of the image being pulled. The value can be `8.1.0`, `9.0.0`, `10.0.0`, `11.0.0`, `12.0.0` or `13.0.0`. The default is 11.0.0.
```bash
# pull the latest image
python redroid.py -a 11.0.0
```
## Add OpenGapps to ReDroid image
<img src="./assets/3.png" style="zoom:50%;" />
```bash
python redroid.py -g
```
## Add libndk arm translation to ReDroid image
<img src="./assets/2.png" style="zoom:50%;" />
libndk_translation from guybrush firmware.
libndk seems to have better performance than libhoudini on AMD.
```bash
python redroid.py -n
```
## Add Magisk to ReDroid image
<img src="./assets/1.png" style="zoom:50%;" />
Zygisk and modules like LSPosed should work.
```bash
python redroid.py -m
```
## Example
This command will add Gapps, Magisk and Libndk to the ReDroid image at the same time.
```bash
python redroid.py -a 11.0.0 -gmn
```
## Troubleshooting
- Magisk installed: N/A
According to some feedback from WayDroid users, changing the kernel may solve this issue. https://t.me/WayDroid/126202
- The device isn't Play Protect certified
1. Run below command on host
```
adb root
adb shell 'sqlite3 /data/data/com.google.android.gsf/databases/gservices.db \
"select * from main where name = \"android_id\";"'
```
2. Grab device id and register on this website: https://www.google.com/android/uncertified/
- libndk doesn't work
I only made it work on `redroid/redroid:11.0.0`. Also, turning on Zygisk seems to break libndk.
- libhoudini doesn't work
I have no idea. I can't get any version of libhoudini to work on redroid.
## Credits
1. [waydroid_script](https://github.com/casualsnek/waydroid_script)
2. [Magisk Delta](https://huskydg.github.io/magisk-files/)
3. [vendor_intel_proprietary_houdini](https://github.com/supremegamers/vendor_intel_proprietary_houdini)

BIN
assets/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

BIN
assets/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 KiB

BIN
assets/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 KiB

85
redroid.py Normal file
View File

@@ -0,0 +1,85 @@
from io import BytesIO
import argparse
from stuffs.gapps import Gapps
from stuffs.houdini import Houdini
from stuffs.magisk import Magisk
from stuffs.ndk import Ndk
from stuffs.widevine import Widevine
import tools.helper as helper
import docker
def main():
dockerfile = ""
tags = []
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('-a', '--android-version',
dest='android',
help='Specify the Android version to build',
default='11.0.0',
choices=['13.0.0', '12.0.0', '11.0.0', '10.0.0', '9.0.0', '8.1.0'])
parser.add_argument('-g', '--install-gapps',
dest='gapps',
help='Install OpenGapps to ReDroid',
action='store_true')
parser.add_argument('-n', '--install-ndk-translation',
dest='ndk',
help='Install libndk translation files',
action='store_true')
parser.add_argument('-m', '--install-magisk', dest='magisk',
help='Install Magisk ( Bootless )',
action='store_true')
# Not working
# parser.add_argument('-h', '--install-libhoudini', dest='houdini',
# help='Install libhoudini for arm translation',
# action='store_true')
# Not working
# parser.add_argument('-w', '--install-widevine', dest='widevine',
# help='Integrate Widevine DRM (L3)',
# action='store_true')
args = parser.parse_args()
dockerfile = dockerfile + \
"FROM redroid/redroid:{}-latest\n".format(
args.android)
tags.append(args.android)
if args.gapps:
Gapps().install()
dockerfile = dockerfile + "COPY gapps /\n"
tags.append("gapps")
# if args.ndk and not args.houdini:
if args.ndk:
if args.android == "11.0.0":
arch = helper.host()[0]
if arch == "x86" or arch == "x86_64":
Ndk().install()
dockerfile = dockerfile+"COPY ndk /\n"
tags.append("ndk")
else:
helper.print_color(
"WARNING: Libndk seems to work only on redroid:11.0.0", helper.bcolors.YELLOW)
# if args.houdini and not args.installndk:
# arch = helper.host()[0]
# if arch == "x86" or arch == "x86_64":
# Houdini(args.android).install()
# dockerfile = dockerfile+"COPY houdini /\n"
if args.magisk:
Magisk().install()
dockerfile = dockerfile+"COPY magisk /\n"
tags.append("magisk")
# if args.widevine:
# Widevine().install()
# dockerfile = dockerfile+"COPY widevine /\n"
print("\nDockerfile\n"+dockerfile)
with open("./Dockerfile", "w") as f:
f.write(dockerfile)
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
new_image_name = "redroid/redroid:"+"-".join(tags)
client.images.build(path="/home/rikka/redroid-script",
dockerfile="Dockerfile",
tag=new_image_name)
helper.print_color("Successfully built {}".format(new_image_name), helper.bcolors.GREEN)
if __name__ == "__main__":
main()

59
stuffs/gapps.py Normal file
View File

@@ -0,0 +1,59 @@
import os
import shutil
from stuffs.general import General
from tools.helper import get_download_dir, host, print_color, run, bcolors
class Gapps(General):
dl_links = {
"x86_64": ["https://master.dl.sourceforge.net/project/opengapps/x86_64/20220121/open_gapps-x86_64-10.0-pico-20220121.zip?viasf=1", "e8c9a7412f5712eea7948957a62a7d66"],
"x86": ["https://udomain.dl.sourceforge.net/project/opengapps/x86/20220122/open_gapps-x86-10.0-pico-20220122.zip", "9e39e45584b7ade4529e6be654af7b81"],
"arm64-v8a": ["https://liquidtelecom.dl.sourceforge.net/project/opengapps/arm64/20220122/open_gapps-arm64-10.0-pico-20220122.zip", "8dfa6e76aeb2d1d5aed40b058e8a852c"],
"armeabi-v7a": ["https://nav.dl.sourceforge.net/project/opengapps/arm/20220122/open_gapps-arm-10.0-pico-20220122.zip", "a48ccbd25eb0a3c5e30f5db5435f5536"]
}
arch = host()
download_loc = get_download_dir()
dl_link = dl_links[arch[0]][0]
dl_file_name = os.path.join(download_loc, "open_gapps.zip")
act_md5 = dl_links[arch[0]][1]
sys_image_mount = "./gapps"
extract_to = "/tmp/ogapps/extract"
non_apks = [
"defaultetc-common.tar.lz",
"defaultframework-common.tar.lz",
"googlepixelconfig-common.tar.lz"
]
skip = [
"setupwizarddefault-x86_64.tar.lz",
"setupwizardtablet-x86_64.tar.lz"
]
def download(self):
print_color("Downloading OpenGapps now .....", bcolors.GREEN)
super().download()
def copy(self):
if not os.path.exists(self.extract_to):
os.makedirs(self.extract_to)
if not os.path.exists(os.path.join(self.extract_to, "appunpack")):
os.makedirs(os.path.join(self.extract_to, "appunpack"))
for lz_file in os.listdir(os.path.join(self.extract_to, "Core")):
for d in os.listdir(os.path.join(self.extract_to, "appunpack")):
shutil.rmtree(os.path.join(self.extract_to, "appunpack", d))
if lz_file not in self.skip:
if lz_file not in self.non_apks:
print(" Processing app package : "+os.path.join(self.extract_to, "Core", lz_file))
run(["tar", "--lzip", "-xvf", os.path.join(self.extract_to, "Core", lz_file), "-C", os.path.join(self.extract_to, "appunpack")])
app_name = os.listdir(os.path.join(self.extract_to, "appunpack"))[0]
xx_dpi = os.listdir(os.path.join(self.extract_to, "appunpack", app_name))[0]
app_priv = os.listdir(os.path.join(self.extract_to, "appunpack", app_name, "nodpi"))[0]
app_src_dir = os.path.join(self.extract_to, "appunpack", app_name, xx_dpi, app_priv)
for app in os.listdir(app_src_dir):
shutil.copytree(os.path.join(app_src_dir, app), os.path.join(self.sys_image_mount, "system", "priv-app", app), dirs_exist_ok=True)
else:
print(" Processing extra package : "+os.path.join(self.extract_to, "Core", lz_file))
run(["tar", "--lzip", "-xvf", os.path.join(self.extract_to, "Core", lz_file), "-C", os.path.join(self.extract_to, "appunpack")])
app_name = os.listdir(os.path.join(self.extract_to, "appunpack"))[0]
common_content_dirs = os.listdir(os.path.join(self.extract_to, "appunpack", app_name, "common"))
for ccdir in common_content_dirs:
shutil.copytree(os.path.join(self.extract_to, "appunpack", app_name, "common", ccdir), os.path.join(self.sys_image_mount, "system", ccdir), dirs_exist_ok=True)

34
stuffs/general.py Normal file
View File

@@ -0,0 +1,34 @@
import os
import zipfile
import hashlib
from tools.helper import bcolors, download_file, print_color
class General:
def download(self):
loc_md5 = ""
if os.path.isfile(self.dl_file_name):
with open(self.dl_file_name,"rb") as f:
bytes = f.read()
loc_md5 = hashlib.md5(bytes).hexdigest()
while not os.path.isfile(self.dl_file_name) or loc_md5 != self.act_md5:
if os.path.isfile(self.dl_file_name):
os.remove(self.dl_file_name)
print_color("md5 mismatches, redownloading now ....",bcolors.YELLOW)
loc_md5 = download_file(self.dl_link, self.dl_file_name)
def extract(self):
print_color("Extracting archive...", bcolors.GREEN)
print(self.dl_file_name)
print(self.extract_to)
with zipfile.ZipFile(self.dl_file_name) as z:
z.extractall(self.extract_to)
def copy(self):
pass
def install(self):
# pass
self.download()
self.extract()
self.copy()

53
stuffs/houdini.py Normal file
View File

@@ -0,0 +1,53 @@
import os
import re
import shutil
from stuffs.general import General
from tools.helper import bcolors, get_download_dir, print_color, run
class Houdini(General):
download_loc = get_download_dir()
sys_image_mount = "./houdini"
dl_links = {
"11.0.0": [
"https://github.com/supremegamers/vendor_intel_proprietary_houdini/archive/81f2a51ef539a35aead396ab7fce2adf89f46e88.zip",
"fbff756612b4144797fbc99eadcb6653"],
"12.0.0": [
"https://github.com/supremegamers/vendor_intel_proprietary_houdini/archive/0e0164611d5fe5595229854759c30a9b5c1199a5.zip",
"9709701b44b6ab7fc311c7dc95945bd0"],
"13.0.0": [
"https://github.com/supremegamers/vendor_intel_proprietary_houdini/archive/978d8cba061a08837b7e520cd03b635af643ba08.zip",
"1e139054c05034648fae58a1810573b4"
],
# "9.0.0":[],
# "8.1.0":[]
}
dl_file_name = os.path.join(download_loc, "libhoudini.zip")
extract_to = "/tmp/houdiniunpack"
def __init__(self, version):
self.version = version
if version in self.dl_links.keys():
self.dl_link = self.dl_links[version][0]
self.act_md5 = self.dl_links[version][1]
else:
raise ValueError(
"No available libhoudini for Android {}".format(version))
def download(self):
print_color("Downloading libhoudini now .....", bcolors.GREEN)
super().download()
def copy(self):
run(["chmod", "+x", self.extract_to, "-R"])
print_color("Copying libhoudini library files ...", bcolors.GREEN)
name = re.findall("([a-zA-Z0-9]+)\.zip", self.dl_link)[0]
shutil.copytree(os.path.join(self.extract_to, "vendor_intel_proprietary_houdini-" + name,
"prebuilts"), os.path.join(self.sys_image_mount, "vendor"), dirs_exist_ok=True)
init_path = os.path.join(self.sys_image_mount, "system", "etc", "init", "houdini.rc")
if not os.path.isfile(init_path):
os.makedirs(os.path.dirname(init_path), exist_ok=True)
with open(init_path, "w") as initfile:
initfile.write(self.init_rc_component)

101
stuffs/magisk.py Normal file
View File

@@ -0,0 +1,101 @@
import gzip
import os
import shutil
import re
from stuffs.general import General
from tools.helper import bcolors, download_file, host, print_color, run, get_download_dir
class Magisk(General):
download_loc = get_download_dir()
dl_link = "https://huskydg.github.io/magisk-files/app-release.apk"
dl_file_name = os.path.join(download_loc, "magisk.apk")
extract_to = "/tmp/magisk_unpack"
sys_overlay_dir = "./magisk"
magisk_dir = os.path.join(sys_overlay_dir, "system", "etc", "init", "magisk")
machine = host()
oringinal_bootanim = """
service bootanim /system/bin/bootanimation
class core animation
user graphics
group graphics audio
disabled
oneshot
ioprio rt 0
task_profiles MaxPerformance
"""
bootanim_component = """
on post-fs-data
start logd
exec u:r:su:s0 root root -- /system/etc/init/magisk/magisk{arch} --auto-selinux --setup-sbin /system/etc/init/magisk
exec u:r:su:s0 root root -- /system/etc/init/magisk/magiskpolicy --live --magisk "allow * magisk_file lnk_file *"
mkdir /sbin/.magisk 700
mkdir /sbin/.magisk/mirror 700
mkdir /sbin/.magisk/block 700
copy /system/etc/init/magisk/config /sbin/.magisk/config
rm /dev/.magisk_unblock
start 7zKkuZ1ZhD
wait /dev/.magisk_unblock 40
rm /dev/.magisk_unblock
service 7zKkuZ1ZhD /sbin/magisk --auto-selinux --post-fs-data
user root
seclabel u:r:su:s0
oneshot
service wHgGlkRCtMoIQw /sbin/magisk --auto-selinux --service
class late_start
user root
seclabel u:r:su:s0
oneshot
on property:sys.boot_completed=1
mkdir /data/adb/magisk 755
exec u:r:su:s0 root root -- /sbin/magisk --auto-selinux --boot-complete
exec -- /system/bin/sh -c "if [ ! -e /data/data/io.github.huskydg.magisk ] ; then pm install /system/etc/init/magisk/magisk.apk ; fi"
on property:init.svc.zygote=restarting
exec u:r:su:s0 root root -- /sbin/magisk --auto-selinux --zygote-restart
on property:init.svc.zygote=stopped
exec u:r:su:s0 root root -- /sbin/magisk --auto-selinux --zygote-restart
""".format(arch=machine[1])
def download(self):
if os.path.isfile(self.dl_file_name):
os.remove(self.dl_file_name)
print_color("Downloading latest Magisk-Delta now .....", bcolors.GREEN)
download_file(self.dl_link, self.dl_file_name)
def copy(self):
if not os.path.exists(self.magisk_dir):
os.makedirs(self.magisk_dir, exist_ok=True)
if not os.path.exists(os.path.join(self.sys_overlay_dir, "sbin")):
os.makedirs(os.path.join(self.sys_overlay_dir, "sbin"), exist_ok=True)
print_color("Copying magisk libs now ...", bcolors.GREEN)
lib_dir = os.path.join(self.extract_to, "lib", self.machine[0])
for parent, dirnames, filenames in os.walk(lib_dir):
for filename in filenames:
o_path = os.path.join(lib_dir, filename)
filename = re.search('lib(.*)\.so', filename)
n_path = os.path.join(self.magisk_dir, filename.group(1))
shutil.copyfile(o_path, n_path)
run(["chmod", "+x", n_path])
shutil.copyfile(self.dl_file_name, os.path.join(self.magisk_dir,"magisk.apk") )
# Updating Magisk from Magisk manager will modify bootanim.rc,
# So it is necessary to backup the original bootanim.rc.
bootanim_path = os.path.join(self.sys_overlay_dir, "system", "etc", "init", "bootanim.rc")
gz_filename = os.path.join(bootanim_path)+".gz"
with gzip.open(gz_filename,'wb') as f_gz:
f_gz.write(self.oringinal_bootanim.encode('utf-8'))
with open(bootanim_path, "w") as initfile:
initfile.write(self.oringinal_bootanim+self.bootanim_component)

39
stuffs/ndk.py Normal file
View File

@@ -0,0 +1,39 @@
import os
import shutil
from stuffs.general import General
from tools.helper import bcolors, get_download_dir, print_color, run
class Ndk(General):
download_loc = get_download_dir()
sys_image_mount = "./ndk"
dl_link = "https://www.dropbox.com/s/eaf4dj3novwiccp/libndk_translation_Module-c6077f3398172c64f55aad7aab0e55fad9110cf3.zip?dl=1"
dl_file_name = os.path.join(download_loc, "libndktranslation.zip")
extract_to = "/tmp/libndkunpack"
act_md5 = "4456fc1002dc78e544e8d9721bb24398"
init_rc_component = """
# Enable native bridge for target executables
on early-init
mount binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc
on property:ro.enable.native.bridge.exec=1
copy /system/etc/binfmt_misc/arm_exe /proc/sys/fs/binfmt_misc/register
copy /system/etc/binfmt_misc/arm_dyn /proc/sys/fs/binfmt_misc/register
copy /system/etc/binfmt_misc/arm64_exe /proc/sys/fs/binfmt_misc/register
copy /system/etc/binfmt_misc/arm64_dyn /proc/sys/fs/binfmt_misc/register
"""
def download(self):
print_color("Downloading libndk now .....", bcolors.GREEN)
super().download()
def copy(self):
run(["chmod", "+x", self.extract_to, "-R"])
print_color("Copying libndk library files ...", bcolors.GREEN)
shutil.copytree(os.path.join(self.extract_to, "libndk_translation_Module-c6077f3398172c64f55aad7aab0e55fad9110cf3", "system"), os.path.join(self.sys_image_mount, "system"), dirs_exist_ok=True)
init_path = os.path.join(self.sys_image_mount, "system", "etc", "init", "libndk.rc")
if not os.path.isfile(init_path):
os.makedirs(os.path.dirname(init_path), exist_ok=True)
with open(init_path, "w") as initfile:
initfile.write(self.init_rc_component)

23
stuffs/widevine.py Normal file
View File

@@ -0,0 +1,23 @@
import os
import shutil
from stuffs.general import General
from tools.helper import bcolors, get_download_dir, print_color, run
class Widevine(General):
download_loc = get_download_dir()
vendor_image_mount = "./widevine"
dl_link = "https://codeload.github.com/supremegamers/vendor_google_proprietary_widevine-prebuilt/zip/94c9ee172e3d78fecc81863f50a59e3646f7a2bd"
dl_file_name = os.path.join(download_loc, "widevine.zip")
extract_to = "/tmp/widevineunpack"
act_md5 = "a31f325453c5d239c21ecab8cfdbd878"
def download(self):
print_color("Downloading widevine now .....", bcolors.GREEN)
super().download()
def copy(self):
run(["chmod", "+x", self.extract_to, "-R"])
print_color("Copying widevine library files ...", bcolors.GREEN)
shutil.copytree(os.path.join(self.extract_to, "vendor_google_proprietary_widevine-prebuilt-94c9ee172e3d78fecc81863f50a59e3646f7a2bd",
"prebuilts"), os.path.join(self.vendor_image_mount, "vendor"), dirs_exist_ok=True)

74
tools/helper.py Normal file
View File

@@ -0,0 +1,74 @@
import os
import platform
import subprocess
import requests
from tqdm import tqdm
import hashlib
def get_download_dir():
download_loc = ""
if os.environ.get("XDG_CACHE_HOME", None) is None:
download_loc = os.path.join('/', "home", os.environ.get("SUDO_USER", os.environ["USER"]), ".cache", "redroid", "downloads")
else:
download_loc = os.path.join(os.environ["XDG_CACHE_HOME"], "redroid", "downloads")
if not os.path.exists(download_loc):
os.makedirs(download_loc)
return download_loc
def run(args):
result = subprocess.run(args=args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if result.stderr:
print(result.stderr.decode("utf-8"))
raise subprocess.CalledProcessError(
returncode = result.returncode,
cmd = result.args,
stderr = result.stderr
)
return result
def download_file(url, f_name):
md5 = ""
response = requests.get(url, stream=True, proxies={"https":"127.0.0.1:7890"})
total_size_in_bytes = int(response.headers.get('content-length', 0))
block_size = 1024 # 1 Kibibyte
progress_bar = tqdm(total=total_size_in_bytes, unit='iB', unit_scale=True)
with open(f_name, 'wb') as file:
for data in response.iter_content(block_size):
progress_bar.update(len(data))
file.write(data)
progress_bar.close()
with open(f_name, "rb") as f:
bytes = f.read()
md5 = hashlib.md5(bytes).hexdigest()
if total_size_in_bytes != 0 and progress_bar.n != total_size_in_bytes:
raise ValueError("Something went wrong while downloading")
return md5
def host():
machine = platform.machine()
mapping = {
"i686": ("x86", 32),
"x86_64": ("x86_64", 64),
"aarch64": ("arm64-v8a", 64),
"armv7l": ("armeabi-v7a", 32),
"armv8l": ("armeabi-v7a", 32)
}
if machine in mapping:
# if mapping[machine] == "x86_64":
# with open("/proc/cpuinfo") as f:
# if "sse4_2" not in f.read():
# print("x86_64 CPU does not support SSE4.2, falling back to x86...")
# return ("x86", 32)
return mapping[machine]
raise ValueError("platform.machine '" + machine + "'"
" architecture is not supported")
class bcolors:
RED = '\033[31m'
YELLOW = '\033[33m'
GREEN = '\033[32m'
ENDC = '\033[0m'
def print_color(str, color):
print(color+str+bcolors.ENDC)