recentlyUnwatched.sh 3.0 KB

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