269 lines
7.8 KiB
Bash
269 lines
7.8 KiB
Bash
#!/usr/bin/env bash
|
|||
|
|
|
||
|
|
# TitleBot-NG - Master Launch Script
|
||
|
|
# Starts all components of the TitleBot system
|
||
|
|
# THIS SCRIPT WAS CREATED VIA BLACKBOX AI -- HUMANIZATION REQUIRED
|
||
|
|
|
||
|
|
set -e
|
||
|
|
|
||
|
|
# Color codes for output
|
||
|
|
RED='\033[0;31m'
|
||
|
|
GREEN='\033[0;32m'
|
||
|
|
YELLOW='\033[1;33m'
|
||
|
|
BLUE='\033[0;34m'
|
||
|
|
NC='\033[0m' # No Color
|
||
|
|
|
||
|
|
# Detect OS
|
||
|
|
detect_os() {
|
||
|
|
case "$(uname -s)" in
|
||
|
|
Linux*) echo "linux" ;;
|
||
|
|
FreeBSD*) echo "freebsd" ;;
|
||
|
|
*) echo "linux" ;;
|
||
|
|
esac
|
||
|
|
}
|
||
|
|
|
||
|
|
OS=$(detect_os)
|
||
|
|
echo -e "${BLUE}Detected OS: $OS${NC}"
|
||
|
|
|
||
|
|
# Set OS-specific binary names
|
||
|
|
get_bin_name() {
|
||
|
|
local base=$1
|
||
|
|
case "$OS" in
|
||
|
|
freebsd)
|
||
|
|
case "$base" in
|
||
|
|
jep) echo "jepfbd" ;;
|
||
|
|
vs) echo "vsfbsd" ;;
|
||
|
|
*) echo "${base}_${OS}" ;;
|
||
|
|
esac
|
||
|
|
;;
|
||
|
|
*)
|
||
|
|
echo "$base"
|
||
|
|
;;
|
||
|
|
esac
|
||
|
|
}
|
||
|
|
|
||
|
|
JEP_BIN=$(get_bin_name "jep")
|
||
|
|
VS_BIN=$(get_bin_name "vs")
|
||
|
|
|
||
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
|
|
cd "$SCRIPT_DIR"
|
||
|
|
|
||
|
|
# PID file directory
|
||
|
|
PID_DIR="$SCRIPT_DIR/.pids"
|
||
|
|
mkdir -p "$PID_DIR"
|
||
|
|
|
||
|
|
# Log directory
|
||
|
|
LOG_DIR="$SCRIPT_DIR/logs"
|
||
|
|
mkdir -p "$LOG_DIR"
|
||
|
|
|
||
|
|
# Cleanup function
|
||
|
|
cleanup() {
|
||
|
|
echo -e "\n${YELLOW}Shutting down all services...${NC}"
|
||
|
|
|
||
|
|
# Kill all background processes
|
||
|
|
if [ -d "$PID_DIR" ]; then
|
||
|
|
for pidfile in "$PID_DIR"/*.pid; do
|
||
|
|
if [ -f "$pidfile" ]; then
|
||
|
|
pid=$(cat "$pidfile")
|
||
|
|
name=$(basename "$pidfile" .pid)
|
||
|
|
if kill -0 "$pid" 2>/dev/null; then
|
||
|
|
echo -e "${YELLOW}Stopping $name (PID: $pid)${NC}"
|
||
|
|
kill "$pid" 2>/dev/null || true
|
||
|
|
fi
|
||
|
|
rm -f "$pidfile"
|
||
|
|
fi
|
||
|
|
done
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Fallback: kill any lingering service processes even if pid files are stale/missing
|
||
|
|
for bin in "$JEP_BIN" "$VS_BIN"; do
|
||
|
|
pkill -x "$bin" 2>/dev/null || true
|
||
|
|
done
|
||
|
|
for script in scraper post_results get_votes get_user_list; do
|
||
|
|
pkill -f "python3 $script.py" 2>/dev/null || true
|
||
|
|
done
|
||
|
|
|
||
|
|
echo -e "${GREEN}All services stopped.${NC}"
|
||
|
|
exit 0
|
||
|
|
}
|
||
|
|
|
||
|
|
# Set up trap for cleanup
|
||
|
|
trap cleanup SIGINT SIGTERM EXIT
|
||
|
|
|
||
|
|
# Function to start a Go service
|
||
|
|
start_go_service() {
|
||
|
|
local name=$1
|
||
|
|
local dir=$2
|
||
|
|
local binary=$3
|
||
|
|
|
||
|
|
echo -e "${BLUE}Building $name...${NC}"
|
||
|
|
if [ "$OS" = "freebsd" ]; then
|
||
|
|
(cd "$dir" && GOOS=freebsd go build -o "$binary") || {
|
||
|
|
echo -e "${RED}Failed to build $name for FreeBSD${NC}"
|
||
|
|
return 1
|
||
|
|
}
|
||
|
|
else
|
||
|
|
(cd "$dir" && go build -o "$binary") || {
|
||
|
|
echo -e "${RED}Failed to build $name${NC}"
|
||
|
|
return 1
|
||
|
|
}
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo -e "${GREEN}Starting $name...${NC}"
|
||
|
|
(cd "$dir" && ./"$binary" > "$LOG_DIR/$name.log" 2>&1) &
|
||
|
|
echo $! > "$PID_DIR/$name.pid"
|
||
|
|
|
||
|
|
# Brief wait to check if it started successfully
|
||
|
|
sleep 1
|
||
|
|
if kill -0 $(cat "$PID_DIR/$name.pid") 2>/dev/null; then
|
||
|
|
echo -e "${GREEN}✓ $name started (PID: $(cat "$PID_DIR/$name.pid"))${NC}"
|
||
|
|
return 0
|
||
|
|
else
|
||
|
|
echo -e "${RED}✗ $name failed to start${NC}"
|
||
|
|
return 1
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
# Function to start a Python service
|
||
|
|
start_python_service() {
|
||
|
|
local name=$1
|
||
|
|
local script=$2
|
||
|
|
local config_path=${3:-}
|
||
|
|
local config_arg=""
|
||
|
|
local label="$name"
|
||
|
|
if [ -n "$config_path" ]; then
|
||
|
|
config_arg="$config_path"
|
||
|
|
label="${name}-$(basename "$config_path" .yaml)"
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo -e "${GREEN}Starting $label...${NC}"
|
||
|
|
|
||
|
|
# Activate virtual environment and run script
|
||
|
|
(source .env/bin/activate && python3 "$script" $config_arg > "$LOG_DIR/$label.log" 2>&1) &
|
||
|
|
echo $! > "$PID_DIR/$label.pid"
|
||
|
|
|
||
|
|
# Brief wait to check if it started successfully
|
||
|
|
sleep 1
|
||
|
|
if kill -0 $(cat "$PID_DIR/$label.pid") 2>/dev/null; then
|
||
|
|
echo -e "${GREEN}✓ $label started (PID: $(cat "$PID_DIR/$label.pid"))${NC}"
|
||
|
|
return 0
|
||
|
|
else
|
||
|
|
echo -e "${RED}✗ $label failed to start${NC}"
|
||
|
|
return 1
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
# Check if virtual environment exists
|
||
|
|
if [ ! -d ".env" ]; then
|
||
|
|
echo -e "${RED}Error: Python virtual environment not found at .env${NC}"
|
||
|
|
echo -e "${YELLOW}Please create it with: python3 -m venv .env${NC}"
|
||
|
|
echo -e "${YELLOW}Then install dependencies: source .env/bin/activate && pip install matrix-nio pyyaml requests${NC}"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Check if config.yaml exists
|
||
|
|
if [ ! -f "configs/config.yaml" ]; then
|
||
|
|
echo -e "${RED}Error: configs/config.yaml not found${NC}"
|
||
|
|
echo -e "${YELLOW}Please copy configs/config_example.yaml to configs/config.yaml and configure it${NC}"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Discover active room configs (skip example/template files)
|
||
|
|
room_configs=()
|
||
|
|
for cfg in configs/*.yaml; do
|
||
|
|
if [[ "$(basename "$cfg")" == *example* ]]; then
|
||
|
|
continue
|
||
|
|
fi
|
||
|
|
room_configs+=("$cfg")
|
||
|
|
done
|
||
|
|
if [ ${#room_configs[@]} -eq 0 ]; then
|
||
|
|
echo -e "${RED}Error: no room configs found in configs/*.yaml${NC}"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
echo -e "${BLUE}Found ${#room_configs[@]} room config(s): ${room_configs[*]}${NC}"
|
||
|
|
|
||
|
|
echo -e "${BLUE}========================================${NC}"
|
||
|
|
echo -e "${BLUE} TitleBot-NG - Starting All Services ${NC}"
|
||
|
|
echo -e "${BLUE}========================================${NC}"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
# Start services in order
|
||
|
|
echo -e "${YELLOW}Cleaning up any existing processes...${NC}"
|
||
|
|
for bin in "$JEP_BIN" "$VS_BIN"; do
|
||
|
|
if pgrep -x "$bin" > /dev/null 2>&1; then
|
||
|
|
echo -e "${YELLOW}Stopping existing $bin process...${NC}"
|
||
|
|
pkill -x "$bin" 2>/dev/null || true
|
||
|
|
fi
|
||
|
|
done
|
||
|
|
for script in scraper post_results get_votes get_user_list; do
|
||
|
|
if pgrep -f "python3 $script.py" > /dev/null 2>&1; then
|
||
|
|
echo -e "${YELLOW}Stopping existing $script process...${NC}"
|
||
|
|
pkill -f "python3 $script.py" 2>/dev/null || true
|
||
|
|
fi
|
||
|
|
done
|
||
|
|
sleep 1
|
||
|
|
|
||
|
|
echo -e "${YELLOW}Step 1: Starting scrapers (write room_slugs.json for voting paths)...${NC}"
|
||
|
|
for cfg in "${room_configs[@]}"; do
|
||
|
|
start_python_service "scraper" "scraper.py" "$cfg"
|
||
|
|
done
|
||
|
|
sleep 2
|
||
|
|
|
||
|
|
echo -e "${YELLOW}Step 2: Starting backend services...${NC}"
|
||
|
|
start_go_service "jsonEndpoint" "jsonEndpoint" "$JEP_BIN"; true
|
||
|
|
sleep 2 # Give jsonEndpoint time to fully start
|
||
|
|
|
||
|
|
start_go_service "voteServer" "voteServer" "$VS_BIN"; true
|
||
|
|
sleep 2 # Give voteServer time to fully start
|
||
|
|
|
||
|
|
echo ""
|
||
|
|
echo -e "${YELLOW}Step 3: Starting remaining Matrix bots...${NC}"
|
||
|
|
for cfg in "${room_configs[@]}"; do
|
||
|
|
start_python_service "post_results" "post_results.py" "$cfg"
|
||
|
|
sleep 1
|
||
|
|
start_python_service "get_votes" "get_votes.py" "$cfg"
|
||
|
|
sleep 1
|
||
|
|
start_python_service "get_user_list" "get_user_list.py" "$cfg"
|
||
|
|
done
|
||
|
|
|
||
|
|
echo ""
|
||
|
|
echo -e "${GREEN}========================================${NC}"
|
||
|
|
echo -e "${GREEN} All services started successfully! ${NC}"
|
||
|
|
echo -e "${GREEN}========================================${NC}"
|
||
|
|
echo ""
|
||
|
|
echo -e "${BLUE}Service Status:${NC}"
|
||
|
|
echo -e " • JSON Endpoint: http://localhost:9080"
|
||
|
|
echo -e " • Vote Server: http://localhost:9081"
|
||
|
|
for cfg in "${room_configs[@]}"; do
|
||
|
|
label=$(basename "$cfg" .yaml)
|
||
|
|
echo -e " • Room ($label): scraper / post_results / get_votes / get_user_list"
|
||
|
|
done
|
||
|
|
echo ""
|
||
|
|
echo -e "${BLUE}Logs are available in: $LOG_DIR${NC}"
|
||
|
|
echo -e "${BLUE}PIDs are stored in: $PID_DIR${NC}"
|
||
|
|
echo ""
|
||
|
|
echo -e "${YELLOW}Press Ctrl+C to stop all services${NC}"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
# Keep script running and monitor processes
|
||
|
|
while true; do
|
||
|
|
# Check if all processes are still running
|
||
|
|
all_running=true
|
||
|
|
for pidfile in "$PID_DIR"/*.pid; do
|
||
|
|
if [ -f "$pidfile" ]; then
|
||
|
|
pid=$(cat "$pidfile")
|
||
|
|
if ! kill -0 "$pid" 2>/dev/null; then
|
||
|
|
name=$(basename "$pidfile" .pid)
|
||
|
|
echo -e "${RED}Warning: $name (PID: $pid) has stopped unexpectedly${NC}"
|
||
|
|
all_running=false
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
done
|
||
|
|
|
||
|
|
if [ "$all_running" = false ]; then
|
||
|
|
echo -e "${YELLOW}Some services have stopped. Check logs in $LOG_DIR${NC}"
|
||
|
|
fi
|
||
|
|
|
||
|
|
sleep 10
|
||
|
|
done
|