Plex Meta Manager – working code

A few weeks back I was on Reddit and I came across a post about automating several things in Plex using a tool named Plex Meta Manager (PMM). The Reddit thread eventually lead me to seamonkey420’s GitHub page where seamonkey420 laid out a configuration that looked great so I decided to give it a try. Me being lazy and not much of a programmer, I decided I would just use it as is. To say that effort failed miserably would be an understatement. I do want to offer a huge thank you to seamonkey420 though as it got me started on a path to success.

I’ve now spent hours digging through the Plex Meta Manager wiki and just when I thought the Wiki made sense and I tried to apply my newfound knowledge, I broke everything. Rinse and repeat. Via Discord PMM has a support feature and the people that support the tool are amazing. They took a look at my butchered config file and did more than just fix it, they explained line by line what my mistakes were and how to correct them.

Here are a few tips that I learned along the way, and at the end I post my entire config file along with a couple of sample images.

Tip 1: Installing PMM on QNAP Container Station

The QNAP walkthrough on PMM https://metamanager.wiki/en/latest/home/guides/qnap.html is not updated. Conceptually it’s correct, but none of the screenshots match the current version of Container Station. Here’s my updated QNAP walkthrough using QNAP QTS 5.1.1.2491 running on a QNAP TVS-872XT with Container Station version 3.0.5.623:

  1. Open Container Station; click “Images” Step 0
  2. Select “Pull” from the top-right Step 2
  3. Leave Mode set to “Basic Mode”
    For the Registry select “Docker Hub”
    Under the Image section you will be typing in the name and version of the Image you wish to pull. PMM offers three images to choose from: latest, develop and nightly. Choose one of the three and type in the one you wish to use as follows:

    meisnate12/plex-meta-manager:latest
    meisnate12/plex-meta-manager:develop
    meisnate12/plex-meta-manager:nightly


    Then click Pull.Step1

    Note: You can repeat this step for each of the different versions and you’ll end up with this:


  4. After the Pull is complete the Image(s) will now be available for use.
  5. From the Images menu under the Actions Column click the Play button to bring up the “Create Container” option Step 2
  6. Create Container Step 1 Select Image – you’ve already done this so just click Next
  7. Create Container Step 2 Configure Container you can edit the name if you wish. From here on you’ll be working in the Advanced Settings sub-menu. Click on Advanced Settings. Step 4
    • Under Advanced Settings > Commands you’ll find the “Command:” and “Entrypoint:” sections which are set to Default. In general you should not have to edit these. Step 5
    • From the Advanced Settings Page select Environments.
      You don’t have to change anything here, but you may wish to add more Environment Variables. The list of Variables are found on the PMM wiki.
      One use case where I found setting Environments to be helpful is to change the default behavior so that as soon as the Container is started PMM begins to run instead of waiting for the default 5AM run time. Here’s an example of how I added the Environment variable PMM_RUN = true to trigger this behavior:
    • The last Advanced Settings page you will need to get correct is the Storage Tab which now looks like this by default:
      Step7
      QNAP seems to want you to define volumes within Container Station that I suspect live within the Container, but I wanted to use a folder on the QNAP where I had dumped all my config files. To accomplish this, click the Trash Can icon to remove the default Storage Mapping
      • Click Add Volume then choose “Bind Mount Host Path”Step 9
      • Select the Yellow Folder icon10“Select Host Path” will appear as seen below, letting you select the folder you want to use. 11After selecting your folder and choosing Apply the Host path will be filled in as seen in the screenshot below. For the Container path you MUST use /config as seen below Select Apply to finish the Advanced Settings configuration.
  8. Select Next to advance to “Step 3 Summary”
  9. Select Finish
  10. Congratulations you’ve successfully configured PMM on QNAP.

Tip 2: Don’t use FlixPatrol

Up until recently, FlixPatrol could be called via PMM to build some dynamic collections in Plex based on things like “which movies on Disney+ are trending this week.” PMM’s Wiki offers details on how this stuff used to work; however within the last week FlixPatrol has moved many of their API’s behind a paywall requiring a “FlixPatrol Premium” license. FlixPatrol explains these changes in more details here. The end result is that now none of the FlixPatrol PMM features work so don’t attempt to add them into your config.yml file.

Tip 3: Understand the pmm YAML schema to avoid silly mistakes

Typing this seems silly in hindsight, but I did not understand the PMM yaml schema so when I was finding sample config.yml files online I was copy-and-pasting things all over the place in the config.yml file, not grasping that while the - pmm: Name shows up under multiple parts of the config.yml file there is a specific purpose to each - pmm: Name.

