PMSCheck.sh 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #!/bin/bash
  2. # Config
  3. RESTART_DELAY=600
  4. UNWATCHED_SECTION="2"
  5. UNWATCHED_SLEEP=60
  6. UNWATCHED_RETRIES=5
  7. MIN_UNWATCHED_COUNT=10
  8. MAX_MEM=$(( 14 * 1024 * 1024 )) # GB in kB
  9. ADMIN_EMAIL="zach@kotlarek.com"
  10. IFS=''
  11. CURL_TIMEOUT=15
  12. CURL_OPTS=(--silent --connect-timeout 5 --max-time $CURL_TIMEOUT)
  13. # Construct URL components from the environment
  14. if [ -z "${PMS_URL}" ]; then
  15. if [ -z "${PMS_HOST}" ]; then
  16. PMS_HOST="localhost"
  17. fi
  18. if [ -z "${PMS_PORT}" ]; then
  19. PMS_PORT=32400
  20. fi
  21. PMS_URL="http://${PMS_HOST}:${PMS_PORT}"
  22. fi
  23. if [ -z "${PMS_TOKEN}" ]; then
  24. echo "No PMS_TOKEN provided" 1>&2
  25. fi
  26. CURL_OPTS+=(-H "X-Plex-Token: ${PMS_TOKEN}")
  27. # Heady allows 0 unwatched
  28. if hostname | grep -qi heady; then
  29. MIN_UNWATCHED_COUNT=0
  30. fi
  31. # Command-line config
  32. LOOP=-1
  33. if [ "${1}" ]; then
  34. LOOP="${1}"
  35. fi
  36. # Run at least once, loop if requested
  37. while [ $LOOP -ne 0 ]; do
  38. # State tracking
  39. FAILED=""
  40. # Ensure the media share is mounted
  41. if [ -z "${FAILED}" ]; then
  42. if ! ~/bin/video/isMediaMounted; then
  43. FAILED="Media share not mounted"
  44. fi
  45. fi
  46. # Ask Plex for the top-level status page
  47. if [ -z "${FAILED}" ]; then
  48. PAGE="`curl ${CURL_OPTS[@]} "${PMS_URL}/"`"
  49. if [ -z "${PAGE}" ]; then
  50. FAILED="HTTP timeout"
  51. else
  52. UPDATE="`echo "${PAGE}" | grep 'updatedAt=' | sed 's%^.*updatedAt="\([0-9]*\)".*$%\1%'`"
  53. if [ -z "${UPDATE}" ]; then
  54. FAILED="Invalid update timestamp on status page"
  55. fi
  56. fi
  57. fi
  58. # Ask Plex for a list of unwatched TV series
  59. UNWATCHED_TIMEOUT=$(( $CURL_TIMEOUT ))
  60. if [ -z "${FAILED}" ]; then
  61. UNWATCHED_URL="${PMS_URL}/library/sections/${UNWATCHED_SECTION}/all?type=2&unwatched=1&sort=titleSort:asc&X-Plex-Container-Start=0&X-Plex-Container-Size=10000"
  62. TRY=1
  63. FAILED="Too few unwatched series"
  64. while [ $TRY -le $UNWATCHED_RETRIES ] && [ -n "${FAILED}" ]; do
  65. TRY=$(( $TRY + 1 ))
  66. PAGE="`curl ${CURL_OPTS[@]} --max-time "${UNWATCHED_TIMEOUT}" "${UNWATCHED_URL}"`"
  67. COUNT="`echo "${PAGE}" | grep '</Directory>' | wc -l`"
  68. if [ $COUNT -ge $MIN_UNWATCHED_COUNT ]; then
  69. FAILED=""
  70. else
  71. sleep $UNWATCHED_SLEEP
  72. FAILED="${FAILED} ${COUNT}"
  73. UNWATCHED_TIMEOUT=$(( $UNWATCHED_TIMEOUT + $CURL_TIMEOUT ))
  74. fi
  75. done
  76. fi
  77. # Check Plex's memory usage
  78. if [ -z "${FAILED}" ]; then
  79. MEM="`ps awx -o vsize,comm | awk '$0 ~ /\/Plex Media Server$/ {print $1}'`"
  80. if [ -z "${MEM}" ]; then
  81. FAILED="Unable to read memory use"
  82. fi
  83. if [ $MEM -gt $MAX_MEM ]; then
  84. FAILED="Memory use too high: ${MEM}/${MAX_MEM} kB"
  85. fi
  86. fi
  87. # If Plex has failed kill it
  88. if [ -n "${FAILED}" ]; then
  89. ERR_MSG="PMS is non-responsive (${FAILED}). Killing..."
  90. echo "${ERR_MSG}" 1>&2
  91. ~/bin/video/pms/killPMS.sh
  92. if [ $LOOP -lt 1 ]; then
  93. exit 1
  94. elif [ -n "${ADMIN_EMAIL}" ]; then
  95. echo -e "Subject: PMS Restart\n\n${ERR_MSG}" | sendmail "${ADMIN_EMAIL}"
  96. fi
  97. # Give plex a breather to get restarted before we check again
  98. sleep "${RESTART_DELAY}"
  99. # Re-index (in the background)
  100. ~/bin/video/pms/optimize.sh &
  101. # If Plex was super slow, optimize it
  102. elif [ $UNWATCHED_TIMEOUT -gt $(( $CURL_TIMEOUT * $(( $UNWATCHED_RETRIES / 2 )) )) ]; then
  103. ERR_MSG="PMS is slow (${UNWATCHED_TIMEOUT}). Optimizing..."
  104. echo "${ERR_MSG}" 1>&2
  105. # Re-index (in the background)
  106. ~/bin/video/pms/optimize.sh &
  107. fi
  108. # Sleep for the next loop or exit
  109. if [ $LOOP -gt 0 ]; then
  110. sleep $LOOP
  111. else
  112. exit 0
  113. fi
  114. done