From d0de47bdd7d1f6f1f500e1b1f8708aecea59909c Mon Sep 17 00:00:00 2001 From: Spencer Grimes Date: Sat, 31 Jan 2026 13:54:27 -0600 Subject: [PATCH] fix: replace emoji characters with ASCII-safe markers for Windows compatibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace Unicode emoji (✓, ⚠️) with [OK] and [WARN] in audio_preprocessor.py to prevent UnicodeEncodeError on Windows console (cp1252 codec) - Add auto-update dependencies function to bot.py for easier maintenance - Remove setup_linux.sh (no longer needed) - Update .gitignore to exclude VS Code launch.json --- .gitignore | 3 +- audio_preprocessor.py | 12 +-- bot.py | 22 +++++ setup_linux.sh | 213 ------------------------------------------ 4 files changed, 30 insertions(+), 220 deletions(-) delete mode 100755 setup_linux.sh diff --git a/.gitignore b/.gitignore index 27d775d..598432b 100644 --- a/.gitignore +++ b/.gitignore @@ -124,4 +124,5 @@ venv.bak/ .numba_cache/ # Gemini files GEMINI.md -PROGRESS.md \ No newline at end of file +PROGRESS.md +.vscode/launch.json diff --git a/audio_preprocessor.py b/audio_preprocessor.py index d12945b..728e597 100644 --- a/audio_preprocessor.py +++ b/audio_preprocessor.py @@ -190,16 +190,16 @@ def print_audio_analysis(file_path: str) -> None: print(f"\n{'=' * 50}") print(f"Audio Analysis: {info['path']}") print(f"{'=' * 50}") - print(f" Sample Rate: {info['sample_rate']} Hz {'⚠️ (should be 22050)' if info['needs_resampling'] else '✓'}") + print(f" Sample Rate: {info['sample_rate']} Hz {'[WARN] (should be 22050)' if info['needs_resampling'] else '[OK]'}") print(f" Duration: {info['duration_seconds']:.2f}s", end="") if info['is_too_short']: - print(" ⚠️ (too short, aim for 5-15s)") + print(" [WARN] (too short, aim for 5-15s)") elif info['is_too_long']: - print(" ⚠️ (quite long, 5-15s is ideal)") + print(" [WARN] (quite long, 5-15s is ideal)") else: - print(" ✓") - print(f" Channels: {'Stereo' if info['is_stereo'] else 'Mono'} {'⚠️ (will convert to mono)' if info['is_stereo'] else '✓'}") - print(f" Max Amplitude: {info['max_amplitude']:.3f} {'✓' if info['is_normalized'] else '⚠️ (low volume)'}") + print(" [OK]") + print(f" Channels: {'Stereo' if info['is_stereo'] else 'Mono'} {'[WARN] (will convert to mono)' if info['is_stereo'] else '[OK]'}") + print(f" Max Amplitude: {info['max_amplitude']:.3f} {'[OK]' if info['is_normalized'] else '[WARN] (low volume)'}") print(f" RMS Level: {info['rms_level']:.4f}") print(f" Noise Floor: {info['estimated_noise_floor']:.4f}") print(f"{'=' * 50}\n") diff --git a/bot.py b/bot.py index f71fa9e..dc3c10d 100644 --- a/bot.py +++ b/bot.py @@ -1,6 +1,8 @@ import numba_config import asyncio import io +import subprocess +import sys import time from typing import Any @@ -365,7 +367,27 @@ class TTSBot(commands.Bot): return None +def auto_update_dependencies() -> None: + """Auto-update pip packages on startup.""" + try: + print("Checking for package updates...") + result = subprocess.run( + [sys.executable, "-m", "pip", "install", "-r", "requirements.txt", "-U", "-q"], + capture_output=True, + text=True, + check=False + ) + if result.returncode == 0: + print("Packages updated successfully (or already up to date)") + else: + print(f"Warning: Package update had issues: {result.stderr}") + except Exception as e: + print(f"Warning: Could not auto-update packages: {e}") + + def main(): + auto_update_dependencies() + errors = Config.validate() if errors: print("Configuration errors:") diff --git a/setup_linux.sh b/setup_linux.sh deleted file mode 100755 index 992529f..0000000 --- a/setup_linux.sh +++ /dev/null @@ -1,213 +0,0 @@ -#!/bin/bash - -# Vox Discord Bot - Linux Setup Script -# This script helps set up the bot and install it as a systemd service - -set -e - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color - -echo -e "${GREEN}========================================${NC}" -echo -e "${GREEN} Vox Discord Bot - Linux Setup${NC}" -echo -e "${GREEN}========================================${NC}" -echo - -# Get the directory where this script is located -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -USERNAME="$(whoami)" - -# Check if running as root -if [ "$EUID" -eq 0 ]; then - echo -e "${RED}Please do not run this script as root.${NC}" - echo "Run it as the user who will own the bot." - exit 1 -fi - -# Function to check if a command exists -command_exists() { - command -v "$1" >/dev/null 2>&1 -} - -echo -e "${YELLOW}Step 1: Checking system dependencies...${NC}" - -# Check for Python 3.10+ -if command_exists python3; then - PYTHON_VERSION=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")') - PYTHON_MAJOR=$(echo $PYTHON_VERSION | cut -d. -f1) - PYTHON_MINOR=$(echo $PYTHON_VERSION | cut -d. -f2) - - if [ "$PYTHON_MAJOR" -ge 3 ] && [ "$PYTHON_MINOR" -ge 10 ]; then - echo -e " ${GREEN}✓${NC} Python $PYTHON_VERSION found" - else - echo -e " ${RED}✗${NC} Python 3.10+ required, found $PYTHON_VERSION" - echo " Please install Python 3.10 or later" - exit 1 - fi -else - echo -e " ${RED}✗${NC} Python 3 not found" - echo " Please install Python 3.10 or later" - exit 1 -fi - -# Check for FFmpeg -if command_exists ffmpeg; then - FFMPEG_VERSION=$(ffmpeg -version 2>&1 | head -n1 | cut -d' ' -f3) - echo -e " ${GREEN}✓${NC} FFmpeg found ($FFMPEG_VERSION)" -else - echo -e " ${RED}✗${NC} FFmpeg not found" - echo "" - echo " Please install FFmpeg:" - echo " Ubuntu/Debian: sudo apt install ffmpeg" - echo " Fedora: sudo dnf install ffmpeg" - echo " Arch: sudo pacman -S ffmpeg" - exit 1 -fi - -# Check for pip -if command_exists pip3; then - echo -e " ${GREEN}✓${NC} pip3 found" -else - echo -e " ${RED}✗${NC} pip3 not found" - echo " Please install python3-pip" - exit 1 -fi - -echo -echo -e "${YELLOW}Step 2: Setting up virtual environment...${NC}" - -cd "$SCRIPT_DIR" - -if [ -d "venv" ]; then - echo " Virtual environment already exists" -else - echo " Creating virtual environment..." - python3 -m venv venv - echo -e " ${GREEN}✓${NC} Virtual environment created" -fi - -echo " Activating virtual environment..." -source venv/bin/activate - -echo " Installing dependencies..." -pip install --upgrade pip -q -pip install -r requirements.txt -q -echo -e " ${GREEN}✓${NC} Dependencies installed" - -echo -echo -e "${YELLOW}Step 3: Checking configuration...${NC}" - -# Check for .env file -if [ -f ".env" ]; then - echo -e " ${GREEN}✓${NC} .env file found" -else - echo -e " ${YELLOW}!${NC} .env file not found" - echo " Creating .env template..." - cat > .env << 'EOF' -# Discord Bot Configuration -DISCORD_TOKEN=your_bot_token_here -TEXT_CHANNEL_ID=your_channel_id_here - -# Voice Configuration -VOICES_DIR=./voices -# DEFAULT_VOICE=estinien -EOF - echo -e " ${YELLOW}!${NC} Please edit .env with your Discord token and channel ID" -fi - -# Check for voices directory -if [ -d "voices" ]; then - VOICE_COUNT=$(find voices -name "*.wav" 2>/dev/null | wc -l) - echo -e " ${GREEN}✓${NC} voices directory found ($VOICE_COUNT voice files)" - if [ "$VOICE_COUNT" -eq 0 ]; then - echo -e " ${YELLOW}!${NC} No voice files found. Add .wav files to the voices directory." - fi -else - echo " Creating voices directory..." - mkdir -p voices - echo -e " ${YELLOW}!${NC} Add voice .wav files to the voices directory" -fi - -echo -echo -e "${YELLOW}Step 4: Setting up systemd service...${NC}" - -read -p "Do you want to install the bot as a systemd service? (y/n) " -n 1 -r -echo -if [[ $REPLY =~ ^[Yy]$ ]]; then - # Create the service file with correct paths - SERVICE_FILE="/tmp/vox.service" - - cat > "$SERVICE_FILE" << EOF -[Unit] -Description=Vox Discord Bot -After=network-online.target -Wants=network-online.target - -[Service] -User=$USERNAME -Group=$USERNAME -WorkingDirectory=$SCRIPT_DIR -ExecStart=$SCRIPT_DIR/venv/bin/python bot.py -Restart=on-failure -RestartSec=10 -TimeoutStopSec=30 -StandardOutput=journal -StandardError=journal -SyslogIdentifier=vox - -# Security hardening -NoNewPrivileges=true -ProtectSystem=strict -ProtectHome=read-only -ReadWritePaths=$SCRIPT_DIR/voices -PrivateTmp=true - -[Install] -WantedBy=multi-user.target -EOF - - echo " Installing systemd service (requires sudo)..." - sudo cp "$SERVICE_FILE" /etc/systemd/system/vox.service - sudo systemctl daemon-reload - echo -e " ${GREEN}✓${NC} Service installed" - - read -p "Do you want to enable the service to start on boot? (y/n) " -n 1 -r - echo - if [[ $REPLY =~ ^[Yy]$ ]]; then - sudo systemctl enable vox - echo -e " ${GREEN}✓${NC} Service enabled for boot" - fi - - read -p "Do you want to start the service now? (y/n) " -n 1 -r - echo - if [[ $REPLY =~ ^[Yy]$ ]]; then - sudo systemctl start vox - echo -e " ${GREEN}✓${NC} Service started" - sleep 2 - echo - echo " Service status:" - sudo systemctl status vox --no-pager || true - fi -fi - -echo -echo -e "${GREEN}========================================${NC}" -echo -e "${GREEN} Setup Complete!${NC}" -echo -e "${GREEN}========================================${NC}" -echo -echo "Useful commands:" -echo " Start bot: sudo systemctl start vox" -echo " Stop bot: sudo systemctl stop vox" -echo " Restart bot: sudo systemctl restart vox" -echo " View status: sudo systemctl status vox" -echo " View logs: journalctl -u vox -f" -echo " Disable boot: sudo systemctl disable vox" -echo -echo "To run the bot manually (without systemd):" -echo " cd $SCRIPT_DIR" -echo " source venv/bin/activate" -echo " python bot.py" -echo \ No newline at end of file