|
| 1 | +import os |
| 2 | +import platform |
| 3 | +import subprocess |
| 4 | + |
| 5 | +import requests |
| 6 | +from tqdm import tqdm |
| 7 | + |
| 8 | +from rift.runtime.config import Config |
| 9 | + |
| 10 | + |
| 11 | +class RiftLibSetup: |
| 12 | + urls = { |
| 13 | + "windows": "https://github.com/AminRezaei0x443/ton/releases/download/v0.1.0/rift-lib-win64.dll", |
| 14 | + "darwin": "https://github.com/AminRezaei0x443/ton/releases/download/v0.1.0/rift-lib-macOS.dylib", |
| 15 | + "linux-u18": "https://github.com/AminRezaei0x443/ton/releases/download/v0.1.0/rift-lib-ubuntu-18.04.so", |
| 16 | + "linux-u20": "https://github.com/AminRezaei0x443/ton/releases/download/v0.1.0/rift-lib-ubuntu-20.04.so", |
| 17 | + "linux-u22": "https://github.com/AminRezaei0x443/ton/releases/download/v0.1.0/rift-lib-ubuntu-22.04.so", |
| 18 | + } |
| 19 | + |
| 20 | + @classmethod |
| 21 | + def acquire_lib(cls, ensure=False) -> str: |
| 22 | + if ensure: |
| 23 | + cls.setup_riftlib() |
| 24 | + return os.path.join(Config.dirs.user_data_dir, "_riftlib.pyd") |
| 25 | + |
| 26 | + @classmethod |
| 27 | + def is_setup(cls) -> bool: |
| 28 | + return os.path.exists(cls.acquire_lib()) |
| 29 | + |
| 30 | + @classmethod |
| 31 | + def _ubuntu_version(cls) -> int: |
| 32 | + try: |
| 33 | + if os.path.exists("/etc/lsb-release"): |
| 34 | + with open("/etc/lsb-release") as f: |
| 35 | + c = f.read().strip() |
| 36 | + lines = c.split("\n") |
| 37 | + info = dict(map(lambda x: x.split("="), lines)) |
| 38 | + if info["DISTRIB_ID"].lower() == "ubuntu": |
| 39 | + return int(info["DISTRIB_RELEASE"].split(".")[0]) |
| 40 | + return -1 |
| 41 | + except Exception: |
| 42 | + return -1 |
| 43 | + |
| 44 | + @classmethod |
| 45 | + def determine_lib(cls) -> str: |
| 46 | + s = platform.uname().system.lower() |
| 47 | + if s == "windows" or s == "darwin": |
| 48 | + return cls.urls[s] |
| 49 | + uv = cls._ubuntu_version() |
| 50 | + if uv == -1: |
| 51 | + raise RuntimeError("Unsupported os") |
| 52 | + return cls.urls[f"linux-u{uv}"] |
| 53 | + |
| 54 | + @classmethod |
| 55 | + def _call_get(cls, command): |
| 56 | + p = subprocess.Popen( |
| 57 | + command, stdout=subprocess.PIPE, stderr=subprocess.PIPE |
| 58 | + ) |
| 59 | + out, err = p.communicate() |
| 60 | + if p.returncode == 0: |
| 61 | + return True, out.decode("utf-8") |
| 62 | + return False, err.decode("utf-8") |
| 63 | + |
| 64 | + @classmethod |
| 65 | + def get_shared_libs(cls): |
| 66 | + ok, res = cls._call_get("ldconfig -p") |
| 67 | + if not ok: |
| 68 | + raise RuntimeError("Error fetching shared libraries!") |
| 69 | + res = filter(lambda x: "=>" in x, res.split("\n")) |
| 70 | + res = map( |
| 71 | + lambda x: list(map(lambda f: f.strip(), x.split("=>"))), res |
| 72 | + ) |
| 73 | + libs = dict(res) |
| 74 | + return libs |
| 75 | + |
| 76 | + @classmethod |
| 77 | + def get_glibc_version(cls): |
| 78 | + ok, res = cls._call_get("ldconfig --version") |
| 79 | + if not ok: |
| 80 | + raise RuntimeError("Error fetching glibc version!") |
| 81 | + return res.split("\n")[0].split(" ")[-1].strip() |
| 82 | + |
| 83 | + @classmethod |
| 84 | + def get_env_info(cls): |
| 85 | + return { |
| 86 | + "libs": cls.get_shared_libs(), |
| 87 | + "glibc": cls.get_glibc_version(), |
| 88 | + } |
| 89 | + |
| 90 | + @classmethod |
| 91 | + def _download(cls, addr: str, to: str, buffer=1024): |
| 92 | + response = requests.get(addr, stream=True) |
| 93 | + file_size = int(response.headers.get("Content-Length")) |
| 94 | + pbar = tqdm(total=file_size, unit="B", unit_scale=True) |
| 95 | + with open(to, "wb") as f: |
| 96 | + for chunk in response.iter_content(chunk_size=buffer): |
| 97 | + if chunk: # filter out keep-alive new chunks |
| 98 | + f.write(chunk) |
| 99 | + pbar.update(buffer) |
| 100 | + pbar.close() |
| 101 | + |
| 102 | + @classmethod |
| 103 | + def setup_riftlib(cls): |
| 104 | + lib_path = cls.acquire_lib() |
| 105 | + if cls.is_setup(): |
| 106 | + return |
| 107 | + url = cls.determine_lib() |
| 108 | + cls._download(url, lib_path, buffer=4096) |
0 commit comments