You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
187 lines
5.7 KiB
187 lines
5.7 KiB
#!/bin/bash |
|
|
|
# Directory to monitor |
|
BASE_DIR="/home/shane/foodie_automator" |
|
CHECKSUM_FILE="$BASE_DIR/.file_checksum" |
|
LOG_FILE="$BASE_DIR/logs/manage_scripts.log" |
|
VENV_PYTHON="$BASE_DIR/venv/bin/python" |
|
LOCK_DIR="$BASE_DIR/locks" |
|
|
|
# Log function |
|
log() { |
|
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE" |
|
} |
|
|
|
# Calculate checksum of files (excluding logs, JSON files, and venv) |
|
calculate_checksum() { |
|
find "$BASE_DIR" -type f \ |
|
-not -path "$BASE_DIR/logs/*" \ |
|
-not -path "$BASE_DIR/*.json" \ |
|
-not -path "$BASE_DIR/.file_checksum" \ |
|
-not -path "$BASE_DIR/venv/*" \ |
|
-not -path "$BASE_DIR/locks/*" \ |
|
-exec sha256sum {} \; | sort | sha256sum | awk '{print $1}' |
|
} |
|
|
|
# Check if a script is running (using lock file) |
|
check_running() { |
|
local script_name="$1" |
|
local lock_file="$LOCK_DIR/${script_name}.lock" |
|
if [ -f "$lock_file" ]; then |
|
local pid=$(cat "$lock_file") |
|
if ps -p "$pid" > /dev/null; then |
|
log "$script_name is already running (PID: $pid)" |
|
return 0 |
|
else |
|
log "Stale lock file found for $script_name, removing" |
|
rm -f "$lock_file" |
|
fi |
|
fi |
|
return 1 |
|
} |
|
|
|
# Create lock file |
|
create_lock() { |
|
local script_name="$1" |
|
local lock_file="$LOCK_DIR/${script_name}.lock" |
|
mkdir -p "$LOCK_DIR" |
|
echo $$ > "$lock_file" |
|
log "Created lock file for $script_name (PID: $$)" |
|
} |
|
|
|
# Remove lock file |
|
remove_lock() { |
|
local script_name="$1" |
|
local lock_file="$LOCK_DIR/${script_name}.lock" |
|
rm -f "$lock_file" |
|
log "Removed lock file for $script_name" |
|
} |
|
|
|
# Stop scripts |
|
stop_scripts() { |
|
log "Stopping scripts..." |
|
for script in foodie_automator_*.py; do |
|
if [ -f "$script" ] && [ "$script" != "foodie_weekly_thread.py" ] && [ "$script" != "foodie_engagement_tweet.py" ]; then |
|
local script_name="${script%.py}" |
|
pkill -TERM -f "$VENV_PYTHON.*$script_name" || true |
|
fi |
|
done |
|
sleep 10 |
|
for script in foodie_automator_*.py; do |
|
if [ -f "$script" ] && [ "$script" != "foodie_weekly_thread.py" ] && [ "$script" != "foodie_engagement_tweet.py" ]; then |
|
local script_name="${script%.py}" |
|
pkill -9 -f "$VENV_PYTHON.*$script_name" || true |
|
remove_lock "$script_name" |
|
fi |
|
done |
|
log "Scripts stopped." |
|
} |
|
|
|
# Start scripts |
|
start_scripts() { |
|
log "Starting scripts..." |
|
cd "$BASE_DIR" || { log "Failed to change to $BASE_DIR"; exit 1; } |
|
|
|
# Source virtual environment |
|
if [ -f "$BASE_DIR/venv/bin/activate" ]; then |
|
source "$BASE_DIR/venv/bin/activate" |
|
else |
|
log "Error: Virtual environment not found at $BASE_DIR/venv" |
|
exit 1 |
|
fi |
|
|
|
# Load .env variables |
|
if [ -f "$BASE_DIR/.env" ]; then |
|
export $(grep -v '^#' "$BASE_DIR/.env" | xargs) |
|
log ".env variables loaded" |
|
else |
|
log "Error: .env file not found at $BASE_DIR/.env" |
|
exit 1 |
|
fi |
|
|
|
# Find and start all foodie_automator_*.py scripts (excluding weekly/engagement) |
|
for script in foodie_automator_*.py; do |
|
if [ -f "$script" ] && [ "$script" != "foodie_weekly_thread.py" ] && [ "$script" != "foodie_engagement_tweet.py" ]; then |
|
local script_name="${script%.py}" |
|
if ! check_running "$script_name"; then |
|
log "Starting $script..." |
|
create_lock "$script_name" |
|
nohup "$VENV_PYTHON" "$script" >> "$BASE_DIR/logs/${script_name}.log" 2>&1 & |
|
if [ $? -eq 0 ]; then |
|
log "$script started successfully" |
|
else |
|
log "Failed to start $script" |
|
remove_lock "$script_name" |
|
fi |
|
fi |
|
fi |
|
done |
|
log "All scripts started." |
|
} |
|
|
|
# Update dependencies |
|
update_dependencies() { |
|
log "Updating dependencies..." |
|
cd "$BASE_DIR" || { log "Failed to change to $BASE_DIR"; exit 1; } |
|
|
|
# Create venv if it doesn't exist |
|
if [ ! -d "venv" ]; then |
|
python3 -m venv venv |
|
log "Created new virtual environment" |
|
fi |
|
|
|
# Source virtual environment |
|
if [ -f "$BASE_DIR/venv/bin/activate" ]; then |
|
source "$BASE_DIR/venv/bin/activate" |
|
else |
|
log "Error: Virtual environment not found at $BASE_DIR/venv" |
|
exit 1 |
|
fi |
|
|
|
# Update pip and install requirements |
|
"$VENV_PYTHON" -m pip install --upgrade pip |
|
if [ -f "requirements.txt" ]; then |
|
"$VENV_PYTHON" -m pip install -r requirements.txt || { |
|
log "Failed to install requirements.txt, attempting fallback dependencies" |
|
"$VENV_PYTHON" -m pip install requests openai beautifulsoup4 feedparser praw duckduckgo_search selenium Pillow pytesseract webdriver-manager |
|
log "Fallback: Installed core dependencies" |
|
} |
|
else |
|
log "Error: requirements.txt not found, installing core dependencies" |
|
"$VENV_PYTHON" -m pip install requests openai beautifulsoup4 feedparser praw duckduckgo_search selenium Pillow pytesseract webdriver-manager |
|
fi |
|
log "Dependencies updated." |
|
} |
|
|
|
# Main logic |
|
log "Checking for file changes..." |
|
CURRENT_CHECKSUM=$(calculate_checksum) |
|
|
|
if [ -f "$CHECKSUM_FILE" ]; then |
|
PREVIOUS_CHECKSUM=$(cat "$CHECKSUM_FILE") |
|
else |
|
PREVIOUS_CHECKSUM="" |
|
fi |
|
|
|
if [ "$CURRENT_CHECKSUM" != "$PREVIOUS_CHECKSUM" ]; then |
|
log "File changes detected. Previous checksum: $PREVIOUS_CHECKSUM, Current checksum: $CURRENT_CHECKSUM" |
|
|
|
# Stop scripts if running |
|
if pgrep -f "$VENV_PYTHON.*foodie_automator" > /dev/null; then |
|
stop_scripts |
|
fi |
|
|
|
# Update dependencies |
|
update_dependencies |
|
|
|
# Start scripts |
|
start_scripts |
|
|
|
# Update checksum |
|
echo "$CURRENT_CHECKSUM" > "$CHECKSUM_FILE" |
|
log "Checksum updated." |
|
else |
|
log "No file changes detected." |
|
fi |
|
|
|
exit 0 |