afegit setup-quake
This commit is contained in:
Executable
+27
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Navigate to setup-quake/ regardless of where we're called from
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
# Activate virtualenv if present, otherwise require pyinstaller in PATH
|
||||
if [[ -f .venv/bin/activate ]]; then
|
||||
source .venv/bin/activate
|
||||
echo "Activated .venv"
|
||||
elif ! command -v pyinstaller &>/dev/null; then
|
||||
echo "Error: pyinstaller not found. Either create a .venv or install pyinstaller." >&2
|
||||
echo " python3 -m venv .venv && .venv/bin/pip install -r requirements.txt" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Building setup-quake binary..."
|
||||
pyinstaller --onefile --clean --name setup-quake setup_quake.py
|
||||
|
||||
echo "Copying config.ini to dist/..."
|
||||
cp config.ini dist/
|
||||
|
||||
echo ""
|
||||
echo "Build complete. Output:"
|
||||
echo " ${SCRIPT_DIR}/dist/setup-quake"
|
||||
echo " ${SCRIPT_DIR}/dist/config.ini"
|
||||
@@ -0,0 +1,3 @@
|
||||
[quake]
|
||||
files_url = https://php.sustancia.synology.me/files/ioquake3-files.zip
|
||||
install_dir = .q3a
|
||||
@@ -0,0 +1 @@
|
||||
pyinstaller
|
||||
@@ -0,0 +1,132 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
setup-quake: Install ioquake3 and download Quake 3 data files
|
||||
to the real user's home directory for use at a retro gaming fair.
|
||||
|
||||
Usage: sudo ./setup-quake
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import configparser
|
||||
import os
|
||||
import pwd
|
||||
import subprocess
|
||||
import sys
|
||||
import urllib.request
|
||||
import zipfile
|
||||
|
||||
|
||||
def get_script_dir():
|
||||
"""Return the directory containing the script or binary."""
|
||||
if getattr(sys, "frozen", False):
|
||||
return os.path.dirname(sys.executable)
|
||||
return os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Install ioquake3 and download Quake 3 data files."
|
||||
)
|
||||
parser.parse_args()
|
||||
|
||||
|
||||
def check_root():
|
||||
if os.geteuid() != 0:
|
||||
print("Error: this script must be run as root (use sudo).", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def load_config():
|
||||
config_path = os.path.join(get_script_dir(), "config.ini")
|
||||
cfg = configparser.ConfigParser()
|
||||
cfg.read(config_path)
|
||||
files_url = cfg.get("quake", "files_url", fallback="https://php.sustancia.synology.me/files/ioquake3-files.zip")
|
||||
install_dir = cfg.get("quake", "install_dir", fallback=".q3a")
|
||||
return files_url, install_dir
|
||||
|
||||
|
||||
def get_real_home():
|
||||
"""Resolve the actual user's home when running under sudo."""
|
||||
sudo_user = os.environ.get("SUDO_USER")
|
||||
if sudo_user:
|
||||
home_dir = pwd.getpwnam(sudo_user).pw_dir
|
||||
return home_dir, sudo_user
|
||||
home_dir = os.path.expanduser("~")
|
||||
return home_dir, "root"
|
||||
|
||||
|
||||
def install_ioquake3():
|
||||
print(" Running: apt-get install -y ioquake3")
|
||||
subprocess.run(["apt-get", "install", "-y", "ioquake3"], check=True)
|
||||
|
||||
|
||||
def download_files(url):
|
||||
"""Download the Quake 3 files zip to /tmp. Returns destination path."""
|
||||
dest = "/tmp/ioquake3-files.zip"
|
||||
print(f" Downloading: {url}")
|
||||
print(f" Destination: {dest}")
|
||||
|
||||
with urllib.request.urlopen(url) as response:
|
||||
total = response.headers.get("Content-Length")
|
||||
total_mb = f"{int(total) / 1024 / 1024:.1f} MB" if total else "unknown size"
|
||||
print(f" File size: {total_mb}")
|
||||
|
||||
downloaded = 0
|
||||
chunk_size = 1024 * 1024 # 1 MB
|
||||
with open(dest, "wb") as f:
|
||||
while True:
|
||||
chunk = response.read(chunk_size)
|
||||
if not chunk:
|
||||
break
|
||||
f.write(chunk)
|
||||
downloaded += len(chunk)
|
||||
print(f" Downloaded: {downloaded / 1024 / 1024:.1f} MB", end="\r")
|
||||
|
||||
print() # newline after progress
|
||||
return dest
|
||||
|
||||
|
||||
def extract_files(zip_path, home_dir, install_dir):
|
||||
target = os.path.join(home_dir, install_dir)
|
||||
print(f" Extracting to: {target}")
|
||||
os.makedirs(target, exist_ok=True)
|
||||
|
||||
with zipfile.ZipFile(zip_path) as zf:
|
||||
zf.extractall(target)
|
||||
|
||||
os.remove(zip_path)
|
||||
print(f" Cleaned up: {zip_path}")
|
||||
|
||||
|
||||
def main():
|
||||
parse_args()
|
||||
check_root()
|
||||
|
||||
files_url, install_dir = load_config()
|
||||
home_dir, username = get_real_home()
|
||||
|
||||
print("=== setup-quake ===")
|
||||
print(f" User : {username}")
|
||||
print(f" Home directory : {home_dir}")
|
||||
print(f" Install dir : {os.path.join(home_dir, install_dir)}")
|
||||
print()
|
||||
|
||||
print("[1/3] Installing ioquake3...")
|
||||
install_ioquake3()
|
||||
print()
|
||||
|
||||
print("[2/3] Downloading Quake 3 data files...")
|
||||
zip_path = download_files(files_url)
|
||||
print()
|
||||
|
||||
print("[3/3] Extracting data files...")
|
||||
extract_files(zip_path, home_dir, install_dir)
|
||||
print()
|
||||
|
||||
print("Done. Verify with:")
|
||||
print(f" dpkg -l ioquake3")
|
||||
print(f" ls {os.path.join(home_dir, install_dir)}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user