Created
January 3, 2026 16:48
-
-
Save yowmamasita/40d18bc524c1a840d4ee4b3435945e3b to your computer and use it in GitHub Desktop.
Plex Embedded Poster Fixer - Replaces ugly embedded posters (e.g., from BTM releases with watermarks) with clean TMDB posters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Plex Embedded Poster Fixer | |
| # Finds movies with embedded posters OR no poster selected, and fixes them with TMDB posters | |
| # | |
| # Usage: | |
| # PLEX_URL="http://localhost:32400" PLEX_TOKEN="your_token" ./fix_embedded_posters.sh | |
| # | |
| # Options: | |
| # PLEX_URL - Your Plex server URL (required) | |
| # PLEX_TOKEN - Your Plex authentication token (required) | |
| # LIBRARY_SECTION - Library section ID to scan (default: 1) | |
| # DRY_RUN - Set to "true" to preview changes without applying (default: false) | |
| set -e | |
| # Validate required environment variables | |
| if [ -z "$PLEX_URL" ]; then | |
| echo "Error: PLEX_URL is required" | |
| echo "Usage: PLEX_URL=\"http://localhost:32400\" PLEX_TOKEN=\"your_token\" $0" | |
| exit 1 | |
| fi | |
| if [ -z "$PLEX_TOKEN" ]; then | |
| echo "Error: PLEX_TOKEN is required" | |
| echo "Usage: PLEX_URL=\"http://localhost:32400\" PLEX_TOKEN=\"your_token\" $0" | |
| exit 1 | |
| fi | |
| LIBRARY_SECTION="${LIBRARY_SECTION:-1}" | |
| DRY_RUN="${DRY_RUN:-false}" | |
| echo "Plex Embedded Poster Fixer" | |
| echo "==========================" | |
| echo "Server: $PLEX_URL" | |
| echo "Library Section: $LIBRARY_SECTION" | |
| echo "Dry Run: $DRY_RUN" | |
| echo "" | |
| echo "Scanning library..." | |
| # Get all movies in the library | |
| movies=$(curl -s "$PLEX_URL/library/sections/$LIBRARY_SECTION/all?X-Plex-Token=$PLEX_TOKEN" | \ | |
| grep -oE 'ratingKey="[0-9]+"' | grep -oE '[0-9]+') | |
| if [ -z "$movies" ]; then | |
| echo "Error: No movies found. Check your PLEX_URL, PLEX_TOKEN, and LIBRARY_SECTION." | |
| exit 1 | |
| fi | |
| total=$(echo "$movies" | wc -l | tr -d ' ') | |
| count=0 | |
| fixed=0 | |
| embedded_count=0 | |
| no_selection_count=0 | |
| for movie_id in $movies; do | |
| count=$((count + 1)) | |
| # Get poster info | |
| poster_info=$(curl -s "$PLEX_URL/library/metadata/$movie_id/posters?X-Plex-Token=$PLEX_TOKEN") | |
| needs_fix=false | |
| reason="" | |
| # Check if embedded poster is selected | |
| if echo "$poster_info" | grep -q 'selected="1".*provider="embedded"'; then | |
| needs_fix=true | |
| reason="embedded" | |
| embedded_count=$((embedded_count + 1)) | |
| # Check if NO poster is selected at all (but has embedded available) | |
| elif ! echo "$poster_info" | grep -q 'selected="1"'; then | |
| if echo "$poster_info" | grep -q 'provider="embedded"'; then | |
| needs_fix=true | |
| reason="no_selection_with_embedded" | |
| no_selection_count=$((no_selection_count + 1)) | |
| fi | |
| fi | |
| if [ "$needs_fix" = true ]; then | |
| # Get movie title | |
| title=$(curl -s "$PLEX_URL/library/metadata/$movie_id?X-Plex-Token=$PLEX_TOKEN" | \ | |
| grep -oE 'title="[^"]*"' | head -1 | sed 's/title="//;s/"$//') | |
| # Get first TMDB poster URL | |
| tmdb_poster=$(echo "$poster_info" | grep -o 'https://image.tmdb.org[^"]*' | head -1) | |
| if [ -n "$tmdb_poster" ]; then | |
| echo "[$count/$total] FIXING ($reason): $movie_id - $title" | |
| if [ "$DRY_RUN" != "true" ]; then | |
| curl -s -X PUT "$PLEX_URL/library/metadata/$movie_id/poster?url=$tmdb_poster&X-Plex-Token=$PLEX_TOKEN" > /dev/null | |
| echo " -> Set to TMDB poster" | |
| else | |
| echo " -> Would set to TMDB poster" | |
| fi | |
| fixed=$((fixed + 1)) | |
| else | |
| echo "[$count/$total] WARNING: $movie_id - $title - No TMDB poster available" | |
| fi | |
| fi | |
| # Progress indicator every 100 items | |
| if [ $((count % 100)) -eq 0 ]; then | |
| echo "Progress: $count/$total scanned..." | |
| fi | |
| done | |
| echo "" | |
| echo "==========================" | |
| echo "Done! Scanned $total movies." | |
| echo "Fixed: $fixed posters" | |
| echo " - Embedded posters: $embedded_count" | |
| echo " - No selection (with embedded): $no_selection_count" | |
| if [ "$DRY_RUN" = "true" ]; then | |
| echo "" | |
| echo "This was a dry run. Run without DRY_RUN=true to apply changes." | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment