232 lines
5.7 KiB
Bash
Executable File
232 lines
5.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# qlpycon installer
|
|
# Usage:
|
|
# pipe2bash:
|
|
# curl -sSL https://6bit.ch/qlpycon/install.sh | bash
|
|
#
|
|
# local:
|
|
# mkdir qlpycon
|
|
# cd qlpycon
|
|
# chmod u+x install.sh
|
|
# ./install.sh
|
|
#
|
|
# or run directly from cloned repo:
|
|
# git clone https://git.6bit.ch/xbl/qlpycon.git
|
|
# cd qlpycon
|
|
# chmod u+x install.sh
|
|
# ./install.sh
|
|
#
|
|
|
|
set -e
|
|
|
|
TAR_URL="https://6bit.ch/qlpycon.tar.gz"
|
|
BIN_DIR="$HOME/.local/bin"
|
|
BIN_PATH="$BIN_DIR/qlpycon"
|
|
|
|
# === Colors ===>
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
CYAN='\033[0;36m'
|
|
MAGENTA='\033[0;35m'
|
|
NC='\033[0m'
|
|
|
|
info() { echo -e "${CYAN} o_o [INFO]${NC} $*"; }
|
|
success() { echo -e "${GREEN} ^_^ [SUCCESS]${NC} $*"; }
|
|
warn() { echo -e "${YELLOW} >_< [WARN]${NC} $*"; }
|
|
die() { echo -e "${RED} x_x [ERROR]${NC} $*" >&2; exit 1; }
|
|
|
|
# === Checks ===>
|
|
check_dependencies() {
|
|
info "Checking dependencies..."
|
|
|
|
command -v python3 >/dev/null 2>&1 || die "python3 is required but not installed"
|
|
|
|
# Check Python version >= 3.9
|
|
python3 -c "
|
|
import sys
|
|
if sys.version_info < (3, 9):
|
|
print('Python 3.9+ required, found ' + sys.version)
|
|
sys.exit(1)
|
|
" || die "Python 3.9 or higher is required"
|
|
|
|
command -v pip3 >/dev/null 2>&1 || \
|
|
python3 -m pip --version >/dev/null 2>&1 || \
|
|
die "pip is required but not installed"
|
|
|
|
success "Dependencies OK"
|
|
}
|
|
|
|
# === Source detection ===>
|
|
detect_source() {
|
|
if [[ -f "./main.py" && -d "./lib" ]]; then
|
|
echo "repo"
|
|
else
|
|
echo "download"
|
|
fi
|
|
}
|
|
|
|
# === Download ===>
|
|
download_and_extract() {
|
|
info "Downloading to temp and extracting to $INSTALL_DIR..."
|
|
|
|
mkdir -p "$INSTALL_DIR"
|
|
|
|
TMP_TAR=$(mktemp)
|
|
|
|
if command -v curl >/dev/null 2>&1; then
|
|
curl -sSL "$TAR_URL" -o "$TMP_TAR" || die "Download failed"
|
|
else
|
|
wget -qO "$TMP_TAR" "$TAR_URL" || die "Download failed"
|
|
fi
|
|
|
|
if ! file "$TMP_TAR" | grep -q 'gzip'; then
|
|
rm -f "$TMP_TAR"
|
|
die "Download failed or URL returned invalid content"
|
|
fi
|
|
|
|
# Preserve existing config if updating
|
|
if [[ -f "$INSTALL_DIR/qlpycon.conf" ]]; then
|
|
warn "Existing qlpycon.conf found - keeping it"
|
|
tar -xzf "$TMP_TAR" -C "$INSTALL_DIR" --exclude='qlpycon.conf' || die "Extraction failed"
|
|
else
|
|
tar -xzf "$TMP_TAR" -C "$INSTALL_DIR" || die "Extraction failed"
|
|
fi
|
|
|
|
rm -f "$TMP_TAR"
|
|
|
|
success "Extracted to $INSTALL_DIR"
|
|
}
|
|
|
|
# === Venv ===>
|
|
setup_venv() {
|
|
info "Setting up Python virtual environment..."
|
|
|
|
if [[ ! -d "$INSTALL_DIR/venv" ]] || [[ ! -f "$INSTALL_DIR/venv/bin/pip" ]]; then
|
|
python3 -m venv "$INSTALL_DIR/venv" || die "Failed to create venv"
|
|
else
|
|
warn "venv already exists - skipping creation"
|
|
fi
|
|
|
|
info "Installing pip"
|
|
"$INSTALL_DIR/venv/bin/pip" install --quiet --upgrade pip
|
|
info "Installing pyzmq via pip"
|
|
"$INSTALL_DIR/venv/bin/pip" install --quiet pyzmq
|
|
|
|
success "Virtual environment ready"
|
|
}
|
|
|
|
# === Launcher ===>
|
|
write_launcher() {
|
|
info "Writing launcher to $BIN_PATH..."
|
|
|
|
mkdir -p "$BIN_DIR"
|
|
|
|
echo "BIN_PATH is: $BIN_PATH"
|
|
cat > "$BIN_PATH" << EOF
|
|
#!/usr/bin/env bash
|
|
# qlpycon launcher — generated by install.sh
|
|
QLPYCON_DIR="$INSTALL_DIR"
|
|
|
|
if [[ ! -d "\$QLPYCON_DIR" ]]; then
|
|
echo "Error: qlpycon directory not found: \$QLPYCON_DIR"
|
|
echo "Re-run install.sh or cry :("
|
|
exit 1
|
|
fi
|
|
|
|
cd "\$QLPYCON_DIR"
|
|
source "\$QLPYCON_DIR/venv/bin/activate"
|
|
exec python3 main.py "\$@"
|
|
EOF
|
|
|
|
chmod +x "$BIN_PATH"
|
|
success "Launcher written to $BIN_PATH"
|
|
}
|
|
|
|
# === PATH check ===>
|
|
check_path() {
|
|
info "Checking \$PATH..."
|
|
if [[ ":$PATH:" != *":$BIN_DIR:"* ]]; then
|
|
warn "$BIN_DIR is not in your PATH."
|
|
echo ""
|
|
echo " Add this to your ~/.bashrc or ~/.zshrc:"
|
|
echo " export PATH=\"\$HOME/.local/bin:\$PATH\""
|
|
echo ""
|
|
else
|
|
success "\$PATH is superfine"
|
|
fi
|
|
}
|
|
|
|
# === Config ===>
|
|
setup_config() {
|
|
if [[ ! -f "$INSTALL_DIR/qlpycon.conf" ]]; then
|
|
if [[ -f "$INSTALL_DIR/qlpycon.conf.example" ]]; then
|
|
cp "$INSTALL_DIR/qlpycon.conf.example" "$INSTALL_DIR/qlpycon.conf"
|
|
success "Created $INSTALL_DIR/qlpycon.conf from example"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# === Main ===>
|
|
|
|
main() {
|
|
print_banner() {
|
|
cat <<'EOF'
|
|
_/
|
|
_/_/_/ _/ _/_/_/ _/ _/ _/_/_/ _/_/ _/_/_/
|
|
_/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/
|
|
_/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/
|
|
_/_/_/ _/ _/_/_/ _/_/_/ _/_/_/ _/_/ _/ _/
|
|
_/ _/ _/
|
|
_/ _/ _/_/
|
|
EOF
|
|
}
|
|
|
|
if command -v lolcat >/dev/null 2>&1 && [[ ${LOLCAT:-1} -eq 1 ]]; then
|
|
{
|
|
print_banner
|
|
echo
|
|
echo " qlpycon installer"
|
|
} | lolcat -
|
|
else
|
|
echo -e "${MAGENTA}"
|
|
print_banner
|
|
echo -e "${NC}"
|
|
echo -e "${CYAN} qlpycon installer${NC}"
|
|
fi
|
|
|
|
echo
|
|
|
|
check_dependencies
|
|
|
|
SOURCE=$(detect_source)
|
|
|
|
if [[ "$SOURCE" == "repo" ]]; then
|
|
INSTALL_DIR="$(pwd)"
|
|
info "Running from cloned repo - using $INSTALL_DIR"
|
|
else
|
|
DEFAULT_DIR="$HOME/.local/share/qlpycon"
|
|
read -p "Install directory [$DEFAULT_DIR]: " USER_DIR </dev/tty
|
|
INSTALL_DIR="${USER_DIR:-$DEFAULT_DIR}"
|
|
INSTALL_DIR="${INSTALL_DIR/#\~/$HOME}"
|
|
download_and_extract
|
|
fi
|
|
|
|
setup_venv
|
|
setup_config
|
|
write_launcher
|
|
check_path
|
|
|
|
echo ""
|
|
success "qlpycon installed"
|
|
echo ""
|
|
echo " Edit your config: ${INSTALL_DIR}/qlpycon.conf"
|
|
echo " Run: qlpycon --list"
|
|
echo " qlpycon ffa"
|
|
echo " qlpycon --host tcp://1.2.3.4:28960 --password secret"
|
|
echo ""
|
|
}
|
|
|
|
main "$@"
|