This repository has been archived on 2026-05-21. You can view files and clone it, but cannot push or open issues or pull requests.
TyChat-TUI/extra/compile.py

124 lines
4.4 KiB
Python

# TyChat TUI auto installer
# This is bugged pice of shit because of crossplatform
# I will only officialy supporting Windows and UNIX-Like systems excluding MacOS and KolibriOS
import os
import sys
import shutil
import subprocess
import platform
import urllib.request
import zipfile
# Configuration, you can change if you like, for example, making a fork of my messenger
REPO_URL = "https://git.idkmail.ru/lohrrrr/TyChat-Client.git"
PROJECT_DIR = "TyChat-Client-Build"
VENV_DIR = os.path.join(PROJECT_DIR, "setup-venv")
ENTRY_POINT = "TUI.py"
DEPENDENCIES = [
"pyinstaller",
"python-socketio",
"websocket-client",
"numpy",
"sounddevice",
"prompt_toolkit"
]
GREEN = '\033[92m'
RESET = '\033[0m'
def run_command(command, cwd=None, shell=False):
"""Wrapper to run shell commands."""
try:
subprocess.run(command, cwd=cwd, check=True, shell=shell)
except subprocess.CalledProcessError as e:
print(f"[ERROR] Command failed: {' '.join(command)}")
sys.exit(1)
def get_venv_paths():
"""Determine paths based on the operating system and check for valid executables."""
# Resolve to an absolute path so altering cwd downstream doesn't break relative lookups
absolute_venv = os.path.abspath(VENV_DIR)
if platform.system() == "Windows":
return os.path.join(absolute_venv, "Scripts", "python.exe"), os.path.join(absolute_venv, "Scripts", "pip.exe")
# Check for python3, fallback to python
python_path = os.path.join(absolute_venv, "bin", "python3")
if not os.path.exists(python_path):
python_path = os.path.join(absolute_venv, "bin", "python")
# Check for pip3, fallback to pip
pip_path = os.path.join(absolute_venv, "bin", "pip3")
if not os.path.exists(pip_path):
pip_path = os.path.join(absolute_venv, "bin", "pip")
return python_path, pip_path
def download_and_extract_zip(url, target_dir):
"""Downloads the repository source ZIP and extracts its contents into target_dir."""
zip_path = "repo_archive.zip"
try:
print(" -> Git not found. Downloading source ZIP archive...")
# Download the zip file
urllib.request.urlretrieve(url, zip_path)
print(" -> Extracting archive...")
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
# The archive extracts into a root folder like 'TyChat-Client' or 'TyChat-Client-main'
# We look at the first directory level inside the ZIP
root_in_zip = zip_ref.namelist()[0].split('/')[0]
zip_ref.extractall(".")
# Rename the extracted folder to match your expected PROJECT_DIR
if os.path.exists(root_in_zip):
os.rename(root_in_zip, target_dir)
except Exception as e:
print(f"[ERROR] Failed to download or extract the repository ZIP: {e}")
sys.exit(1)
finally:
# Clean up the downloaded zip file
if os.path.exists(zip_path):
os.remove(zip_path)
def main():
# Cleanup existing build
if os.path.exists(PROJECT_DIR):
shutil.rmtree(PROJECT_DIR)
print("[*] Cloning repository...")
# Check if git is available in the system PATH
if shutil.which("git"):
run_command(["git", "clone", REPO_URL, PROJECT_DIR])
else:
# Fallback to the direct zip archive if git is missing
zip_url = "https://git.idkmail.ru/lohrrrr/TyChat-Client/archive/main.zip"
download_and_extract_zip(zip_url, PROJECT_DIR)
print("[*] Creating virtual environment...")
run_command([sys.executable, "-m", "venv", VENV_DIR])
python_exe, pip_exe = get_venv_paths()
print("[*] Upgrading pip...")
run_command([python_exe, "-m", "pip", "install", "--upgrade", "pip"])
print("[*] Installing dependencies...")
for dep in DEPENDENCIES:
print(f" -> Installing {dep}...")
run_command([pip_exe, "install", dep])
print("[*] Building standalone binary...")
# Run PyInstaller (and pray to the god)
run_command([python_exe, "-m", "PyInstaller", "--onefile", "--name", "TyChat", ENTRY_POINT], cwd=PROJECT_DIR)
dist_dir = os.path.join(PROJECT_DIR, "dist")
if os.path.exists(dist_dir):
print(f"\n{GREEN}Your executable file is located in {os.path.abspath(dist_dir)}{RESET}")
else:
print(f"\n[!] Build complete, but 'dist' directory not found at: {dist_dir}.")
if __name__ == "__main__":
main()