In general the config.yml is broken into 3 parts:

  1. metadata_path (used for Collections)
  2. overlay_path (used for Overlays)
  3. Operations (this can be its own separate section of the file or it can be part of the first two)

You will find the - pmm: Name in both the metadata_path and the overlay_path sections but they are NOT ALWAYS interchangeable. For example the - pmm: actor is used under the metadata_path because it is a collection, not an overlay. The - pmm: ribbon is used in the overlay_path section because it is an overlay not a collection. But there are always exceptions, for example - pmm: studio can be both an overlay and a collection.

The best way to avoid this silly error is to lookup the specific - pmm: Name on the PMM Wiki and it will tell you if it belongs in the metadata_path or if it belongs in the overlay_path of the config.yml.

In conclusion: Here’s my config.yml

The end result in Plex looks like this for non-4K material:

The end result in Plex looks like this for 4K material:

I will probably try to tweak the placement for the 4K Audio codec so that it sits just below the 4KUHD black bar,but that experiment will be for another day.

A couple of important points:

  1. All the config files come directly from seamonkey420’s GitHub page so you should pull those first. Here’s that link THANK YOU seamonkey420!!!!!
  2. To use this file you need to change the names of each of the libraries to match your Plex server. For example I have a library named Christmas Films. Remove this entire section if you don’t have a library named Christmas Films or just rename it to match the name in Plex of your film library. Be careful not to mix Film libraries with TV show libraries as this file does different things for TV shows then it does for Movies.
  3. Line 338 is where you begin to change all of the API calls for your specific environment. I host my Plex Server directly on the QNAP and so instead of the IP address of the Plex server you need to know the correct full path to the Plex app. I left a sample of what the format looks like in here but it will be unique to your install of Plex.
  4. For each of the API’s starting on Line 345 (TMDb, Trakt, OMDb, and Mdblist) the PMM Wiki includes very detailed instructions for how to get your own API Keys and Tokens. Here are direct links to these documents:
    • For TMDb click here
    • For Trakt click here
    • For OMDb click here
    • For Mdblist click here
