recentlyUnwatched.sh 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #!/bin/bash
  2. CURL_OPTS=(--silent --connect-timeout 5 --max-time 30)
  3. NUM_SERIES=18
  4. NUM_EPISODES=4
  5. MAX_RESULTS=100
  6. # Construct URL components from the environment
  7. if [ -z "${PMS_URL}" ]; then
  8. if [ -z "${PMS_HOST}" ]; then
  9. PMS_HOST="localhost"
  10. fi
  11. if [ -z "${PMS_PORT}" ]; then
  12. PMS_PORT=32400
  13. fi
  14. PMS_URL="http://${PMS_HOST}:${PMS_PORT}"
  15. fi
  16. PMS_AUTH=""
  17. if [ -n "${PMS_TOKEN}" ]; then
  18. PMS_AUTH="X-Plex-Token=${PMS_TOKEN}"
  19. else
  20. echo "No PMS_TOKEN provided" 1>&2
  21. fi
  22. # Select a configuration mode
  23. URL1="${PMS_URL}/library/sections/2/onDeck/?${PMS_AUTH}"
  24. URL2_POST="children/allLeaves?unwatched=1&${PMS_AUTH}"
  25. if echo "${1}" | grep -iq Movie; then
  26. URL1="${PMS_URL}/library/sections/1/recentlyAdded/?${PMS_AUTH}"
  27. URL2_POST="?${PMS_AUTH}"
  28. elif echo "${1}" | grep -iq YouTube; then
  29. URL1="${PMS_URL}/library/sections/16/onDeck/?${PMS_AUTH}"
  30. NUM_EPISODES=$(( $NUM_EPISODES * 3 ))
  31. NUM_SERIES=$(( $NUM_SERIES * 2 ))
  32. fi
  33. # Find recent items
  34. ITEMS="`curl ${CURL_OPTS[@]} "${URL1}" | \
  35. grep '<Video ' | \
  36. head -n "${MAX_RESULTS}" | \
  37. sed 's%^.* ratingKey="\([0-9]*\)".*$%\1%'`"
  38. # Resolve the series item
  39. SERIES=""
  40. IFS=$'\n'
  41. for i in $ITEMS; do
  42. ITEM="`curl ${CURL_OPTS[@]} "${PMS_URL}/library/metadata/${i}/?${PMS_AUTH}" | \
  43. grep '<Video ' | \
  44. head -n "${MAX_RESULTS}"`"
  45. if echo "${ITEM}" | grep -q 'type="episode"'; then
  46. KEY="`echo "${ITEM}" | \
  47. sed 's%^.* parentRatingKey="\([0-9]*\)".*$%\1%'`"
  48. elif echo "${ITEM}" | grep -q 'type="movie"'; then
  49. KEY="`echo "${ITEM}" | \
  50. grep -v 'lastViewedAt="' | \
  51. sed 's%^.* ratingKey="\([0-9]*\)".*$%\1%'`"
  52. else
  53. echo "Unknown type: ${ITEM}" 1>&2
  54. exit -1
  55. fi
  56. if [ -n "${KEY}" ]; then
  57. SERIES="${SERIES}${KEY}"$'\n'
  58. fi
  59. done
  60. SERIES_COUNT=0
  61. IFS=$'\n'
  62. for i in $SERIES; do
  63. SERIES_COUNT=$(( $SERIES_COUNT + 1 ))
  64. FILES="`curl ${CURL_OPTS[@]} "${PMS_URL}/library/metadata/${i}/${URL2_POST}" 2>/dev/null | \
  65. grep '<Part ' | \
  66. head -n "${MAX_RESULTS}" | \
  67. sed 's%^.*file="\([^\"]*\)".*$%\1%' | \
  68. sed "s%^.*/media/%%"`"
  69. SEASON_COUNTS=()
  70. IFS=$'\n'
  71. for j in $FILES; do
  72. # Find the season number and increment the count
  73. # I know the metadata has the season number in it, but this is less work
  74. # Account no-season items (i.e. movies) separately
  75. SEASON="`echo "${j}" | sed 's%^.*/Season \([0-9]*\)/.*$%\1%'`"
  76. if ! echo "${SEASON}" | grep -q '^[0-9]*$'; then
  77. SEASON="`echo "${j}" | sed 's%^.*/S\([0-9]*\)E[0-9].*$%\1%'`"
  78. fi
  79. if ! echo "${SEASON}" | grep -q '^[0-9]*$'; then
  80. SEASON=-1
  81. else
  82. SEASON_COUNTS[$SEASON]=$(( ${SEASON_COUNTS[$SEASON]} + 1 ))
  83. fi
  84. # Limit the number of series (or movies)
  85. if [ $SERIES_COUNT -gt $NUM_SERIES ]; then
  86. continue
  87. # Only output NUM_EPISODES files per season
  88. elif [ $SEASON -ge 0 ] && [ ${SEASON_COUNTS[$SEASON]} -gt $NUM_EPISODES ]; then
  89. continue
  90. fi
  91. # Print the name, decoding both hex encoding and XML entities, and fixing SMB mapping
  92. echo "${j}" | \
  93. sed 's/%C3%A9/é/' | \
  94. perl -pe 's/%([0-9a-f]{2})/sprintf("%s", pack("H2",$1))/eig' | \
  95. perl -e 'use XML::Entities; while (<>) { print XML::Entities::decode('all', $_); }'
  96. done
  97. done