|
|
|
|
@ -1,24 +1,19 @@ |
|
|
|
|
#!/bin/bash |
|
|
|
|
|
|
|
|
|
# Ensure logs and locks directories exist |
|
|
|
|
BASE_DIR="/home/shane/foodie_automator" |
|
|
|
|
LOG_DIR="$BASE_DIR/logs" |
|
|
|
|
LOCK_DIR="$BASE_DIR/locks" |
|
|
|
|
mkdir -p "$LOG_DIR" "$LOCK_DIR" || { echo "Error: Failed to create $LOG_DIR or $LOCK_DIR"; exit 1; } |
|
|
|
|
LOG_FILE="$LOG_DIR/manage_scripts.log" |
|
|
|
|
VENV_PYTHON="$BASE_DIR/venv/bin/python" |
|
|
|
|
CHECKSUM_FILE="$BASE_DIR/.file_checksum" |
|
|
|
|
|
|
|
|
|
mkdir -p "$LOG_DIR" "$LOCK_DIR" || { echo "Error: Failed to create directories"; exit 1; } |
|
|
|
|
|
|
|
|
|
# Log function |
|
|
|
|
log() { |
|
|
|
|
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE" |
|
|
|
|
echo "$1" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# Directory to monitor |
|
|
|
|
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" |
|
|
|
|
|
|
|
|
|
# Calculate checksum of files (excluding logs, JSON files, and venv) |
|
|
|
|
calculate_checksum() { |
|
|
|
|
find "$BASE_DIR" -type f \ |
|
|
|
|
-not -path "$BASE_DIR/logs/*" \ |
|
|
|
|
@ -29,7 +24,6 @@ calculate_checksum() { |
|
|
|
|
-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" |
|
|
|
|
@ -39,23 +33,22 @@ check_running() { |
|
|
|
|
log "$script_name is already running (PID: $pid)" |
|
|
|
|
return 0 |
|
|
|
|
else |
|
|
|
|
log "Stale lock file found for $script_name, removing" |
|
|
|
|
log "Stale lock file for $script_name, removing" |
|
|
|
|
rm -f "$lock_file" |
|
|
|
|
fi |
|
|
|
|
fi |
|
|
|
|
return 1 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# Run a script and extract sleep_time |
|
|
|
|
run_script() { |
|
|
|
|
local script="$1" |
|
|
|
|
local script_name="${script%.py}" |
|
|
|
|
local script_log="$BASE_DIR/logs/${script_name}.log" |
|
|
|
|
local script_log="$LOG_DIR/${script_name}.log" |
|
|
|
|
if check_running "$script_name"; then |
|
|
|
|
return 1 |
|
|
|
|
fi |
|
|
|
|
log "Running $script..." |
|
|
|
|
"$VENV_PYTHON" "$script" >> "$script_log" 2>&1 & |
|
|
|
|
"$VENV_PYTHON" "$BASE_DIR/$script" >> "$script_log" 2>&1 & |
|
|
|
|
local pid=$! |
|
|
|
|
echo "$pid" > "$LOCK_DIR/${script_name}.lock" |
|
|
|
|
wait "$pid" |
|
|
|
|
@ -71,11 +64,10 @@ run_script() { |
|
|
|
|
echo "$sleep_time" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# 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 |
|
|
|
|
for script in foodie_automator_*.py foodie_engagement_tweet.py; do |
|
|
|
|
if [ -f "$script" ] && [ "$script" != "foodie_weekly_thread.py" ]; then |
|
|
|
|
local script_name="${script%.py}" |
|
|
|
|
if pkill -TERM -f "$VENV_PYTHON.*$script_name"; then |
|
|
|
|
log "Sent TERM to $script_name" |
|
|
|
|
@ -88,29 +80,9 @@ stop_scripts() { |
|
|
|
|
log "Removed lock file for $script_name" |
|
|
|
|
fi |
|
|
|
|
done |
|
|
|
|
# Mark all running scripts as stopped in system_activity.json |
|
|
|
|
"$VENV_PYTHON" -c " |
|
|
|
|
import json, os |
|
|
|
|
f = '/home/shane/foodie_automator/system_activity.json' |
|
|
|
|
if os.path.exists(f): |
|
|
|
|
with open(f, 'r') as fh: |
|
|
|
|
data = json.load(fh) |
|
|
|
|
changed = False |
|
|
|
|
for entry in data: |
|
|
|
|
if entry.get('status') == 'running': |
|
|
|
|
entry['status'] = 'stopped' |
|
|
|
|
entry['stop_time'] = __import__('datetime').datetime.now(__import__('datetime').timezone.utc).isoformat() |
|
|
|
|
entry['pid'] = None |
|
|
|
|
changed = True |
|
|
|
|
if changed: |
|
|
|
|
with open(f, 'w') as fh: |
|
|
|
|
json.dump(data, fh, indent=2) |
|
|
|
|
" |
|
|
|
|
log "Marked all running scripts as stopped in system_activity.json" |
|
|
|
|
log "Scripts stopped." |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# Update dependencies |
|
|
|
|
update_dependencies() { |
|
|
|
|
log "Updating dependencies..." |
|
|
|
|
cd "$BASE_DIR" || { log "Failed to change to $BASE_DIR"; exit 1; } |
|
|
|
|
@ -119,52 +91,32 @@ update_dependencies() { |
|
|
|
|
log "Created new virtual environment" |
|
|
|
|
fi |
|
|
|
|
source "$BASE_DIR/venv/bin/activate" |
|
|
|
|
# Commenting out dependency installation since packages are already installed and working |
|
|
|
|
# "$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 core dependencies" |
|
|
|
|
# "$VENV_PYTHON" -m pip install requests openai beautifulsoup4 feedparser praw duckduckgo_search selenium Pillow pytesseract webdriver-manager tweepy python-dotenv flickr-api filelock requests-oauthlib psutil |
|
|
|
|
# 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 tweepy python-dotenv flickr-api filelock requests-oauthlib psutil |
|
|
|
|
# fi |
|
|
|
|
log "Dependencies updated." |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# Handle stop command |
|
|
|
|
if [ "$1" == "stop" ]; then |
|
|
|
|
log "Received stop command, stopping all scripts..." |
|
|
|
|
stop_scripts |
|
|
|
|
if pkill -TERM -f "$VENV_PYTHON.*foodie_engagement_generator"; then |
|
|
|
|
log "Sent TERM to foodie_engagement_generator.py" |
|
|
|
|
sleep 2 |
|
|
|
|
pkill -9 -f "$VENV_PYTHON.*foodie_engagement_generator" || true |
|
|
|
|
else |
|
|
|
|
log "No running foodie_engagement_generator.py found" |
|
|
|
|
fi |
|
|
|
|
rm -f "$LOCK_DIR/foodie_engagement_generator.lock" || log "Failed to remove foodie_engagement_generator.lock" |
|
|
|
|
log "Stopped foodie_engagement_generator.py" |
|
|
|
|
if pkill -TERM -f "$VENV_PYTHON.*foodie_weekly_thread"; then |
|
|
|
|
log "Sent TERM to foodie_weekly_thread.py" |
|
|
|
|
for script in foodie_engagement_generator.py foodie_weekly_thread.py; do |
|
|
|
|
local script_name="${script%.py}" |
|
|
|
|
if pkill -TERM -f "$VENV_PYTHON.*$script_name"; then |
|
|
|
|
log "Sent TERM to $script_name" |
|
|
|
|
sleep 2 |
|
|
|
|
pkill -9 -f "$VENV_PYTHON.*foodie_weekly_thread" || true |
|
|
|
|
pkill -9 -f "$VENV_PYTHON.*$script_name" || true |
|
|
|
|
else |
|
|
|
|
log "No running foodie_weekly_thread.py found" |
|
|
|
|
log "No running $script_name found" |
|
|
|
|
fi |
|
|
|
|
rm -f "$LOCK_DIR/foodie_weekly_thread.lock" || log "Failed to remove foodie_weekly_thread.lock" |
|
|
|
|
log "Stopped foodie_weekly_thread.py" |
|
|
|
|
log "All scripts stopped. Reminder: Disable cron jobs to prevent automatic restarts (crontab -e)." |
|
|
|
|
rm -f "$LOCK_DIR/$script_name.lock" |
|
|
|
|
log "Stopped $script_name" |
|
|
|
|
done |
|
|
|
|
log "All scripts stopped. Reminder: Disable cron jobs (crontab -e)." |
|
|
|
|
exit 0 |
|
|
|
|
fi |
|
|
|
|
|
|
|
|
|
# Handle start command |
|
|
|
|
if [ "$1" == "start" ]; then |
|
|
|
|
log "Received start command, starting all scripts..." |
|
|
|
|
cd "$BASE_DIR" || { log "Failed to change to $BASE_DIR"; exit 1; } |
|
|
|
|
source "$BASE_DIR/venv/bin/activate" || { log "Failed to activate virtual environment"; exit 1; } |
|
|
|
|
source "$BASE_DIR/venv/bin/activate" |
|
|
|
|
if [ -f "$BASE_DIR/.env" ]; then |
|
|
|
|
while IFS='=' read -r key value; do |
|
|
|
|
if [[ ! -z "$key" && ! "$key" =~ ^# ]]; then |
|
|
|
|
@ -173,10 +125,10 @@ if [ "$1" == "start" ]; then |
|
|
|
|
done < <(grep -v '^#' "$BASE_DIR/.env") |
|
|
|
|
log ".env variables loaded" |
|
|
|
|
else |
|
|
|
|
log "Error: .env file not found at $BASE_DIR/.env" |
|
|
|
|
log "Error: .env file not found" |
|
|
|
|
exit 1 |
|
|
|
|
fi |
|
|
|
|
for script in foodie_automator_rss.py foodie_automator_reddit.py foodie_automator_google.py; do |
|
|
|
|
for script in foodie_automator_rss.py foodie_automator_reddit.py foodie_automator_google.py foodie_engagement_tweet.py; do |
|
|
|
|
if [ -f "$script" ]; then |
|
|
|
|
sleep_time=$(run_script "$script" | tail -n 1) |
|
|
|
|
if [ -n "$sleep_time" ]; then |
|
|
|
|
@ -185,23 +137,19 @@ if [ "$1" == "start" ]; then |
|
|
|
|
fi |
|
|
|
|
else |
|
|
|
|
log "Script $script not found" |
|
|
|
|
exit 1 |
|
|
|
|
fi |
|
|
|
|
done |
|
|
|
|
if [ -f "foodie_engagement_generator.py" ]; then |
|
|
|
|
if ! check_running "foodie_engagement_generator"; then |
|
|
|
|
log "Running foodie_engagement_generator.py..." |
|
|
|
|
"$VENV_PYTHON" "foodie_engagement_generator.py" >> "$BASE_DIR/logs/foodie_engagement_generator.log" 2>&1 |
|
|
|
|
"$VENV_PYTHON" "foodie_engagement_generator.py" >> "$LOG_DIR/foodie_engagement_generator.log" 2>&1 |
|
|
|
|
log "foodie_engagement_generator.py completed" |
|
|
|
|
fi |
|
|
|
|
else |
|
|
|
|
log "Script foodie_engagement_generator.py not found" |
|
|
|
|
fi |
|
|
|
|
log "All scripts started. Ensure cron jobs are enabled for automatic scheduling (crontab -l)." |
|
|
|
|
log "All scripts started. Ensure cron jobs are enabled (crontab -l)." |
|
|
|
|
exit 0 |
|
|
|
|
fi |
|
|
|
|
|
|
|
|
|
# Main logic |
|
|
|
|
log "Checking for file changes..." |
|
|
|
|
CURRENT_CHECKSUM=$(calculate_checksum) |
|
|
|
|
if [ -f "$CHECKSUM_FILE" ]; then |
|
|
|
|
@ -218,7 +166,7 @@ if [ "$CURRENT_CHECKSUM" != "$PREVIOUS_CHECKSUM" ]; then |
|
|
|
|
echo "$CURRENT_CHECKSUM" > "$CHECKSUM_FILE" |
|
|
|
|
log "Checksum updated." |
|
|
|
|
fi |
|
|
|
|
cd "$BASE_DIR" || { log "Failed to change to $BASE_DIR"; exit 1; } |
|
|
|
|
cd "$BASE_DIR" |
|
|
|
|
source "$BASE_DIR/venv/bin/activate" |
|
|
|
|
if [ -f "$BASE_DIR/.env" ]; then |
|
|
|
|
while IFS='=' read -r key value; do |
|
|
|
|
@ -228,10 +176,10 @@ if [ -f "$BASE_DIR/.env" ]; then |
|
|
|
|
done < <(grep -v '^#' "$BASE_DIR/.env") |
|
|
|
|
log ".env variables loaded" |
|
|
|
|
else |
|
|
|
|
log "Error: .env file not found at $BASE_DIR/.env" |
|
|
|
|
log "Error: .env file not found" |
|
|
|
|
exit 1 |
|
|
|
|
fi |
|
|
|
|
for script in foodie_automator_rss.py foodie_automator_reddit.py foodie_automator_google.py; do |
|
|
|
|
for script in foodie_automator_rss.py foodie_automator_reddit.py foodie_automator_google.py foodie_engagement_tweet.py; do |
|
|
|
|
if [ -f "$script" ]; then |
|
|
|
|
sleep_time=$(run_script "$script" | tail -n 1) |
|
|
|
|
if [ -n "$sleep_time" ]; then |
|
|
|
|
@ -240,7 +188,6 @@ for script in foodie_automator_rss.py foodie_automator_reddit.py foodie_automato |
|
|
|
|
fi |
|
|
|
|
else |
|
|
|
|
log "Script $script not found" |
|
|
|
|
exit 1 |
|
|
|
|
fi |
|
|
|
|
done |
|
|
|
|
log "All scripts processed." |
|
|
|
|
|