libraries:
  Movies:
    metadata_path:
      - file: config/movies_imdb.yml
      - file: config/movies_tmdb.yml
      - file: config/movies-rotten.yml
      - file: config/movies-trakt.yml
      - file: config/collections.yml
      - pmm: separator_chart
      - pmm: franchise
      - pmm: universe
      - pmm: content_rating_us
      - pmm: resolution
      - pmm: studio
      - pmm: tmdb
    overlay_path:
      - remove_overlays: false # Set this to true to remove all overlays
      - pmm: audio_codec
        template_variables:
          style: standard
          horizontal_align: right
          vertical_align: top
      - pmm: ratings
        template_variables:
          rating1: critic
          rating2: audience
          rating3: user
          rating1_image: imdb
          rating2_image: rt_popcorn
          rating3_image: tmdb
      - file: config/overlays/imdb_top_250.yml
    operations:
      mass_critic_rating_update: imdb
      mass_audience_rating_update: mdb_tomatoesaudience
      mass_user_rating_update: tmdb
  TV Shows: # TV Shows Library
    overlay_path:
      - remove_overlays: false # Set this to true to remove all overlays
      - pmm: ratings
        template_variables:
          rating1: critic
          rating2: audience
          rating3: user
          rating1_image: imdb
          rating2_image: rt_popcorn
          rating3_image: tmdb
      - pmm: ratings
        template_variables:
          builder_level: episode
          rating1: critic
          rating2: audience
          rating1_image: imdb
          rating2_image: tmdb
    metadata_path:
      - file: config/collections.yml
      - pmm: tmdb
      - pmm: network
      - pmm: streaming
      - pmm: studio
      - pmm: separator_chart
    operations:
      mass_critic_rating_update: imdb
      mass_audience_rating_update: mdb_tomatoesaudience
      mass_user_rating_update: tmdb
      mass_episode_critic_rating_update: imdb
      mass_episode_audience_rating_update: tmdb
  4K: # 4K Movie Library
    metadata_path:
      - file: config/movies_imdb.yml
      - file: config/movies_tmdb.yml
      - file: config/movies-rotten.yml
      - file: config/movies-trakt.yml
      - file: config/collections.yml
      - pmm: separator_chart
      - pmm: franchise
      - pmm: universe
      - pmm: content_rating_us
      - pmm: resolution
      - pmm: studio
    overlay_path:
      - remove_overlays: false # Set this to true to remove all overlays
      - file: config/overlays/4K.yml
      - pmm: audio_codec
        template_variables:
          style: standard
          horizontal_align: right
          vertical_align: top
      - pmm: ratings
        template_variables:
          rating1: critic
          rating2: audience
          rating3: user
          rating1_image: imdb
          rating2_image: rt_popcorn
          rating3_image: tmdb
      - file: config/overlays/imdb_top_250.yml
    operations:
      mass_critic_rating_update: imdb
      mass_audience_rating_update: mdb_tomatoesaudience
      mass_user_rating_update: tmdb
  Christmas Films: # Christmas Films Library
    metadata_path:
      - file: config/movies_imdb.yml
      - file: config/movies_tmdb.yml
      - file: config/movies-rotten.yml
      - file: config/movies-trakt.yml
      - file: config/collections.yml
      - pmm: separator_chart
      - pmm: franchise
      - pmm: universe
      - pmm: content_rating_us
      - pmm: resolution
      - pmm: studio
    overlay_path:
      - remove_overlays: false # Set this to true to remove all overlays
      - pmm: audio_codec
        template_variables:
          style: standard
          horizontal_align: right
          vertical_align: top
      - pmm: ratings
        template_variables:
          rating1: critic
          rating2: audience
          rating3: user
          rating1_image: imdb
          rating2_image: rt_popcorn
          rating3_image: tmdb
      - file: config/overlays/imdb_top_250.yml
    operations:
      mass_critic_rating_update: imdb
      mass_audience_rating_update: mdb_tomatoesaudience
      mass_user_rating_update: tmdb
  Classic Films: # Classic Films Library
    metadata_path:
      - file: config/movies_imdb.yml
      - file: config/movies_tmdb.yml
      - file: config/movies-rotten.yml
      - file: config/movies-trakt.yml
      - file: config/collections.yml
      - pmm: separator_chart
      - pmm: franchise
      - pmm: universe
      - pmm: content_rating_us
      - pmm: resolution
      - pmm: studio
    overlay_path:
      - remove_overlays: false # Set this to true to remove all overlays
      - pmm: audio_codec
        template_variables:
          style: standard
          horizontal_align: right
          vertical_align: top
      - pmm: ratings
        template_variables:
          rating1: critic
          rating2: audience
          rating3: user
          rating1_image: imdb
          rating2_image: rt_popcorn
          rating3_image: tmdb
      - file: config/overlays/imdb_top_250.yml
    operations:
      mass_critic_rating_update: imdb
      mass_audience_rating_update: mdb_tomatoesaudience
      mass_user_rating_update: tmdb
  Horror: # Horror Films Library
    metadata_path:
      - file: config/movies_imdb.yml
      - file: config/movies_tmdb.yml
      - file: config/movies-rotten.yml
      - file: config/movies-trakt.yml
      - file: config/collections.yml
      - pmm: separator_chart
      - pmm: franchise
      - pmm: universe
      - pmm: content_rating_us
      - pmm: resolution
      - pmm: studio
    overlay_path:
      - remove_overlays: false # Set this to true to remove all overlays
      - pmm: audio_codec
        template_variables:
          style: standard
          horizontal_align: right
          vertical_align: top
      - pmm: ratings
        template_variables:
          rating1: critic
          rating2: audience
          rating3: user
          rating1_image: imdb
          rating2_image: rt_popcorn
          rating3_image: tmdb
      - file: config/overlays/imdb_top_250.yml
    operations:
      mass_critic_rating_update: imdb
      mass_audience_rating_update: mdb_tomatoesaudience
      mass_user_rating_update: tmdb
  Kids Movies: # Kids Movies Films Library
    metadata_path:
      - file: config/movies_imdb.yml
      - file: config/movies_tmdb.yml
      - file: config/movies-rotten.yml
      - file: config/movies-trakt.yml
      - file: config/collections.yml
      - pmm: separator_chart
      - pmm: franchise
      - pmm: universe
      - pmm: content_rating_us
      - pmm: resolution
      - pmm: studio
    overlay_path:
      - remove_overlays: false # Set this to true to remove all overlays
      - pmm: audio_codec
        template_variables:
          style: standard
          horizontal_align: right
          vertical_align: top
      - pmm: ratings
        template_variables:
          rating1: critic
          rating2: audience
          rating3: user
          rating1_image: imdb
          rating2_image: rt_popcorn
          rating3_image: tmdb
      - file: config/overlays/imdb_top_250.yml
    operations:
      mass_critic_rating_update: imdb
      mass_audience_rating_update: mdb_tomatoesaudience
      mass_user_rating_update: tmdb
  4K TV: # 4K TV Library
    overlay_path:
      - remove_overlays: false # Set this to true to remove all overlays
      - pmm: ratings
        template_variables:
          rating1: critic
          rating2: audience
          rating3: user
          rating1_image: imdb
          rating2_image: rt_popcorn
          rating3_image: tmdb
      - pmm: ratings
        template_variables:
          builder_level: episode
          rating1: critic
          rating2: audience
          rating1_image: imdb
          rating2_image: tmdb
    metadata_path:
      - file: config/collections.yml
      - pmm: tmdb
      - pmm: network
      - pmm: streaming
      - pmm: studio
      - pmm: separator_chart
    operations:
      mass_critic_rating_update: imdb
      mass_audience_rating_update: mdb_tomatoesaudience
      mass_user_rating_update: tmdb
      mass_episode_critic_rating_update: imdb
      mass_episode_audience_rating_update: tmdb
  Cartoons: #Cartoons Library
    overlay_path:
      - remove_overlays: false # Set this to true to remove all overlays
      - pmm: ratings
        template_variables:
          rating1: critic
          rating2: audience
          rating3: user
          rating1_image: imdb
          rating2_image: rt_popcorn
          rating3_image: tmdb
      - pmm: ratings
        template_variables:
          builder_level: episode
          rating1: critic
          rating2: audience
          rating1_image: imdb
          rating2_image: tmdb
    metadata_path:
      - file: config/collections.yml
      - pmm: tmdb
      - pmm: network
      - pmm: streaming
      - pmm: studio
      - pmm: separator_chart
    operations:
      mass_critic_rating_update: imdb
      mass_audience_rating_update: mdb_tomatoesaudience
      mass_user_rating_update: tmdb
      mass_episode_critic_rating_update: imdb
      mass_episode_audience_rating_update: tmdb
