init
This commit is contained in:
485
start
Executable file
485
start
Executable file
@@ -0,0 +1,485 @@
|
||||
#!/bin/bash
|
||||
|
||||
#==============================================================================
|
||||
# Animex Extension Server Startup Script
|
||||
# Description: Professional startup script with comprehensive error handling,
|
||||
# logging, and environment management for Animex Extension Server
|
||||
# Author: Animex Developer (Indie)
|
||||
# Date: 2023-10-01
|
||||
# License: GPL-3.0
|
||||
# Version: 2.0
|
||||
#==============================================================================
|
||||
|
||||
set -euo pipefail # Exit on error, undefined vars, pipe failures
|
||||
|
||||
#==============================================================================
|
||||
# CONFIGURATION
|
||||
#==============================================================================
|
||||
|
||||
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
readonly VENV_DIR="${SCRIPT_DIR}/venv"
|
||||
readonly REQUIREMENTS="${SCRIPT_DIR}/requirements.txt"
|
||||
readonly FIRST_RUN_FLAG="${SCRIPT_DIR}/.first_run_complete"
|
||||
readonly LOGO_FILE="${SCRIPT_DIR}/logo.txt"
|
||||
readonly LOG_FILE="${SCRIPT_DIR}/startup.log"
|
||||
|
||||
readonly APP_NAME="Animex Extension Server"
|
||||
readonly APP_HOST="${APP_HOST:-0.0.0.0}"
|
||||
readonly APP_PORT="${APP_PORT:-7275}"
|
||||
readonly PYTHON_CMD="${PYTHON_CMD:-python3}"
|
||||
|
||||
#==============================================================================
|
||||
# UTILITY FUNCTIONS
|
||||
#==============================================================================
|
||||
|
||||
# Logging function with timestamps
|
||||
log() {
|
||||
local level="$1"
|
||||
shift
|
||||
local message="$*"
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo "[$timestamp] [$level] $message" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
log_info() { log "INFO" "$@"; }
|
||||
log_warn() { log "WARN" "$@"; }
|
||||
log_error() { log "ERROR" "$@"; }
|
||||
|
||||
# Display colored output
|
||||
print_colored() {
|
||||
local color_code="$1"
|
||||
local message="$2"
|
||||
echo -e "\033[${color_code}m${message}\033[0m"
|
||||
}
|
||||
|
||||
print_success() { print_colored "1;32" "$1"; }
|
||||
print_warning() { print_colored "1;33" "$1"; }
|
||||
print_error() { print_colored "1;31" "$1"; }
|
||||
print_info() { print_colored "1;36" "$1"; }
|
||||
print_orange() { print_colored "1;38;5;208" "$1"; }
|
||||
|
||||
# Display Animex logo in bright orange
|
||||
display_logo() {
|
||||
echo ""
|
||||
if [[ -f "$LOGO_FILE" ]]; then
|
||||
print_orange "$(cat "$LOGO_FILE")"
|
||||
echo ""
|
||||
print_orange "╔══════════════════════════════════════════════════════════════════════════╗"
|
||||
print_orange "║ ANIMEX EXTENSION SERVER ║"
|
||||
print_orange "║ Advanced Anime Streaming Platform ║"
|
||||
print_orange "╚══════════════════════════════════════════════════════════════════════════╝"
|
||||
else
|
||||
print_orange "╔══════════════════════════════════════════════════════════════════════════╗"
|
||||
print_orange "║ ANIMEX EXTENSION SERVER ║"
|
||||
print_orange "║ Advanced Anime Streaming Platform ║"
|
||||
print_orange "╚══════════════════════════════════════════════════════════════════════════╝"
|
||||
log_warn "Logo file not found: $LOGO_FILE"
|
||||
fi
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Check system requirements
|
||||
check_requirements() {
|
||||
log_info "Checking system requirements for Animex Extension Server..."
|
||||
|
||||
if ! command -v "$PYTHON_CMD" &> /dev/null; then
|
||||
log_error "Python 3 is not installed or not in PATH"
|
||||
print_error "ERROR: $PYTHON_CMD command not found. Please install Python 3."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local python_version
|
||||
python_version=$("$PYTHON_CMD" --version 2>&1 | cut -d' ' -f2)
|
||||
log_info "Found Python version: $python_version"
|
||||
|
||||
if ! "$PYTHON_CMD" -m venv --help &> /dev/null; then
|
||||
log_error "Python venv module is not available"
|
||||
print_error "ERROR: Python venv module not found. Please install python3-venv."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "System requirements check passed for Animex Extension Server"
|
||||
}
|
||||
|
||||
# Create and setup virtual environment
|
||||
setup_virtual_environment() {
|
||||
log_info "Setting up Animex Extension Server virtual environment at: $VENV_DIR"
|
||||
|
||||
if [[ ! -d "$VENV_DIR" ]]; then
|
||||
print_info "🔧 Creating Animex virtual environment..."
|
||||
if ! "$PYTHON_CMD" -m venv "$VENV_DIR"; then
|
||||
log_error "Failed to create virtual environment"
|
||||
print_error "ERROR: Failed to create virtual environment"
|
||||
exit 1
|
||||
fi
|
||||
log_info "Animex virtual environment created successfully"
|
||||
print_success "✓ Animex virtual environment created"
|
||||
else
|
||||
log_info "Animex virtual environment already exists"
|
||||
print_info "🔧 Animex virtual environment already exists"
|
||||
fi
|
||||
}
|
||||
|
||||
# Activate virtual environment
|
||||
activate_virtual_environment() {
|
||||
local activate_script="${VENV_DIR}/bin/activate"
|
||||
|
||||
if [[ ! -f "$activate_script" ]]; then
|
||||
log_error "Virtual environment activation script not found: $activate_script"
|
||||
print_error "ERROR: Virtual environment is corrupted. Please delete the venv directory and try again."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
source "$activate_script"
|
||||
log_info "Animex virtual environment activated"
|
||||
print_success "✓ Animex virtual environment activated"
|
||||
}
|
||||
|
||||
#==============================================================================
|
||||
# MODULE & EXTENSION REQUIREMENTS MANAGEMENT
|
||||
#==============================================================================
|
||||
|
||||
# Extract requirements from .module files
|
||||
extract_module_requirements() {
|
||||
local modules_dir="${SCRIPT_DIR}/modules"
|
||||
local temp_req_file="$1"
|
||||
|
||||
if [[ ! -d "$modules_dir" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
while IFS= read -r -d '' module_file; do
|
||||
local json_header
|
||||
json_header=$(sed -n '2,/^---$/p' "$module_file" | sed '$d' 2>/dev/null)
|
||||
|
||||
if [[ -n "$json_header" ]]; then
|
||||
local requirements
|
||||
requirements=$("$PYTHON_CMD" -c "
|
||||
import json, sys
|
||||
try:
|
||||
data = json.loads('''$json_header''')
|
||||
reqs = data.get('requirements', [])
|
||||
for req in reqs: print(req)
|
||||
except: pass
|
||||
" 2>/dev/null)
|
||||
|
||||
if [[ -n "$requirements" ]]; then
|
||||
echo "$requirements" >> "$temp_req_file"
|
||||
fi
|
||||
fi
|
||||
done < <(find "$modules_dir" -name "*.module" -type f -print0)
|
||||
}
|
||||
|
||||
# Check and free required ports
|
||||
check_and_free_ports() {
|
||||
local ports=(7275 7277)
|
||||
|
||||
for port in "${ports[@]}"; do
|
||||
log_info "Checking if port $port is in use..."
|
||||
|
||||
local pids
|
||||
pids=$(lsof -ti tcp:"$port" || true)
|
||||
|
||||
if [[ -n "$pids" ]]; then
|
||||
log_warn "Port $port is already in use by PID(s): $pids"
|
||||
print_warning "⚠ Port $port is in use. Attempting to stop process(es)..."
|
||||
|
||||
# Try graceful shutdown first
|
||||
kill $pids 2>/dev/null || true
|
||||
sleep 2
|
||||
|
||||
# Force kill if still alive
|
||||
for pid in $pids; do
|
||||
if kill -0 "$pid" 2>/dev/null; then
|
||||
log_warn "PID $pid did not terminate gracefully. Force killing..."
|
||||
kill -9 "$pid" 2>/dev/null || true
|
||||
fi
|
||||
done
|
||||
|
||||
sleep 1
|
||||
fi
|
||||
|
||||
# Final verification
|
||||
if lsof -ti tcp:"$port" &>/dev/null; then
|
||||
log_error "Port $port is still in use after kill attempts"
|
||||
print_error "❌ Failed to free port $port. Aborting startup."
|
||||
exit 1
|
||||
else
|
||||
log_info "Port $port is free"
|
||||
print_success "✓ Port $port is available"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
# Extract requirements from extension package.json files
|
||||
extract_extension_requirements() {
|
||||
local extensions_dir="${SCRIPT_DIR}/extensions"
|
||||
local temp_req_file="$1"
|
||||
|
||||
if [[ ! -d "$extensions_dir" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
while IFS= read -r -d '' pkg_file; do
|
||||
local requirements
|
||||
requirements=$("$PYTHON_CMD" -c "
|
||||
import json, sys
|
||||
try:
|
||||
with open('$pkg_file', 'r') as f:
|
||||
data = json.load(f)
|
||||
reqs = data.get('requirements', [])
|
||||
for req in reqs: print(req)
|
||||
except: pass
|
||||
" 2>/dev/null)
|
||||
|
||||
if [[ -n "$requirements" ]]; then
|
||||
echo "$requirements" >> "$temp_req_file"
|
||||
fi
|
||||
done < <(find "$extensions_dir" -name "package.json" -type f -print0)
|
||||
}
|
||||
|
||||
# Install Python dependencies with module and extension requirements
|
||||
install_dependencies() {
|
||||
local temp_requirements="${SCRIPT_DIR}/.temp_all_requirements.txt"
|
||||
|
||||
# Clear temp file
|
||||
> "$temp_requirements"
|
||||
|
||||
# Extract requirements from both modules and extensions
|
||||
extract_module_requirements "$temp_requirements"
|
||||
extract_extension_requirements "$temp_requirements"
|
||||
|
||||
# Consolidate and count unique requirements
|
||||
local final_reqs_count=0
|
||||
if [[ -s "$temp_requirements" ]]; then
|
||||
sort -u "$temp_requirements" -o "$temp_requirements"
|
||||
final_reqs_count=$(wc -l < "$temp_requirements")
|
||||
fi
|
||||
|
||||
# Backup original requirements.txt
|
||||
local backup_requirements="${SCRIPT_DIR}/.requirements_backup.txt"
|
||||
if [[ -f "$REQUIREMENTS" ]]; then
|
||||
cp "$REQUIREMENTS" "$backup_requirements"
|
||||
fi
|
||||
|
||||
# Merge all requirements
|
||||
{
|
||||
if [[ -f "$backup_requirements" ]]; then
|
||||
cat "$backup_requirements"
|
||||
fi
|
||||
if [[ $final_reqs_count -gt 0 ]]; then
|
||||
echo ""
|
||||
echo "# Auto-generated module & extension requirements"
|
||||
cat "$temp_requirements"
|
||||
fi
|
||||
} > "$REQUIREMENTS"
|
||||
|
||||
if [[ $final_reqs_count -gt 0 ]]; then
|
||||
log_info "Merged $final_reqs_count unique requirements from modules/extensions."
|
||||
print_success "✓ Found and added $final_reqs_count additional requirements."
|
||||
fi
|
||||
|
||||
if [[ ! -f "$REQUIREMENTS" ]]; then
|
||||
log_warn "Requirements file not found: $REQUIREMENTS"
|
||||
print_warning "WARNING: requirements.txt not found. Server might not run correctly."
|
||||
return 0
|
||||
fi
|
||||
|
||||
log_info "Installing/updating dependencies from: $REQUIREMENTS"
|
||||
print_info "📦 Installing required packages..."
|
||||
|
||||
# Upgrade pip first
|
||||
pip install --upgrade pip >> "$LOG_FILE" 2>&1
|
||||
|
||||
# Install all requirements
|
||||
if ! pip install -r "$REQUIREMENTS" >> "$LOG_FILE" 2>&1; then
|
||||
log_error "Failed to install dependencies. Check $LOG_FILE for details."
|
||||
print_error "ERROR: Failed to install packages. Check log file."
|
||||
# Restore original requirements before exiting
|
||||
if [[ -f "$backup_requirements" ]]; then mv "$backup_requirements" "$REQUIREMENTS"; fi
|
||||
rm -f "$temp_requirements"
|
||||
deactivate 2>/dev/null || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Restore original requirements.txt
|
||||
if [[ -f "$backup_requirements" ]]; then
|
||||
mv "$backup_requirements" "$REQUIREMENTS"
|
||||
else
|
||||
# If no backup, just clear the generated part
|
||||
> "$REQUIREMENTS"
|
||||
fi
|
||||
rm -f "$temp_requirements"
|
||||
|
||||
log_info "Dependencies installed successfully"
|
||||
print_success "✓ Dependencies installed"
|
||||
}
|
||||
|
||||
# Perform first-time setup
|
||||
first_time_setup() {
|
||||
print_orange "🚀 Performing Animex Extension Server first-time setup..."
|
||||
log_info "Starting Animex Extension Server first-time setup"
|
||||
|
||||
check_requirements
|
||||
setup_virtual_environment
|
||||
activate_virtual_environment
|
||||
install_dependencies
|
||||
|
||||
touch "$FIRST_RUN_FLAG"
|
||||
log_info "Animex Extension Server first-time setup completed"
|
||||
print_success "✓ Animex Extension Server first-time setup completed"
|
||||
}
|
||||
|
||||
# Start the Animex Extension Server
|
||||
start_application() {
|
||||
log_info "Starting $APP_NAME on http://$APP_HOST:$APP_PORT"
|
||||
print_orange "🎬 Starting Animex Extension Server..."
|
||||
print_orange "🌐 Server URL: http://$APP_HOST:$APP_PORT"
|
||||
print_orange "📺 Animex Extension Server is ready for anime streaming!"
|
||||
print_info "Press CTRL+C to stop the Animex server"
|
||||
echo ""
|
||||
|
||||
# Check if uvicorn is available
|
||||
if ! command -v uvicorn &> /dev/null; then
|
||||
log_error "uvicorn not found in virtual environment"
|
||||
print_error "ERROR: uvicorn is not installed. Please check your requirements.txt"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if live reload is enabled
|
||||
if [[ "${LIVE_RELOAD:-false}" == "true" ]]; then
|
||||
print_info "🔄 Live reload is enabled - server will restart on file changes"
|
||||
# Start the server with file watching
|
||||
python watch.py
|
||||
else
|
||||
# Start the server normally
|
||||
uvicorn app:app --host "$APP_HOST" --port "$APP_PORT" --log-level info
|
||||
fi
|
||||
}
|
||||
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
local exit_code=$?
|
||||
log_info "Shutting down Animex Extension Server (exit code: $exit_code)"
|
||||
|
||||
# Clean up any remaining temporary requirement files
|
||||
rm -f "${SCRIPT_DIR}/.temp_module_requirements.txt" "${SCRIPT_DIR}/.requirements_backup.txt"
|
||||
|
||||
if [[ -n "${VIRTUAL_ENV:-}" ]]; then
|
||||
deactivate 2>/dev/null || true
|
||||
log_info "Animex virtual environment deactivated"
|
||||
print_info "🔧 Animex virtual environment deactivated"
|
||||
fi
|
||||
|
||||
print_orange "🛑 Animex Extension Server stopped"
|
||||
log_info "Animex Extension Server shutdown complete"
|
||||
exit $exit_code
|
||||
}
|
||||
|
||||
# Display help information
|
||||
show_help() {
|
||||
cat << EOF
|
||||
Usage: $0 [OPTIONS]
|
||||
|
||||
Animex Extension Server - Advanced Anime Streaming Platform
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Show this help message
|
||||
--clean Remove virtual environment and start fresh
|
||||
--check Check system requirements only
|
||||
--live Enable live reload - server will restart on file changes
|
||||
--version Show script version
|
||||
|
||||
ENVIRONMENT VARIABLES:
|
||||
APP_HOST Server host (default: 0.0.0.0)
|
||||
APP_PORT Server port (default: 7275)
|
||||
PYTHON_CMD Python command (default: python3)
|
||||
|
||||
EXAMPLES:
|
||||
$0 Start Animex Extension Server
|
||||
$0 --clean Clean install Animex Extension Server
|
||||
APP_PORT=8080 $0 Start Animex on port 8080
|
||||
|
||||
ABOUT ANIMEX:
|
||||
Animex Extension Server is an advanced anime streaming platform
|
||||
designed to provide seamless anime content delivery and management.
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
#==============================================================================
|
||||
# MAIN EXECUTION
|
||||
#==============================================================================
|
||||
|
||||
main() {
|
||||
# Parse command line arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-h|--help)
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
--clean)
|
||||
print_info "🧹 Cleaning Animex virtual environment..."
|
||||
rm -rf "$VENV_DIR" "$FIRST_RUN_FLAG"
|
||||
log_info "Clean install requested - removed Animex venv and first run flag"
|
||||
;;
|
||||
--check)
|
||||
check_requirements
|
||||
print_success "✓ Animex system requirements check passed"
|
||||
exit 0
|
||||
;;
|
||||
--live)
|
||||
export LIVE_RELOAD=true
|
||||
print_info "🔄 Live reload enabled"
|
||||
log_info "Live reload feature enabled"
|
||||
;;
|
||||
--version)
|
||||
echo "Animex Extension Server Startup Script v2.0"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
print_error "Unknown option: $1"
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Set up signal handlers
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
# Initialize log file
|
||||
echo "=== Animex Extension Server Startup - $(date) ===" >> "$LOG_FILE"
|
||||
|
||||
# Display Animex logo
|
||||
display_logo
|
||||
|
||||
# Check if this is first run
|
||||
if [[ ! -f "$FIRST_RUN_FLAG" ]]; then
|
||||
first_time_setup
|
||||
else
|
||||
print_orange "🎉 Welcome back to Animex Extension Server!"
|
||||
log_info "Returning Animex user detected"
|
||||
check_requirements
|
||||
fi
|
||||
|
||||
# Activate virtual environment
|
||||
activate_virtual_environment
|
||||
|
||||
# Install/update dependencies
|
||||
install_dependencies
|
||||
|
||||
echo ""
|
||||
echo "✅ All systems go! Starting Animex Extension Server... Checking ports..."
|
||||
check_and_free_ports
|
||||
|
||||
# Start the Animex Extension Server
|
||||
start_application
|
||||
}
|
||||
|
||||
# Execute main function with all arguments
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user