claude-home/scripts/tdarr/tdarr-cron-check-configurable.sh
Cal Corum ccdd7ee8b4 CLAUDE: Enhance Tdarr system with GPU transcoding optimization and automated maintenance
## Tdarr Plugin Stack Research & Configuration
- Research optimal H.265/HEVC plugin stacks for quality-focused transcoding
- Configure GPU threshold (95%) to prevent self-termination during transcoding
- Add Tdarr exception logic to distinguish transcoding from gaming GPU usage
- Update gaming detection to preserve active transcoding jobs

## Automated System Maintenance
- Add cron job for automatic cleanup of abandoned Tdarr temp directories
- Cleanup runs every 6 hours, preserves active jobs (< 6 hours old)
- Prevents /tmp filesystem bloat from interrupted transcoding jobs
- Safe cleanup only targets Tdarr-specific work directories

## Enhanced Documentation
- Add comprehensive Tdarr automation documentation in scripts/tdarr/README.md
- Document cleanup system and its relationship to main scheduler
- Update CLAUDE.md with Tdarr keyword triggers and context loading
- Add troubleshooting section for both scheduler and cleanup cron jobs

## System Architecture Improvements
- Organize Tdarr scripts under dedicated scripts/tdarr/ directory
- Maintain backwards compatibility with existing cron jobs
- Add gaming-aware scheduling with configurable time windows
- Implement robust GPU usage detection with Tdarr transcoding awareness

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-09 22:06:24 -05:00

142 lines
5.0 KiB
Bash
Executable File

#!/bin/bash
# Configurable Tdarr Gaming Scheduler (Cron Version)
# Uses tdarr-schedule.conf for flexible time-based scheduling
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
CONFIG_FILE="${SCRIPT_DIR}/tdarr-schedule.conf"
# Load configuration
if [[ -f "$CONFIG_FILE" ]]; then
source "$CONFIG_FILE"
else
echo "ERROR: Configuration file not found: $CONFIG_FILE" >&2
exit 1
fi
# Set defaults if not configured
GAMING_PROCESSES=${GAMING_PROCESSES:-("steam" "lutris" "heroic" "gamemode")}
GPU_THRESHOLD=${GPU_THRESHOLD:-15}
CONTAINER_NAME=${CONTAINER_NAME:-"tdarr-node-gpu-unmapped"}
LOG_FILE=${LOG_FILE:-"/tmp/tdarr-scheduler.log"}
CHECK_GAMING_ONLY=${CHECK_GAMING_ONLY:-false}
QUIET_MODE=${QUIET_MODE:-false}
log() {
if [[ "$QUIET_MODE" != "true" ]]; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
fi
}
is_gaming() {
# Check for gaming processes
for process in "${GAMING_PROCESSES[@]}"; do
if pgrep -f "$process" >/dev/null 2>&1; then
return 0 # Gaming detected
fi
done
# Check GPU usage as backup indicator, but exclude Tdarr's own usage
if command -v nvidia-smi >/dev/null 2>&1; then
local gpu_usage=$(nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader,nounits 2>/dev/null || echo "0")
if [[ $gpu_usage -gt $GPU_THRESHOLD ]]; then
# Check if Tdarr is running and likely causing the GPU usage
if is_tdarr_running && podman exec "$CONTAINER_NAME" pgrep -f "ffmpeg" >/dev/null 2>&1; then
log "📹 High GPU usage (${gpu_usage}%) but Tdarr transcoding active - ignoring"
return 1 # Not gaming, just Tdarr working
else
log "🎮 High GPU usage detected: ${gpu_usage}%"
return 0 # Gaming likely happening
fi
fi
fi
return 1 # No gaming
}
is_tdarr_running() {
podman ps --format "{{.Names}}" | grep -q "^${CONTAINER_NAME}$"
}
is_time_allowed() {
# If gaming-only mode, always allow (time restrictions ignored)
if [[ "$CHECK_GAMING_ONLY" == "true" ]]; then
return 0
fi
local current_hour=$(date +%H | sed 's/^0//') # Remove leading zero
local current_day=$(date +%u) # 1=Monday, 7=Sunday
# Check each time block in ALLOWED_TIMES
for time_block in "${ALLOWED_TIMES[@]}"; do
# Parse format: HOUR_START-HOUR_END:DAYS
local hours_part=$(echo "$time_block" | cut -d':' -f1)
local days_part=$(echo "$time_block" | cut -d':' -f2)
local start_hour=$(echo "$hours_part" | cut -d'-' -f1 | sed 's/^0//')
local end_hour=$(echo "$hours_part" | cut -d'-' -f2 | sed 's/^0//')
# Check if current day matches
local day_match=false
if [[ "$days_part" == "daily" ]]; then
day_match=true
else
# Check specific days (e.g., "1-5" or "3,5")
if [[ "$days_part" =~ ^[0-9]-[0-9]$ ]]; then
# Range format (e.g., "1-5")
local start_day=$(echo "$days_part" | cut -d'-' -f1)
local end_day=$(echo "$days_part" | cut -d'-' -f2)
if [[ $current_day -ge $start_day && $current_day -le $end_day ]]; then
day_match=true
fi
else
# Comma-separated format (e.g., "1,3,5")
if [[ ",$days_part," =~ ,$current_day, ]]; then
day_match=true
fi
fi
fi
# Check if current time matches and day matches
if [[ "$day_match" == "true" ]]; then
# Handle overnight periods (e.g., 22-07)
if [[ $start_hour -gt $end_hour ]]; then
# Overnight: 22-07 means 22:00-23:59 OR 00:00-07:59
if [[ $current_hour -ge $start_hour || $current_hour -le $end_hour ]]; then
return 0 # Time allowed
fi
else
# Same day: 09-17 means 09:00-17:59
if [[ $current_hour -ge $start_hour && $current_hour -le $end_hour ]]; then
return 0 # Time allowed
fi
fi
fi
done
return 1 # Time not allowed
}
# Main logic
if is_gaming; then
# Gaming detected - stop Tdarr if running
if is_tdarr_running; then
log "🎮 Gaming detected - Stopping Tdarr Node"
"${SCRIPT_DIR}/stop-tdarr-gpu-podman.sh" >/dev/null 2>&1
fi
else
# No gaming - check if we should start Tdarr
if is_time_allowed; then
if ! is_tdarr_running; then
local current_time=$(date '+%H:%M')
log "🎬 Starting Tdarr Node at ${current_time} (allowed time, no gaming)"
"${SCRIPT_DIR}/start-tdarr-gpu-podman-clean.sh" >/dev/null 2>&1
fi
else
# Not allowed time - stop if running
if is_tdarr_running; then
local current_time=$(date '+%H:%M')
log "⏰ Stopping Tdarr Node at ${current_time} (outside allowed hours)"
"${SCRIPT_DIR}/stop-tdarr-gpu-podman.sh" >/dev/null 2>&1
fi
fi
fi