playlist_files:
  - pmm: playlist
    template_variables:
      libraries: Movies, 4K, Christmas Films, Classic Films, Horror, Kids Movies
settings:
  cache: true
  cache_expiration: 60
  asset_directory: config/assets
  asset_folders: true
  asset_depth: 0
  create_asset_folders: false
  prioritize_assets: false
  dimensional_asset_rename: false
  download_url_assets: false
  show_missing_season_assets: false
  show_missing_episode_assets: false
  show_asset_not_needed: true
  sync_mode: append
  minimum_items: 1
  default_collection_order:
  delete_below_minimum: true
  delete_not_scheduled: false
  run_again_delay: 2
  missing_only_released: false
  only_filter_missing: false
  show_unmanaged: false
  show_filtered: false
  show_options: false
  show_missing: false
  show_missing_assets: false
  save_report: false
  tvdb_language: eng
  ignore_ids:
  ignore_imdb_ids:
  item_refresh_delay: 0
  playlist_sync_to_user: all
  playlist_report: false
  verify_ssl: true
  custom_repo:
  check_nightly: false
  show_unconfigured: true
  playlist_exclude_users:
# webhooks:                                       # Can be individually specified per library as well
#  error:
#  version:
#  run_start:
#  run_end:
#  changes:
#  delete:
plex:                                           # Can be individually specified per library as well; REQUIRED for the script to run
  url: https://<YOURPLEXSERVERIPADDRESS.QnapRandomStringofNumbers.plex.direct:32400
  token: YOURPLEXSERVERTOKEN
  timeout: 60
  clean_bundles: true
  empty_trash: true
  optimize: false
tmdb:                                           # REQUIRED for the script to run
  apikey: YOURTMDBTOKEN
  language: en
  cache_expiration: 60
  region: US
trakt:
  client_id: YOURTRAKTCLIENTID
  client_secret: YOURTRAKTSECRET
  authorization:
    access_token: YOURTRAKTACCESSTOKEN
    token_type: Bearer
    expires_in: 7889238
    refresh_token: YOURTRAKTREFRESHTOKEN
    scope: public
    created_at: YOURUNIQUEVALUE
omdb:
  apikey: YOURAPIKEY
  cache_expiration: 60
mdblist:
  apikey: YOURAPIKEY
  cache_expiration: 60  
  pin:
  # everything below is autofilled by the script
    access_token: 
    token_type: 
    expires_in: 
    refresh_token: 
    scope: public
    created_at: 

Leave a Reply

Your email address will not be published. Required fields are marked *