[100] add docs

pull/753/head
meisnate12 2 years ago
parent b8ca63ec4f
commit 4aba37884b

@ -0,0 +1,20 @@
# .readthedocs.yml
version: 2
build:
image: latest
sphinx:
configuration: docs/conf.py
formats: all
python:
version: "3.7"
system_packages: true
install:
- requirements: docs/requirements.txt

@ -1 +1 @@
1.15.1-develop99
1.15.1-develop100

@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

@ -0,0 +1,168 @@
.text-left {
text-align: left !important;
padding-left: 15px !important;
}
.text-center {
text-align: center !important;
}
.text-right {
text-align: right !important;
}
.caption {
margin: 15px 0 5px 10px;
}
code {
color: #0ce3ac;
background-color: #030303 !important;
}
td hr, th hr {
visibility: hidden;
margin: 0;
border: 0;
}
hr {
border-top: 3px solid #bcbcbc;
margin-top: 50px;
margin-bottom: 30px;
}
pre code {
background-color: #bcbcbc;
}
a code {
color: #0cafe3;
}
a {
color: #0cafe3;
}
h1, h2, h3, .h1, .h2, .h3 {
margin-top: 50px;
}
h4, h5, h6, .h4, .h5, .h6 {
margin-top: 30px;
}
h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
color: #0ce3ac;
margin-bottom: 20px;
}
th {
color: #0ce3ac;
}
.dropdown-submenu {
position: relative;
}
.dropdown-submenu>.dropdown-menu {
top: 0;
left: 100%;
margin-top: -6px;
margin-left: -1px;
-webkit-border-radius: 0 6px 6px 6px;
-moz-border-radius: 0 6px 6px;
border-radius: 0 6px 6px 6px;
}
.dropdown-submenu:hover>.dropdown-menu {
display: block;
}
.dropdown-submenu>a:after {
display: block;
content: " ";
float: right;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
border-width: 5px 0 5px 5px;
border-left-color: #ccc;
margin-top: 5px;
margin-right: -10px;
}
.dropdown-submenu:hover>a:after {
border-left-color: #fff;
}
.dropdown-submenu.pull-left {
float: none;
}
.dropdown-submenu.pull-left>.dropdown-menu {
left: -100%;
margin-left: 10px;
-webkit-border-radius: 6px 0 6px 6px;
-moz-border-radius: 6px 0 6px 6px;
border-radius: 6px 0 6px 6px;
}
table {
border-collapse: collapse;
}
table thead tr {
background: #111111;
}
table tbody tr:nth-child(even) {
background: #181818;
}
table tbody tr:nth-child(odd) {
background: #1D1D1D;
}
table.clearTable {
margin-top: 5px;
margin-bottom: 5px;
}
table.clearTable td {
padding: 3px 3px 3px 15px;
}
table.clearTable, table.clearTable tbody, table.clearTable tr, table.clearTable td, table.clearTable th {
background-color: rgba(0, 0, 0, 0.0) !important;
}
table.dualTable td, table.dualTable th {
padding-left: 15px !important;
}
details {
margin-bottom: 5px;
}
summary {
padding: 6px 12px 6px 22px;
background: #111111;
position: relative;
cursor: pointer;
}
summary:before {
content: '';
border-width: .4rem;
border-style: solid;
border-color: transparent transparent transparent #fff;
position: absolute;
top: 1.3rem;
left: 1rem;
transform: rotate(0);
transform-origin: .2rem 50%;
transition: .25s transform ease;
}
details[open] > summary:before {
transform: rotate(90deg);
}
details summary::-webkit-details-marker {
display:none;
}
strong {
color: #0ce3ac;
}
td br {
margin-bottom: 15px;
}
td p {
margin-bottom: 0 !important;
}
p {
-moz-hyphens: none !important;
-ms-hyphens: none !important;
-webkit-hyphens: none !important;
hyphens: none !important;
}
.dropdown-menu > li > a:hover, .dropdown-menu > li > a:focus {
background-color: #00a379 !important;
}
.navbar-inverse .navbar-brand:hover, .navbar-inverse .navbar-brand:focus, .navbar-inverse .navbar-nav > li > a:hover, .navbar-inverse .navbar-nav > li > a:focus {
color: #222222 !important;
}

@ -0,0 +1,71 @@
<div id="navbar" class="{{ theme_navbar_class }} navbar-default {% if theme_navbar_fixed_top|tobool -%} navbar-fixed-top{%- endif -%}">
<div class="container">
<div class="navbar-header">
<!-- .btn-navbar is used as the toggle for collapsed navbar content -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="{{ pathto(master_doc) }}">
{%- block sidebarlogo %}
{%- if logo %}<span><img src="{{ pathto('_static/' + logo, 1) }}"></span>{%- endif %}
{%- endblock %}
{% if theme_navbar_title -%}{{ theme_navbar_title|e }}{%- else -%}{{ project|e }}{%- endif -%}
</a>
<span class="navbar-text navbar-version pull-left"><b>{{ version|e }}</b></span>
</div>
<div class="collapse navbar-collapse nav-collapse">
<ul class="nav navbar-nav">
{% if theme_navbar_links %}
{%- for link in theme_navbar_links %}
{% if link[0] == "_menu" %}
<li class="dropdown">
<a role="button" id="{{ link[1] }}Toc" data-toggle="dropdown" data-target="#" href="#" aria-expanded="false">{{ link[1] }} <b class="caret"></b></a>
<ul class="dropdown-menu multi-level" role="menu" aria-labelledby="{{ link[1] }}Toc">
{%- for sublink in link[2] %}
{% if sublink[0] == "_divider" %}
<li class="divider"></li>
{% elif sublink[0] == "_menu" %}
<li class="dropdown-submenu">
<a tabindex="-1" href="#">{{ sublink[1] }}</a>
<ul class="dropdown-menu">
{%- for subsublink in sublink[2] %}
{% if subsublink[0] == "_divider" %}
<li class="divider"></li>
{% else %}
<li><a href="{{ pathto(*subsublink[1:]) }}">{{ subsublink[0] }}</a></li>
{% endif %}
{%- endfor %}
</ul>
</li>
{% else %}
<li><a href="{{ pathto(*sublink[1:]) }}">{{ sublink[0] }}</a></li>
{% endif %}
{%- endfor %}
</ul>
</li>
{% else %}
<li><a href="{{ pathto(*link[1:]) }}">{{ link[0] }}</a></li>
{% endif %}
{%- endfor %}
{% endif %}
{% if theme_navbar_sidebarrel %}
{% block sidebarrel %}
{% include "relations.html" %}
{% endblock %}
{% endif %}
{% block navbarextra %}
{% endblock %}
{% if theme_source_link_position == "nav" %}
<li class="hidden-sm">{% include "sourcelink.html" %}</li>
{% endif %}
</ul>
{% block navbarsearch %}
{% include "navbarsearchbox.html" %}
{% endblock %}
</div>
</div>
</div>

@ -0,0 +1,260 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
import datetime
import sys
from os.path import abspath, dirname
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
import sphinx_bootstrap_theme
path = dirname(abspath(__file__))
sys.path.append(path)
# -- Project information -----------------------------------------------------
project = "Plex Meta Manager Wiki"
author = "Nathan Taggart"
copyright = f"{datetime.datetime.now().year}"
# The full version, including alpha/beta/rc tags
with open("VERSION") as f:
release = f.readline()
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named "sphinx.ext.*") or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.coverage',
'sphinx.ext.viewcode',
'sphinx.ext.napoleon',
'sphinx.ext.todo',
'myst_parser',
'sphinx_inline_tabs'
]
source_suffix = ['.rst', '.md']
myst_heading_anchors = 4
# -- Napoleon Settings -----------------------------------------------------
napoleon_google_docstring = True
napoleon_numpy_docstring = False
napoleon_include_init_with_doc = False
napoleon_include_private_with_doc = False
napoleon_include_special_with_doc = False
napoleon_use_admonition_for_examples = False
napoleon_use_admonition_for_notes = False
napoleon_use_admonition_for_references = False
napoleon_use_ivar = True
napoleon_use_param = True
napoleon_use_rtype = True
napoleon_use_keyword = True
autodoc_member_order = 'bysource'
add_module_names = False
master_doc = 'index'
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
# html_theme = "nature"
html_theme = "bootstrap"
html_theme_path = sphinx_bootstrap_theme.get_html_theme_path()
# (Optional) Logo. Should be small enough to fit the navbar (ideally 24x24).
# Path should be relative to the ``_static`` files directory.
html_logo = "pmm.png"
html_favicon = "pmm.png"
html_copy_source = False
html_show_sourcelink = False
# Theme options are theme-specific and customize the look and feel of a
# theme further.
html_theme_options = {
# Navigation bar title. (Default: ``project`` value)
#'navbar_title': "Demo",
# Tab name for entire site. (Default: "Site")
'navbar_site_name': "Table of Contents",
# A list of tuples containing pages or urls to link to.
# Valid tuples should be in the following forms:
# (name, page) # a link to a page
# (name, "/aa/bb", 1) # a link to an arbitrary relative url
# (name, "http://example.com", True) # arbitrary absolute url
# Note the "1" or "True" value above as the third argument to indicate
# an arbitrary url.
'navbar_links': [
("_menu", "Essentials", [
("Plex Meta Manager", "index"),
("_divider", ),
("_menu", "Installation", [
("Installing Plex Meta Manager", "home/installation"),
("_divider", ),
("Local Walkthrough", "home/guides/local"),
("Docker Walkthrough", "home/guides/docker"),
("unRAID Walkthrough", "home/guides/unraid"),
("Kubernetes Walkthrough", "home/guides/kubernetes"),
]),
("Run Commands & Environment Variables", "home/environmental"),
("_divider", ),
("Configuration File", "config/configuration"),
("Metadata File", "metadata/metadata"),
("_divider", ),
("Scheduling Guide", "home/guides/scheduling"),
("Image Asset Directory Guide", "home/guides/assets"),
("_divider", ),
("Discord Server", "https://discord.gg/NfH6mGFuAB", True),
("Sponsor", "https://github.com/sponsors/meisnate12", True),
("Acknowledgements", "home/acknowledgements"),
]),
("_menu", "Config", [
("Configuration File", "config/configuration"),
("_divider", ),
("_menu", "Libraries/Playlists", [
("Libraries", "config/libraries"),
("Playlists", "config/playlist"),
("Operations", "config/operations"),
]),
("Settings Attributes", "config/settings"),
("_menu", "Services Attributes", [
("Webhooks Attributes", "config/webhooks"),
("Plex Attributes", "config/plex"),
("TMDb Attributes", "config/tmdb"),
("Tautulli Attributes", "config/tautulli"),
("OMDb Attributes", "config/omdb"),
("MdbList Attributes", "config/mdblist"),
("Notifiarr Attributes", "config/notifiarr"),
("AniDB Attributes", "config/anidb"),
("Radarr Attributes", "config/radarr"),
("Sonarr Attributes", "config/sonarr"),
("Trakt Attributes", "config/trakt"),
("MyAnimeList Attributes", "config/myanimelist"),
]),
]),
("_menu", "Metadata", [
("Metadata and Playlist Files", "metadata/metadata"),
("_divider", ),
("Templates", "metadata/templates"),
("Filters", "metadata/filters"),
("Dynamic Collections", "metadata/dynamic"),
("_menu", "Editing Media Metadata", [
("Editing Movie Metadata", "metadata/metadata/movie"),
("Editing TV Metadata", "metadata/metadata/show"),
("Editing Music Metadata", "metadata/metadata/music"),
]),
("_menu", "Metadata Builders", [
("Plex Builders", "metadata/builders/plex"),
("Smart Builders", "metadata/builders/smart"),
("TMDb Builders", "metadata/builders/tmdb"),
("TVDb Builders", "metadata/builders/tvdb"),
("IMDb Builders", "metadata/builders/imdb"),
("Trakt Builders", "metadata/builders/trakt"),
("Tautulli Builders", "metadata/builders/tautulli"),
("MdbList Builders", "metadata/builders/mdblist"),
("Letterboxd Builders", "metadata/builders/letterboxd"),
("ICheckMovies Builders", "metadata/builders/icheckmovies"),
("FlixPatrol Builders", "metadata/builders/flixpatrol"),
("StevenLu Builders", "metadata/builders/stevenlu"),
("AniDB Builders", "metadata/builders/anidb"),
("AniList Builders", "metadata/builders/anilist"),
("MyAnimeList Builders", "metadata/builders/myanimelist"),
]),
("_menu", "Details", [
("Setting Details", "metadata/details/setting"),
("Schedule Details", "metadata/details/schedule"),
("Image Overlay Details", "metadata/details/overlay"),
("Metadata Details", "metadata/details/metadata"),
("Radarr/Sonarr Details", "metadata/details/arr"),
])
]),
("&#10084", "https://github.com/sponsors/meisnate12", True),
],
# Render the next and previous page links in navbar. (Default: true)
'navbar_sidebarrel': False,
# Render the current pages TOC in the navbar. (Default: true)
'navbar_pagenav': False,
# Tab name for the current pages TOC. (Default: "Page")
'navbar_pagenav_name': "Sections",
# Global TOC depth for "site" navbar tab. (Default: 1)
# Switching to -1 shows all levels.
'globaltoc_depth': 2,
# Include hidden TOCs in Site navbar?
#
# Note: If this is "false", you cannot have mixed ``:hidden:`` and
# non-hidden ``toctree`` directives in the same page, or else the build
# will break.
#
# Values: "true" (default) or "false"
'globaltoc_includehidden': "true",
# HTML navbar class (Default: "navbar") to attach to <div> element.
# For black navbar, do "navbar navbar-inverse"
'navbar_class': "navbar navbar-inverse",
# Fix navigation bar to top of page?
# Values: "true" (default) or "false"
'navbar_fixed_top': "true",
# Location of link to source.
# Options are "nav" (default), "footer" or anything else to exclude.
'source_link_position': "nav",
# Bootswatch (http://bootswatch.com/) theme.
#
# Options are nothing (default) or the name of a valid theme
# such as "cosmo" or "sandstone".
#
# The set of valid themes depend on the version of Bootstrap
# that's used (the next config option).
#
# Currently, the supported themes are:
# - Bootstrap 2: https://bootswatch.com/2
# - Bootstrap 3: https://bootswatch.com/3
'bootswatch_theme': "darkly",
# Choose Bootstrap version.
# Values: "3" (default) or "2" (in quotes)
'bootstrap_version': "3",
}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
html_css_files = ["custom.css"]
def setup(app):
app.add_css_file("custom.css")

@ -0,0 +1,19 @@
# AniDB Attributes
Configuring [AniDB](https://anidb.net/) is optional but can allow you to access mature content with AniDB Builders.
**All AniDB Builders still work without this, they will just not have mature content**
A `anidb` mapping is in the root of the config file.
Below is a `anidb` mapping example and the full set of attributes:
```yaml
anidb:
username: ######
password: ######
```
| Attribute | Allowed Values | Required |
|:-----------|:---------------|:--------:|
| `username` | AniDB Username | &#9989; |
| `password` | AniDB Password | &#9989; |

@ -0,0 +1,26 @@
# Configuration File
Plex Meta Manager uses a YAML configuration file; this file contains swettings that deterimine how Plex Meta Manaegr behaves, and the required connection details needed to connect to Plex Media Server, Radarr, Sonarr, and other third-party services via API.
By default, and unless otherwise stated, Plex Meta Manager looks for the configuration file within `/config/config.yml`
A template Configuration File can be found in the [GitHub Repo](https://github.com/meisnate12/Plex-Meta-Manager/blob/master/config/config.yml.template).
This table outlines the third-party services that Plex Meta Manager can make use of. Each service has specific requirements for setup that can be found by clicking the links within the table.
| Attribute | Required |
|:-----------------------------|:---------------------------------------:|
| [`libraries`](libraries) | &#9989; |
| [`playlist_files`](playlist) | &#10060; |
| [`settings`](settings) | &#10060; |
| [`webhooks`](webhooks) | &#10060; |
| [`plex`](plex) | &#9989; <br/>Either here or per library |
| [`tmdb`](tmdb) | &#9989; |
| [`tautulli`](tautulli) | &#10060; |
| [`omdb`](omdb) | &#10060; |
| [`notifiarr`](notifiarr) | &#10060; |
| [`anidb`](anidb) | &#10060; |
| [`radarr`](radarr) | &#10060; |
| [`sonarr`](sonarr) | &#10060; |
| [`trakt`](trakt) | &#10060; |
| [`mal`](myanimelist) | &#10060; |

@ -0,0 +1,173 @@
# Library Attributes & Metadata Paths
## Overview
Within the [Configuration File](configuration), the `libraries:` attribute specifies the Plex libraries that the user wants Plex Meta Manager to act on.
Attributes are used to instruct Plex Meta Manager what actions to take, such as "load the following libraries" or "execute the following Collection Definition files". These attributes can be specified individually per library, or can be inherited from the global value if it has been set. If an attribute is specified at both the library and global level, then the library level attribute will take priority.
## Example
This example is an advanced version of the library mappings which highlights some attributes being set at the global level, and some being set at the library level:
<details>
<summary>Click to Expand</summary>
<br />
In this example, the `"TV Shows On Second Plex"` library has a library-level `plex` configuration, which takes priority over the `plex` configuration set at the global level. <br>
The `"Anime"` library also has a library-level `radarr` configuration, which takes priority over the `radarr` configuration set at the global level.
```yaml
libraries:
Movies:
metadata_path:
- file: config/Movies.yml
- git: meisnate12/MovieCharts
- git: meisnate12/Studios
- git: meisnate12/IMDBGenres
- git: meisnate12/People
operations:
mass_critic_rating_update: tmdb
split_duplicates: true
TV Shows:
metadata_path:
- file: config/TV Shows.yml
- git: meisnate12/ShowCharts
- git: meisnate12/Networks
TV Shows On Second Plex:
library_name: TV Shows
plex:
url: http://192.168.1.98:32400
token: ####################
metadata_path:
- file: config/TV Shows.yml
- git: meisnate12/ShowCharts
- git: meisnate12/Networks
Anime:
metadata_path:
- file: config/Anime.yml
- git: meisnate12/AnimeCharts
radarr:
url: http://192.168.1.45:7878
token: ################################
root_folder_path: S:/Anime
settings:
asset_directory:
config/assets/anime
plex:
url: http://192.168.1.12:32400
token: ####################
radarr:
url: http://192.168.1.12:7878
token: ################################
add: true
root_folder_path: S:/Movies
monitor: true
availability: announced
quality_profile: HD-1080p
tag: pmm
search: false
```
</details>
## Attributes
The available attributes for each library are as follows:
| Attribute | Values | Default | Required |
|:----------------------------------|:--------------------------------------------------------------------------------------|:--------------------------------------:|:-------------------------------:|
| [`library_name`](#library-name) | Library name (required only when trying to use multiple libraries with the same name) | Base Attribute Name | &#10060; |
| [`metadata_path`](#metadata-path) | Location of Metadata YAML files | `/config/<<MAPPING_NAME>>.yml` | &#10060; |
| [`missing_path`](#missing-path) | Location to create the YAML file listing missing items for this library | `/config/<<MAPPING_NAME>>_missing.yml` | &#10060; |
| [`operations`](operations) | Library Operations to run | N/A | &#10060; |
| [`settings`](settings) | Any `setting` attribute that overrides a global value | global | &#10060; |
| [`plex`](plex) | Any `plex` attribute that overrides a global value | global | &#9989; Either here or globally |
| [`radarr`](radarr) | Any `radarr` attribute that overrides a global value | global | &#10060; |
| [`sonarr`](sonarr) | Any `sonarr` attribute that overrides a global value | global | &#10060; |
| [`tautulli`](tautulli) | Any `tautulli` attribute that overrides a global value | global | &#10060; |
## Library Name
Each library that the user wants Plex Meta Manager to interact with must be documented with a library attribute. A library attribute is represented by the mapping name (i.e. `Movies` or `TV Shows`), this must have a unique name that correlates with a library of the same name within the Plex Media Server. In the situation that two servers are being connected to which both have libraries of the same name, the `library_name` attribute can be utilized to specify the real Library Name, whilst the library attribute's mapping name can be made into a placeholder. This is showcased below:
<details>
<summary>Click to Expand</summary>
<br />
```yaml
libraries:
Movies01:
library_name: Movies
Movies02:
library_name: Movies
plex:
url: http://192.168.1.35:32400
token: ####################
TV Shows:
Anime:
plex:
url: http://192.168.1.12:32400
token: ####################
```
* In this example, `"Movies01"`, `"TV Shows"`, and `"Anime"` will all use the global plex server (http://192.168.1.12:32400) which is defined using the global `plex` mapping. `"Movies02"` will use the plex server http://192.168.1.35:32400 which is defined under its `plex` mapping over the global mapping.
</details>
## Metadata Path
### Overview
The `metadata_path` attribute is used to define the metadata (aka YAML) files that will be executed against the parent library.
By default, when `metadata_path` is missing the script will look within the root PMM directory for a metadata file called `<MAPPING_NAME>.yml`. In this example, Plex Meta Manager will look for a file named `TV Shows.yml`.
```yaml
libraries:
TV Shows:
```
### Path Types
In this example, four metadata file path types are defined for the `"TV Shows"` library:
```yaml
TV Shows:
metadata_path:
- file: config/TVShows.yml
- folder: config/TV Shows/
- git: meisnate12/ShowCharts
- url: https://somewhere.com/PopularTV.yml
```
The four path types are outlined as follows:
* `- file:` refers to a metadata file which is located within the system that PMM is being run from.
* `- folder:` refers to a directory containing metadata files which is located within the system that PMM is being run from.
* `- git:` refers to a metadata file which is hosted on GitHub. This file is assumed to be in the [Configs Repo](https://github.com/meisnate12/Plex-Meta-Manager-Configs) unless the user has specified a custom repository with the [`custom-repo` Setting Attribute](settings.md#custom-repo).
* `- url:` refers to a metadata file which is hosted publicly on the internet.
Within the above example, PMM will:
* First, look within the root of the PMM directory (also known as `config/`) for a metadata file named `TVShows.yml`. If this file does not exist, PMM will skip the entry and move to the next one in the list.
* Then, look within the root of the PMM directory (also known as `config/`) for a directory called `TV Shows`, and then load any metadata files within that directory.
* Then, look at the [meisnate12 folder](https://github.com/meisnate12/Plex-Meta-Manager-Configs/tree/master/meisnate12) within the GitHub Configs Repo for a file called `MovieCharts.yml` which it finds [here](https://github.com/meisnate12/Plex-Meta-Manager-Configs/blob/master/meisnate12/MovieCharts.yml).
* Finally, load the metadata file located at `https://somewhere.com/PopularTV.yml`
## Missing Path
The `missing_path` attribute is used to define where to save the "missing items" YAML file. This file is used to store information about media which is missing from the Plex library compared to what is expected from the Metadata file.
If your Metadata file creates a collection with `Movie 1`, `Movie 2` and `Movie 3` but your Plex library only has `Movie 1` and `Movie 3`, then the missing YAML file will be updated to inform the user that `Movie 2` was missing from the library.
The default and recommended path is `/config/<<MAPPING_NAME>>_missing.yml` where `<<MAPPING_NAME>>` is the name of the library attribute, as showcased below:
```yaml
libraries:
Movies:
missing_path: /config/Movies_movies.yml
```
Alternatively, "missing items" YAML files can be placed in their own directory, as below:
```yaml
libraries:
Movies:
missing_path: /config/missing/Movies.yml
```

@ -0,0 +1,21 @@
# MdbList Attributes
Configuring [MdbList](https://mdblist.com/) is optional but can allow you to mass edit metadata.
A `mdblist` mapping is in the root of the config file.
Below is a `mdblist` mapping example and the full set of attributes:
```yaml
mdblist:
apikey: #########################
cache_expiration: 60
```
| Attribute | Allowed Values | Default | Required |
|:-------------------|:--------------------------------------------------------------------------|:-------:|:--------:|
| `apikey` | MdbList API Key | N/A | &#9989; |
| `cache_expiration` | Number of days before each cache mapping expires and has to be re-cached. | 60 | &#10060; |
* The MdbList apikey can be found [here](https://mdblist.com/preferences/).
* The free apikey is limited to 1000 requests per day so if you hit your limit the program should be able to pick up where it left off the next day as long as the `cache` [Setting](settings.md#cache) is enabled

@ -0,0 +1,49 @@
# MyAnimeList Attributes
Configuring [MyAnimeList](https://myanimelist.net/) is optional but is required for MyAnimeList based collections to function.
A `mal` mapping is in the root of the config file.
Below is a `mal` mapping example and the full set of attributes:
```yaml
mal:
client_id: ################################
client_secret: ################################################################
authorization:
access_token:
token_type:
expires_in:
refresh_token:
```
| Attribute | Allowed Values | Required |
|:----------------|:--------------------------------------|:--------:|
| `client_id` | MyAnimeList Application Client ID | &#9989; |
| `client_secret` | MyAnimeList Application Client Secret | &#9989; |
* All other attributes will be filled in by the script.
* To connect to MyAnimeList.net you must create a MyAnimeList application and supply the script the `client id` and `client secret` provided, please do the following:
1. [Click here to create a MyAnimeList API application.](https://myanimelist.net/apiconfig/create)
2. Enter an `App Name` for the application. Ex. `Plex Meta Manager`
3. Select `web` for `App Type`.
4. Enter an `App Description` for the application Ex. `Plex Meta Manager manages metadata and collections`
5. Enter `http://localhost/` for `App Redirect URL`.
6. Enter `https://github.com/meisnate12/Plex-Meta-Manager` for `Homepage URL`.
7. Select `non-commercial` for `Commercial / Non-Commercial`.
8. Enter any name under `Name / Company Name`.
9. Select `hobbyist` for `Purpose of Use`.
10. Agree to the API License and Developer Agreement and hit the `Submit` button
11. You should see `Successfully registered.` followed by a link that says `Return to list` click this link.
12. On this page Click the `Edit` button next to the application you just created.
13. Record the `Client ID` and `Client Secret` found on the application page.
* On the first run, the script will walk the user through the OAuth flow by producing a MyAnimeList URL for the user to follow. After following the URL login to MyAnimeList.net and authorize the application by clicking the `Allow` button which will redirect the user to `http://localhost/`. Copy the entire URL and paste it into the scrip and if the URL is correct then the script will populate the `authorization` sub-attributes to use in subsequent runs.
<h4>OAuth Flow using Docker</h4>
To authenticate MyAnimeList the first time, you need run the container with the `-it` flags in order to walk through the OAuth flow mentioned above. Once you have the MyAnimeList authentication data saved into the YAML, you'll be able to run the container normally.
<h4>OAuth Flow using unRAID Docker</h4>
Directions on how to authenticate MyAnimeList on unRAID can be found on the [unRAID Walkthrough](../home/guides/unraid.md#advanced-installation-authenticating-trakt-or-myanimelist) page.

@ -0,0 +1,25 @@
# Notifiarr Attributes
Configuring [Notifiarr](https://notifiarr.com) is optional but can allow you to send the webhooks straight to notifiarr.
A `notifiarr` mapping is in the root of the config file.
Below is a `notifiarr` mapping example and the full set of attributes:
```yaml
notifiarr:
apikey: ####################################
```
| Attribute | Allowed Values | Required |
|:----------|:------------------|:--------:|
| `apikey` | Notifiarr API Key | &#9989; |
Once you have added the apikey your config.yml you have to add `notifiarr` to any webhook to send that notification to Notifiarr.
```yaml
webhooks:
error: notifiarr
run_start: notifiarr
run_end: notifiarr
collection_changes: notifiarr
```

@ -0,0 +1,21 @@
# OMDb Attributes
Configuring [OMDb](https://www.omdbapi.com/) is optional but can allow you to mass edit metadata using IMDb.
A `omdb` mapping is in the root of the config file.
Below is a `omdb` mapping example and the full set of attributes:
```yaml
omdb:
apikey: ########
cache_expiration: 60
```
| Attribute | Allowed Values | Default | Required |
|:-------------------|:---------------------------------------------------------------------------|:-------:|:--------:|
| `apikey` | OMDb API Key | N/A | &#9989; |
| `cache_expiration` | Number of days before each cache mapping expires and has to be re-cached. | 60 | &#10060; |
* The OMDb apikey can be generated [here](http://www.omdbapi.com/apikey.aspx).
* The free apikey is limited to 1000 requests per day so if you hit your limit the program should be able to pick up where it left off the next day as long as the `cache` [Setting](settings.md#cache) is enabled

@ -0,0 +1,97 @@
# Operations
There are a variety of Library Operations that can be utilized in a library.
Within each library, operations can be defined by using the `operations` attribute, as demonstrated below.
```yaml
libraries:
Movies:
metadata_path:
- git: meisnate12/MovieCharts
operations:
mass_critic_rating_update: tmdb
split_duplicates: true
```
The available attributes for the operations attribute are as follows
| Attribute | Description |
|:--------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `assets_for_all` | Search in assets for images for every item in your library.<br>**Values:** `true` or `false` |
| `delete_collections_with_less` | Deletes every collection with less than the given number of items.<br>**Values:** number greater then 0 |
| `delete_unmanaged_collections` | Deletes every unmanaged collection<br>**Values:** `true` or `false` |
| `mass_genre_update` | Updates every item's genres in the library to the chosen site's genres<br>**Values:** <table class="clearTable"><tr><td>`tmdb`</td><td>Use TMDb for Genres</td></tr><tr><td>`tvdb`</td><td>Use TVDb for Genres</td></tr><tr><td>`omdb`</td><td>Use IMDb through OMDb for Genres</td></tr></table> |
| `mass_content_rating_update` | Updates every item's content rating in the library to the chosen site's genres<br>**Values:** <table class="clearTable"><tr><td>`mdb`</td><td>Use MdbList for Content Ratings</td></tr><tr><td>`mdb_commonsense`</td><td>Use Commonsense Rating through MDbList for Content Ratings</td></tr><tr><td>`omdb`</td><td>Use IMDb through OMDb for Content Ratings</td></tr></table> |
| `mass_audience_rating_update`/<br>`mass_critic_rating_update` | Updates every item's audience/critic rating in the library to the chosen site's rating<br>**Values:** <table class="clearTable"><tr><td>`tmdb`</td><td>Use TMDb Rating</td></tr><tr><td>`omdb`</td><td>Use IMDbRating through OMDb</td></tr><tr><td>`mdb`</td><td>Use MdbList Score</td></tr><tr><td>`mdb_imdb`</td><td>Use IMDb Rating through MDbList</td></tr><tr><td>`mdb_metacritic`</td><td>Use Metacritic Rating through MDbList</td></tr><tr><td>`mdb_metacriticuser`</td><td>Use Metacritic User Rating through MDbList</td></tr><tr><td>`mdb_trakt`</td><td>Use Trakt Rating through MDbList</td></tr><tr><td>`mdb_tomatoes`</td><td>Use Rotten Tomatoes Rating through MDbList</td></tr><tr><td>`mdb_tomatoesaudience`</td><td>Use Rotten Tomatoes Audience Rating through MDbList</td></tr><tr><td>`mdb_tmdb`</td><td>Use TMDb Rating through MDbList</td></tr><tr><td>`mdb_letterboxd`</td><td>Use Letterboxd Rating through MDbList</td></tr></table> |
| `mass_trakt_rating_update` | Updates every movie/show's user rating in the library to match your custom rating on Trakt if there is one<br>**Values:** `true` or `false` |
| `mass_collection_mode` | Updates every Collection in your library to the specified Collection Mode<br>**Values:** `default`: Library default<br>`hide`: Hide Collection<br>`hide_items`: Hide Items in this Collection<br>`show_items`: Show this Collection and its Items<table class="clearTable"><tr><td>`default`</td><td>Library default</td></tr><tr><td>`hide`</td><td>Hide Collection</td></tr><tr><td>`hide_items`</td><td>Hide Items in this Collection</td></tr><tr><td>`show_items`</td><td>Show this Collection and its Items</td></tr></table> |
| `update_blank_track_titles ` | Search though every track in a music library and replace any blank track titles with the tracks sort title<br>**Values:** `true` or `false` |
| `split_duplicates` | Splits all duplicate movies/shows found in this library<br>**Values:** `true` or `false` |
| `radarr_add_all` | Adds every item in the library to Radarr. The existing paths in plex will be used as the root folder of each item, if the paths in Plex are not the same as your Radarr paths you can use the `plex_path` and `radarr_path` [Radarr](radarr) details to convert the paths.<br>**Values:** `true` or `false` |
| `radarr_remove_by_tag` | Removes every item from Radarr with the Tags given<br>**Values:** List or comma separated string of tags |
| `sonarr_add_all` | Adds every item in the library to Sonarr. The existing paths in plex will be used as the root folder of each item, if the paths in Plex are not the same as your Sonarr paths you can use the `plex_path` and `sonarr_path` [Sonarr](sonarr) details to convert the paths.<br>**Values:** `true` or `false` |
| `sonarr_remove_by_tag` | Removes every item from Sonarr with the Tags given<br>**Values:** List or comma separated string of tags |
| `genre_mapper` | Allows genres to be changed to other genres or be removed from every item in your library.<br>**Values:** [see below for usage](#genre-mapper) |
| `metadata_backup` | Creates/Maintains a PMM [Metadata File](../metadata/metadata) with a full `metadata` mapping based on the library's items locked attributes.<br>**Values:** [see below for usage](#metadata-backup) |
## Genre Mapper
You can use the `genre_mapper` operation to map genres in your library.
Each attribute under `genre_mapper` is a separate mapping and has two parts.
* The key (`Action` in the example below) is what the genres will end up as.
* The value(`Action/Adventure, Action & Adventure` in the example below) is what genres you want mapped to the key.
So this example will change go through every item in your library and change the genre `Action/Adventure` or `Action & Adventure` to `Action` and `Romantic Comedy` to `Comedy`.
```yaml
library:
Movies:
operations:
genre_mapper:
Action: Action/Adventure, Action & Adventure
Comedy: Romantic Comedy
```
you can also use a list:
```yaml
library:
Movies:
operations:
genre_mapper:
Action:
- Action/Adventure
- Action & Adventure
Comedy: Romantic Comedy
```
To just Remove a Genre without replacing it just set the Genre to nothing like this.
```yaml
library:
Movies:
operations:
genre_mapper:
Action: Action/Adventure, Action & Adventure
Romantic Comedy:
```
This example will change go through every item in your library and change the genre `Action/Adventure` or `Action & Adventure` to `Action` and remove every instance of the Genre `Romantic Comedy`.
## Metadata Backup
Creates/Maintains a Plex Meta Manager [Metadata File](../metadata/metadata) with a full `metadata` mapping based on the library's items locked attributes.
If you point to an existing Metadata File then PMM will Sync the changes to the file, so you won't lose non plex changes in the file.
There are a few different options to determine how the `metadata_backup` works.
| Attribute | Description |
|:--------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `path` | Path to where the metadata will be saved/maintained<br>**Default:** <<library_name>>_Metadata_Backup.yml in your config folder<br>**Values:** Path to Metadata File |
| `exclude` | Exclude all listed attributes from being saved in the metadata file<br>**Values:** Comma-separated string or list of attributes |
| `sync_tags` | All Tag Attributes will have the `.sync` option and blank attribute will be added to sync to as well<br>**Default:** `false`<br>**Values:** `true` or `false` |
| `add_blank_entries` | Will add a line for entries that have no metadata changes<br>**Default:** `true`<br>**Values:** `true` or `false` |

@ -0,0 +1,32 @@
# Playlist Files
## Overview
As playlists are not tied to one specific library and can combine media from multiple libraries, they require their own special [Playlist File](../metadata/metadata) to work.
You can define Playlist Files by using `playlist_files` mapper. They can either be on the local system, online at an url, or directly from the [Plex Meta Manager Configs](https://github.com/meisnate12/Plex-Meta-Manager-Configs) repository.
## Path Types
In this example, four `playlist_files`attribute path types are defined:
```yaml
playlist_files:
- file: config/playlists.yml
- folder: config/Playlists/
- git: meisnate12/Playlists
- url: https://somewhere.com/Playlists.yml
```
The four path types are outlined as follows:
* `- file:` refers to a playlist file which is located within the system that PMM is being run from.
* `- folder:` refers to a directory containing playlist files which is located within the system that PMM is being run from.
* `- git:` refers to a playlist file which is hosted on GitHub. This file is assumed to be in the [Configs Repo](https://github.com/meisnate12/Plex-Meta-Manager-Configs) unless the user has specified a custom repository with the
* `- url:` refers to a playlist file which is hosted publicly on the internet.
Within the above example, PMM will:
* First, look within the root of the PMM directory (also known as `config/`) for a playlist file named `Playlists.yml`. If this file does not exist, PMM will skip the entry and move to the next one in the list.
* Then, look within the root of the PMM directory (also known as `config/`) for a directory called `Playlists`, and then load any playlist files within that directory.
* Then, look at the [meisnate12 folder](https://github.com/meisnate12/Plex-Meta-Manager-Configs/tree/master/meisnate12) within the GitHub Configs Repo for a file called `MovieCharts.yml` which it finds [here](https://github.com/meisnate12/Plex-Meta-Manager-Configs/blob/master/meisnate12/Playlists.yml).
* Finally, load the playlist file located at `https://somewhere.com/Playlists.yml`

@ -0,0 +1,29 @@
# Plex Attributes
Configuring [Plex](https://www.plex.tv/) is required in order to connect to your libraries.
A `plex` mapping can be either in the root of the config file as global mapping for all libraries, or you can specify the `plex` mapping individually per library.
Below is a `plex` mapping example and the full set of attributes:
```yaml
plex:
url: http://192.168.1.12:32400
token: ####################
timeout: 60
clean_bundles: true
empty_trash: true
optimize: false
```
| Attribute | Allowed Values | Default | Required |
|:----------------|:-----------------------------------------------------------------------|:-------:|:--------:|
| `url` | Plex Server URL<br><strong>Example:</strong> http://192.168.1.12:32400 | N/A | &#9989; |
| `token` | Plex Server Authentication Token | N/A | &#9989; |
| `timeout` | Plex Server Timeout | 60 | &#10060; |
| `clean_bundles` | Runs Clean Bundles on the Server after all Metadata Files are run | false | &#10060; |
| `empty_trash` | Runs Empty Trash on the Server after all Metadata Files are run | false | &#10060; |
| `optimize` | Runs Optimize on the Server after all Metadata Files are run | false | &#10060; |
* This script can be run on a remote Plex server, but be sure that the `url` provided is publicly addressable, and it's recommended to use `HTTPS`.
* If you need help finding your Plex authentication token, please see Plex's [support article](https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/).

@ -0,0 +1,46 @@
# Radarr Attributes
Configuring [Radarr](https://radarr.video/) is optional but will allow you to send movies to a Radarr instance when they're found missing while updating a library's collections.
Radarr V2 may work, but it is not supported please upgrade to V3 if you can.
A `radarr` mapping can be either in the root of the config file as global mapping for all libraries, or you can specify the `radarr` mapping individually per library.
Below is a `radarr` mapping example and the full set of attributes:
```yaml
radarr:
url: http://192.168.1.12:32788
token: ################################
add: true
root_folder_path: S:/Movies
monitor: true
availability: announced
quality_profile: HD-1080p
tag: pmm
search: false
radarr_path: /media
plex_path: /share/CACHEDEV1_DATA/Multimedia
```
| Attribute | Allowed Values | Default | Required |
|:-------------------|:-----------------------------------------------------------------------------------------------|:-----------:|:--------:|
| `url` | Radarr URL (Including URL Base if set)<br>**Example:** http://192.168.1.12:32788 | N/A | &#9989; |
| `token` | Radarr API Token | N/A | &#9989; |
| `add` | Add missing movies found to Radarr<br>**boolean:** true or false | false | &#10060; |
| `add_existing` | Add movie existing in this collection to Radarr<br>**boolean:** true or false | false | &#10060; |
| `root_folder_path` | Radarr Root Folder Path To Use | N/A | &#9989; |
| `monitor` | Monitor the added movie | true | &#10060; |
| `availability` | Minimum Availability of the Movie<br>**Options:** `announced`, `cinemas`, `released`, `db` | `announced` | &#9989; |
| `quality_profile` | Quality Profile To Use | N/A | &#10060; |
| `tag` | Add this list or comma-separated string of tags to every movie added to Radarr | ` ` | &#10060; |
| `search` | Search when adding missing movies to Radarr<br>**boolean:** true or false | false | &#10060; |
| `plex_path` | When using `add_existing` or `radarr_add_all` Convert this part of the path to `radarr_path` | ` ` | &#10060; |
| `radarr_path` | When using `add_existing` or `radarr_add_all` Convert the `plex_path` part of the path to this | ` ` | &#10060; |
* The `token` can be found by going to `Radarr > Settings > General > Security > API Key`
* The `quality_profile` must be the exact name of the desired quality profile, including all spaces and capitalization.
* You can set most attributes per collection by using the [Radarr Details](../metadata/details/arr.md#radarr-details)
![Radarr Details](radarr.png)

@ -0,0 +1,542 @@
# Settings
## Overview
The `settings:` attribute and subsequent settings can be used to command various aspects of the functionality of Plex Meta Manager.
Examples of these settings include the ability to:
* Cache each Plex GUID and IDs to increase performance
* Create asset folders for collections so that custom posters can be stored for upload.
* Use a custom repository as the base for all `git` Metadata files.
The settings attribute and attributes can be specified individually per library, or can be inherited from the global value if it has been set. If an attribute is specified at both the library and global level, then the library level attribute will take priority.
There are some attributes which can be specified at the collection level using [Setting Details](../metadata/details/setting).
Attributes set at the collection level will take priority over any library or global-level attribute.
## Attributes
The available setting attributes which can be set at each level are outlined below:
| Attribute | Global Level | Library Level | Collection/Playlist Level |
|:--------------------------------------------------------------|:------------:|:-------------:|:-------------------------:|
| [`cache`](#cache) | &#9989; | &#10060; | &#10060; |
| [`cache_expiration`](#cache-expiration) | &#9989; | &#10060; | &#10060; |
| [`asset_directory`](#image-asset-directory) | &#9989; | &#9989; | &#10060; |
| [`asset_folders`](#image-asset-folders) | &#9989; | &#9989; | &#10060; |
| [`asset_depth`](#asset-depth) | &#9989; | &#9989; | &#10060; |
| [`create_asset_folders`](#create-asset-folders) | &#9989; | &#9989; | &#10060; |
| [`dimensional_asset_rename`](#dimensional-asset-rename) | &#9989; | &#9989; | &#10060; |
| [`download_url_assets`](#download-url-assets) | &#9989; | &#9989; | &#10060; |
| [`show_missing_season_assets`](#show-missing-season-assets) | &#9989; | &#9989; | &#10060; |
| [`show_missing_episode_assets`](#show-missing-episode-assets) | &#9989; | &#9989; | &#10060; |
| [`show_asset_not_needed`](#show-asset-not-needed) | &#9989; | &#9989; | &#10060; |
| [`sync_mode`](#sync-mode) | &#9989; | &#9989; | &#9989; |
| [`default_collection_order`](#default-collection-order) | &#9989; | &#9989; | &#10060; |
| [`minimum_items`](#minimum-items) | &#9989; | &#9989; | &#9989; |
| [`delete_below_minimum`](#delete-below-minimum) | &#9989; | &#9989; | &#9989; |
| [`delete_not_scheduled`d](#delete-not-scheduled) | &#9989; | &#9989; | &#9989; |
| [`run_again_delay`](#run-again-delay) | &#9989; | &#10060; | &#10060; |
| [`missing_only_released`](#missing-only-released) | &#9989; | &#9989; | &#9989; |
| [`show_unmanaged`](#show-unmanaged-collections) | &#9989; | &#9989; | &#10060; |
| [`show_filtered`](#show-filtered) | &#9989; | &#9989; | &#9989; |
| [`show_options`](#show-options) | &#9989; | &#9989; | &#9989; |
| [`show_missing`](#show-missing) | &#9989; | &#9989; | &#9989; |
| [`only_filter_missing`](#only-filter-missing) | &#9989; | &#9989; | &#9989; |
| [`show_missing_assets`](#show-missing-assets) | &#9989; | &#9989; | &#9989; |
| [`save_missing`](#save-missing) | &#9989; | &#9989; | &#9989; |
| [`tvdb_language`](#tvdb-language) | &#9989; | &#10060; | &#10060; |
| [`ignore_ids`](#ignore-ids) | &#9989; | &#9989; | &#9989; |
| [`ignore_imdb_ids`](#ignore-imdb-ids) | &#9989; | &#9989; | &#9989; |
| [`item_refresh_delay`](#item-refresh-delay) | &#9989; | &#9989; | &#9989; |
| [`playlist_sync_to_users`](#playlist-sync-to-users) | &#9989; | &#10060; | &#9989; |
| [`custom_repo`](#custom-repo) | &#9989; | &#10060; | &#10060; |
| [`verify_ssl`](#verify-ssl) | &#9989; | &#10060; | &#10060; |
## Cache
Cache the Plex GUID and associated IDs for each library item for faster subsequent processing. The cache file is created in the same directory as the configuration file.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>true</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>true</code> or <code>false</code>
</td>
</tr>
</table>
## Cache Expiration
Set the number of days before each cache mapping expires and has to be re-cached.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>60</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td>any integer</td>
</tr>
</table>
## Image Asset Directory
Specify the directory where assets are located.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>[Directory containing YAML config]/assets</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td>any directory</td>
</tr>
</table>
## Image Asset Folders
Search the `asset_directory` for a dedicated folder. Set to true if each poster is within its own directory.<br>
i.e. `assets/Star Wars/poster.png` instead of `assets/Star Wars.png`
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>true</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>true</code> or <code>false</code>
</td>
</tr>
</table>
## Asset Depth
Specify how many folder levels to scan for an item within the asset directory<br>
* `asset_folders` must be set to `true` for this to take effect.
* increasing the amount of levels to scan will reduce performance
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>0</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td>any integer</td>
</tr>
</table>
## Create Asset Folders
Whilst searching for assets, if an asset folder cannot be found within the `asset_directory`, create one. This only applies to library items utilized in a Metadata/Playlist file (i.e. Star Wars Collection)
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>false</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>true</code> or <code>false</code>
</td>
</tr>
</table>
## Dimensional Asset Rename
Whilst searching for assets, scan the folders within the `asset_directory` and if an asset poster (i.e. `/ASSET_NAME/poster.ext`) was not found, rename the first image found that has a height greater than or equal to its width to `poster.ext`. If an asset background (i.e. `/ASSET_NAME/background.ext`), rename the first image found that has a width greater than its height to `background.ext`.
* `asset_folders` must be set to `true` for this to take effect.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>false</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>true</code> or <code>false</code>
</td>
</tr>
</table>
## Download URL Assets
Whilst searching for assets, download images set within Metadata/Playlist files( i.e. images set by `url_poster` or `url_background`) into the asset folder if none are already present.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>false</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>true</code> or <code>false</code>
</td>
</tr>
</table>
## Show Missing Season Assets
Whilst searching for assets, when scanning for assets for a TV Show, if Season posters are found (i.e. `/ASSET_NAME/Season##.ext`), notify the user of any seasons which do not have an asset image.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>false</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>true</code> or <code>false</code>
</td>
</tr>
</table>
## Show Missing Episode Assets
Whilst searching for assets, when scanning for assets for a TV Show, if an Episode Title Card is found (i.e. `/ASSET_NAME/S##E##.ext`), notify the user of any episodes which do not have an asset image.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>false</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>true</code> or <code>false</code>
</td>
</tr>
</table>
## Show Asset Not Needed
Whilst searching for assets, show or hide the `update not needed` messages.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>false</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>true</code> or <code>false</code>
</td>
</tr>
</table>
## Sync Mode
Set the default `sync_mode` for collections.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>append</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>append</code> or <code>sync</code>
</td>
</tr>
</table>
## Default Collection Order
Set the default `collection_order` for every collection run by PMM.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>None</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>release</code>: Order Collection by Release Dates<br>
<code>alpha</code>: Order Collection Alphabetically<br>
<code>custom</code>: Order Collection Via the Builder Order<br>
Any <code>plex_search</code> sort option<sup>1</sup><br>
</td>
</tr>
</table>
<sup>1</sup> `plex_search` sort options can be found [here](../metadata/builders/plex.md#sort-options)
## Minimum Items
Set the minimum number of items that must be found in order to update a collection/playlist.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>1</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td>any integer</td>
</tr>
</table>
## Delete Below Minimum
When a collection is run, delete the collection if it is below the minimum number specified by `minimum_items`.
* Relies on `minimum_items` being set to the desired integer.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>false</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>true</code> or <code>false</code>
</td>
</tr>
</table>
## Delete Not Scheduled
If a collection is skipped due to it not being scheduled, delete the collection.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>false</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>true</code> or <code>false</code>
</td>
</tr>
</table>
## Run Again Delay
Set the number of minutes to delay running `run_again` collections after daily run is finished.
* A collection is a `run_again` collection if it has the `run_again` [Setting Detail](../metadata/details/setting) attribute set to true.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>1</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td>any integer</td>
</tr>
</table>
## Missing Only Released
Whilst running a collection, all unreleased missing items will be filtered out from the [missing YAML file](../metadata/details/setting)
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>false</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>true</code> or <code>false</code>
</td>
</tr>
</table>
## Show Unmanaged Collections
List all collections not managed by Plex Meta Manager at the end of each run.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>true</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>true</code> or <code>false</code>
</td>
</tr>
</table>
## Show Filtered
List all items which have been filtered out of a collection (i.e. if it doesn't meet the filter criteria)
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>false</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>true</code> or <code>false</code>
</td>
</tr>
</table>
## Show Options
While `show_options` is true the available options for an attribute when using `plex_search`, `smart_filter` or `filters` will be shown.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>false</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>true</code> or <code>false</code>
</td>
</tr>
</table>
## Show Missing
While `show_missing` is true items missing from collections will be displayed.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>true</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>true</code> or <code>false</code>
</td>
</tr>
</table>
## Only Filter Missing
Only items missing from a collection will be filtered
* this can be used to filter which missing media items get sent to Sonarr/Radarr
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>false</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>true</code> or <code>false</code>
</td>
</tr>
</table>
## Show Missing Assets
Display missing asset warnings
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>true</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>true</code> or <code>false</code>
</td>
</tr>
</table>
## Save Missing
Save missing items from collections to a YAML file in the same directory as your Metadata file.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>true</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>true</code> or <code>false</code>
</td>
</tr>
</table>
## TVDb Language
Specify the language to query TVDb in.
* If no language is specified or the specified language is not found then the original language is used.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>None</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td>Any ISO 639-2 Language Code<sup>1</sup></td>
</tr>
</table>
<sup>1</sup> Language Codes can be found [here](https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes)
## Ignore IDs
Set a list or comma-separated string of TMDb/TVDb IDs to ignore in all collections.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>None</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td>List or comma-separated string of TMDb/TVDb IDs</td>
</tr>
</table>
## Ignore IMDb IDs
Set alist or comma-separated string of IMDb IDs to ignore in all collections.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>None</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td>List or comma-separated string of IMDb IDs</td>
</tr>
</table>
## Item Refresh Delay
Specify the amount of time to wait between each `item_refresh` of every movie/show in a collection/playlist.
* Useful if your Plex Media Server is having issues with high request levels.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>0</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td>any integer</td>
</tr>
</table>
## Playlist Sync to Users
Set the default playlist `sync_to_users`. To Sync a playlist to only yourself leave `playlist_sync_to_users` blank.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>all</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>all</code>, list of users, or comma-separated string of users</td>
</tr>
</table>
## Custom Repo
Specify where the `repo` attribute's base is when defining `metadata_paths` and `playlist_files`.
* Ensure you are using the raw GitHub link (i.e. https://github.com/meisnate12/Plex-Meta-Manager-Configs/tree/master/meisnate12 )
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>None</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td>link to base repository</td>
</tr>
</table>
## Verify SSL
Turn SSl Verification on or off.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>true</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>true</code> or <code>false</code>
</td>
</tr>
</table>

@ -0,0 +1,52 @@
# Sonarr Attributes
Configuring [Sonarr](https://sonarr.tv/) is optional but will allow you to send shows to a Sonarr instance when they're found missing while updating a library's collections.
Sonarr V2 may work, but it is not supported please upgrade to V3 if you can.
A `sonarr` mapping can be either in the root of the config file as global mapping for all libraries, or you can specify the `sonarr` mapping individually per library.
Below is a `sonarr` mapping example and the full set of attributes:
```YAML
sonarr:
url: http://192.168.1.12:32789
token: ################################
add: true
root_folder_path: S:/Shows
monitor: all
quality_profile: HD-1080p
language_profile: English
series_type: standard
season_folder: true
tag: pmm
search: false
cutoff_search: false
sonarr_path: /media
plex_path: /share/CACHEDEV1_DATA/Multimedia
```
| Attribute | Allowed Values | Default | Required |
|:-------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------:|:--------:|
| `url` | Sonarr URL (Including URL Base if set)<br>**Example:** http://192.168.1.12:32788 | N/A | &#9989; |
| `token` | Sonarr API Token | N/A | &#9989; |
| `add` | Add missing shows found to Sonarr<br>**boolean:** true or false | false | &#10060; |
| `add_existing` | Add shows existing in this collection to Sonarr<br>**boolean:** true or false | false | &#10060; |
| `root_folder_path` | Sonarr Root Folder Path To Use | N/A | &#9989; |
| `monitor` | `all`: Monitor all episodes except specials<br>`future`: Monitor episodes that have not aired yet<br>`missing`: Monitor episodes that do not have files or have not aired yet<br>`existing`: Monitor episodes that have files or have not aired yet<br>`pilot`: Monitor the first episode. All other episodes will be ignored<br>`first`: Monitor all episodes of the first season. All other seasons will be ignored<br>`latest`: Monitor all episodes of the latest season and future seasons<br>`none`: No episodes will be monitored | `all` | &#10060; |
| `quality_profile` | Quality Profile To Use | N/A | &#9989; |
| `language_profile` | Language Profile To Use (v3 Only) | First Profile | &#10060; |
| `series_type` | `standard`: Episodes released with SxxEyy pattern<br>`daily`: Episodes released daily or less frequently that use year-month-day (2017-05-25)<br>`anime`: Episodes released using an absolute episode number | `standard` | &#10060; |
| `season_folder` | Use the Season Folder Option when adding to Sonarr<br>**boolean:** true or false | true | &#10060; |
| `tag` | Add this list or comma-separated string of tags to every show added to Sonarr | ` ` | &#10060; |
| `search` | Start search for missing episodes<br>**boolean:** true or false | false | &#10060; |
| `cutoff_search` | Start search for cutoff unmet episodes<br>**boolean:** true or false | false | &#10060; |
| `plex_path` | When using `add_existing` or `sonarr_add_all` Convert this part of the path to `sonarr_path` | ` ` | &#10060; |
| `sonarr_path` | When using `add_existing` or `sonarr_add_all` Convert the `plex_path` part of the path to this | ` ` | &#10060; |
* The `token` can be found by going to `Sonarr > Settings > General > Security > API Key`
* The `quality_profile` and `language_profile` must be the exact name of the desired quality profile, including all spaces and capitalization.
* You can set most attributes per collection by using the [Sonarr Details](../metadata/details/arr.md#sonarr-details)
![Sonarr Details](sonarr.png)

@ -0,0 +1,20 @@
# Tautulli Attributes
Configuring [Tautulli](https://tautulli.com/) is optional but can allow you to create Collections based on Tautulli's Watch Statistics.
A `tautulli` mapping can be either in the root of the config file as global mapping for all libraries, or you can specify the `tautulli` mapping individually per library.
Below is a `tautulli` mapping example and the full set of attributes:
```yaml
tautulli:
url: http://192.168.1.12:8659
apikey: ################################
```
| Attribute | Allowed Values | Default | Required |
|:----------|:------------------------------------------------------|:-------:|:--------:|
| `url` | Tautulli URL<br>**Example:** http://192.168.1.12:8659 | N/A | &#9989; |
| `apikey` | Tautulli API Key | N/A | &#9989; |
* The apikey can be found by going to Tautulli > Settings > Web Interface > API > API Key

@ -0,0 +1,19 @@
# TMDb Attributes
Configuring [TheMovieDb](https://www.themoviedb.org/) is required in order to run the script.
A `tmdb` mapping is in the root of the config file.
Below is a `tmdb` mapping example and the full set of attributes:
```yaml
tmdb:
apikey: ################################
language: en
```
| Attribute | Allowed Values | Default | Required |
|:-----------|:---------------------|:-------:|:--------:|
| `apikey` | User TMDb V3 API Key | N/A | &#9989; |
| `language` | User Language | en | &#10060; |
If you do not have a TMDb V3 API key please refer to this [guide](https://developers.themoviedb.org/3/getting-started/introduction).

@ -0,0 +1,43 @@
# Trakt Attributes
Configuring [Trakt.tv](https://trakt.tv/) is optional but is required for Trakt based collections to function.
A `trakt` mapping is in the root of the config file.
Below is a `trakt` mapping example and the full set of attributes:
```yaml
trakt:
client_id: ################################################################
client_secret: ################################################################
authorization:
access_token:
token_type:
expires_in:
refresh_token:
scope:
created_at:
```
| Attribute | Allowed Values | Default | Required |
|:----------------|:--------------------------------|:-------:|:--------:|
| `client_id` | Trakt Application Client ID | N/A | &#9989; |
| `client_secret` | Trakt Application Client Secret | N/A | &#9989; |
* All other attributes will be filled in by the script.
* To connect to Trakt.tv you must create a Trakt application and supply the script the `client id` and `client secret` provided, please do the following:
1. [Click here to create a Trakt API application.](https://trakt.tv/oauth/applications/new)
2. Enter a `Name` for the application.
3. Enter `urn:ietf:wg:oauth:2.0:oob` for `Redirect uri`.
4. Click the `SAVE APP` button.
5. Record the `Client ID` and `Client Secret`.
* On the first run, the script will walk the user through the OAuth flow by producing a Trakt URL for the user to follow. Once authenticated at the Trakt URL, the user needs to return the code to the script. If the code is correct, the script will populate the `authorization` sub-attributes to use in subsequent runs.
<h4>OAuth Flow using Docker</h4>
To authenticate Trakt the first time, you need run the container with the `-it` flags in order to walk through the OAuth flow mentioned above. Once you have the Trakt authentication data saved into the YAML, you'll be able to run the container normally.
<h4>OAuth Flow using unRAID Docker</h4>
Directions on how to authenticate Trakt on unRAID can be found on the [unRAID Walkthrough](../home/guides/unraid.md#advanced-installation-authenticating-trakt-or-myanimelist) page.

@ -0,0 +1,149 @@
# Webhooks Attributes
Configuring Webhooks is optional but can allow you to receive notifications when certain events happen.
A `webhooks` mapping is in the root of the config file.
Below is a `webhooks` mapping example and the full set of attributes:
```yaml
webhooks:
error: https://www.myspecialdomain.com/pmm
run_start:
run_end:
changes:
```
| Attribute | Global | Library | Collection |
|:----------------------------------------|:-------:|:--------:|:----------:|
| [`error`](#error-notifications) | &#9989; | &#9989; | &#10060; |
| [`run_start`](#run-start-notifications) | &#9989; | &#10060; | &#10060; |
| [`run_end`](#run-end-notifications) | &#9989; | &#10060; | &#10060; |
| [`changes`](#changes-notifications) | &#9989; | &#9989; | &#9989; |
* Each Attribute can be either a webhook url as a string or a comma-separated list of webhooks urls.
* To send notifications to [Notifiarr](notifiarr) just add `notifiarr` to a webhook instead of the webhook url.
## Error Notifications
The Error notification will be sent whenever an error occurs. The payload that is sent is different Depending on which level the error occurs.
### Global JSON Payload
```yaml
{
"error": str, // Error Message
"critical": bool // Critical Error
}
```
### Library JSON Payload
```yaml
{
"error": str, // Error Message
"critical": bool, // Critical Error
"server_name": str, // Server Name
"library_name": str // Library Name
}
```
### Collection JSON Payload
```yaml
{
"error": str, // Error Message
"critical": bool, // Critical Error
"server_name": str, // Server Name
"library_name": str, // Library Name
"collection": str // Collection Name
}
```
### Playlist JSON Payload
```yaml
{
"error": str, // Error Message
"critical": bool, // Critical Error
"server_name": str, // Server Name
"library_name": str, // Library Name
"playlist": str // Playlist Name
}
```
## Run Start Notifications
The Run Start notification will be sent at the beginning of every run.
### JSON Payload
```yaml
{
"start_time": str, // Time Run is started Format "YY-mm-dd HH:MM:SS"
}
```
## Run End Notifications
The Run End notification will be sent at the end of every run with statistics.
### JSON Payload
```yaml
{
"start_time": str, // Time Run started Format "YY-mm-dd HH:MM:SS"
"end_time": str, // Time Run ended Format "YY-mm-dd HH:MM:SS"
"run_time": str, // Time Run took to complete Format "HH:MM"
"collections_created": int, // Number of Collections/Playlists Created
"collections_modified": int, // Number of Collections/Playlists Modified
"collections_deleted": int, // Number of Collections/Playlists Removed
"items_added": int, // Number of Items added across all Collections/Playlists
"items_removed": int, // Number of Items removed across all Collections/Playlists
"added_to_radarr": int, // Number of Items added to Radarr
"added_to_sonarr": int // Number of Items added to Sonarr
"names": [
"name": str, // Name of collection or playlist in the run
"library": str // Library the collection is in or PLAYLIST
]
}
```
## Changes Notifications
The Changes Notification will be sent after each collection/playlist containing the following payload if the collection/playlist has been created, has new items, or has had items removed.
### JSON Payload
```yaml
{
"server_name": str, // Server Name
"library_name": str, // Library Name
"collection": str, // Collection Name only in payload for a collection
"playlist": str, // Playlist Name only in payload for a playlist
"created": bool, // Was the Collection/Playlist Created on this run
"deleted": bool, // Was the Collection/Playlist Deleted on this run
"poster": str, // Base64 Encoded Collection/Playlist Poster if no poster_url is found
"poster_url": str, // Collection/Playlist Poster URL if avaiable
"background": str, // Base64 Encoded Collection/Playlist Background if no poster_url is found
"background_url": str, // Collection/Playlist Background URL if avaiable
"additions": [
"title": str, // Title of addition
"tmdb_id": int // TMDb ID of addition only appears if it's a Movie
"tvdb_id": int // TVDb ID of addition only appears if it's a Show
],
"removals": [
"title": str, // Title of removal
"tmdb_id": int // TMDb ID of removal only appears if it's a Movie
"tvdb_id": int // TVDb ID of removal only appears if it's a Show
],
"radarr_adds": [
"title": str, // Title of the Radarr Add
"id": int // TMDb ID of the Radarr Add
],
"sonarr_adds": [
"title": str, // Title of the Sonarr Add
"id": int // TVDb ID of the Sonarr Add
]
}
```

@ -0,0 +1,47 @@
# Acknowledgements
The team at Plex Meta Manager would like to recognize and thank those who have helped the project become what it is today.
**We extend our gratitude to everyone who has contributed in any way towards any of the projects mentioned below.**
<br>
<br>
## Community Developer Acknowledgements
These are the developers and creators who are an active part of the Plex Meta Manager community and help us achieve new goals.
| Acknowledgement | Reason | Sponsor the Developer |
|:---------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------:|
| [chazlarson](https://github.com/chazlarson/) | Creator of [Media-Scripts](https://github.com/chazlarson/Media-Scripts) which offers supporting functionality to users of Plex Meta Manager | [Click Here](https://www.google.com/search?q=food+shelf+near+me) |
| [Fribb](https://github.com/Fribb) | Creator of the [MyAnimelist.net Metadata Agent](https://github.com/Fribb/MyAnimeList.bundle) which makes matching Anime easy for Plex Meta Manager users | &#10060; |
| [linas](https://github.com/linaspurinis) | Creator of [MDBlist.com](https://github.com/deva5610/IMDBList2PlexCollection) which makes creating Plex Meta Manager compatible lists easy | [Click Here](https://www.patreon.com/mdblist/posts) |
| [nitsua](https://github.com/austinwbest) | Creator of [Notifiarr](https://github.com/Notifiarr) which integrates Plex Meta Manager with Discord | [Click Here](https://github.com/sponsors/Notifiarr) |
<br>
## Project Inspiration Acknowledgements
These are the developers and creators who served as inspiration for Plex Meta Manager.
| Acknowledgement | Reason | Sponsor the Developer |
|:--------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------:|
| [vladimir-tutin](https://github.com/vladimir-tutin) | Creator of the original [Plex Auto Collections](https://github.com/vladimir-tutin/Plex-Auto-Collections) which is the inspiration for Plex Meta Manager. | &#10060; |
| [jkirkcaldy](https://github.com/jkirkcaldy) | Creator of [plex-utills](https://github.com/jkirkcaldy/plex-utills) which served as inspiration for Image Overlay | [Click Here](https://opencollective.com/themainframe) |
| [JonnyWong16](https://github.com/JonnyWong16) | Creator of the [IMDb Top 250](https://gist.github.com/JonnyWong16/f5b9af386ea58e19bf18c09f2681df23) collection script which served as inspiration for IMDBList2PlexCollection (and for [Tautulli](https://github.com/Tautulli/Tautulli)!) | [Click Here](https://github.com/sponsors/JonnyWong16) |
| [bearlikelion](https://github.com/bearlikelion) | Creator of [popularplex](https://github.com/bearlikelion/popularplex) which served as inspiration for Tautulli support within Plex Meta Manager | &#10060; |
| [deva5610](https://github.com/deva5610) | Creator of [IMDBList2PlexCollection](https://github.com/deva5610/IMDBList2PlexCollection) which prompted vladimir-tutin to write the original Plex Auto Collections | &#10060; |
| [mza921](https://github.com/mza921) and [burkasaurusrex](https://github.com/burkasaurusrex) | Maintaining a forked [Plex Auto Collections](https://github.com/mza921/Plex-Auto-Collections) | &#10060; |
<br>
## PMM Dependency Acknowledgements
These are the developers and creators of the technologies that are required to make Plex Meta Manager work.
| Acknowledgement | Reason | Sponsor the Developer |
|:--------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------:|
| [pkkid](https://github.com/pkkid) | Creator of [python-plexapi](https://github.com/pkkid/python-plexapi) | &#10060; |
| [dbader](https://github.com/dbader) | Creator of [schedule](https://github.com/dbader/schedule) | &#10060; |
| [rholder](https://github.com/rholder) | Creator of [retrying](https://github.com/rholder/retrying) | &#10060; |
| [ZeroQI](https://github.com/ZeroQI) | Creator of [Absolute Series Scanner](https://github.com/ZeroQI/Absolute-Series-Scanner) and [HTTP Anidb Metadata Agent (HAMA)](https://github.com/ZeroQI/Hama.bundle) | [Click Here](https://github.com/sponsors/ZeroQI) |
| [ScudLee](https://github.com/ScudLee) | Creator of [AniDb Anime Lists](https://github.com/Anime-Lists/anime-lists) | &#10060; |

@ -0,0 +1,807 @@
# Run Commands & Environment Variables
This table outlines the run commands and environment variables that can be utilized to customize the running of Plex Meta Manager to the user's requirements. Environment Variable values are used over Shell Command values.
If you run into a race condition where you have set an Environment Variable within your system and also use a Shell Command for the same attribute, then the Environment Variable will take priority.
| Attribute | Shell Command | Environment Variable |
|:------------------------------------------------------|:-----------------------------------|:-------------------------|
| [Config](#config) | `-c` or `--config` | `PMM_CONFIG` |
| [Time to Run](#time-to-run) | `-t` or `--time` | `PMM_TIME` |
| [Run](#run) | `-r` or `--run` | `PMM_RUN` |
| [Run Tests](#run-tests) | `-rt`, `--tests`, or `--run-tests` | `PMM_TEST` |
| [Collections Only](#collections-only) | `-co` or `--collections-only` | `PMM_COLLECTIONS_ONLY` |
| [Libraries Only](#libraries-only) | `-lo` or `--libraries-only` | `PMM_LIBRARIES_ONLY` |
| [Run Collections](#run-collections) | `-rc` or `--run-collections` | `PMM_COLLECTIONS` |
| [Run Libraries](#run-libraries) | `-rl` or `--run-libraries` | `PMM_LIBRARIES` |
| [Run Metadata Files](#run-metadata-files) | `-rm` or `--run-metadata-files` | `PMM_METADATA_FILES` |
| [Libraries First](#libraries-first) | `-lf` or `--libraries-first` | `PMM_LIBRARIES_FIRST` |
| [Ignore Schedules](#ignore-schedules) | `-is` or `--ignore-schedules` | `PMM_IGNORE_SCHEDULES` |
| [Ignore Ghost](#ignore-ghost) | `-ig` or `--ignore-ghost` | `PMM_IGNORE_GHOST` |
| [Delete Collections](#delete-collections) | `-dc` or `--delete-collections` | `PMM_DELETE_COLLECTIONS` |
| [Resume Run](#resume-run) | `-re` or `--resume` | `PMM_RESUME` |
| [No Countdown](#no-countdown) | `-nc` or `--no-countdown` | `PMM_NO_COUNTDOWN` |
| [No Missing](#no-missing) | `-nm` or `--no-missing` | `PMM_NO_MISSING` |
| [Read Only Config](#read-only-config) | `-ro` or `--read-only-config` | `PMM_READ_ONLY_CONFIG` |
| [Divider Character](#divider-character--screen-width) | `-d` or `--divider` | `PMM_DIVIDER` |
| [Screen Width](#divider-character--screen-width) | `-w` or `--width` | `PMM_WIDTH` |
Further explanation and examples of each command can be found below.
## Run Command Attribute Examples
### Config
Specify the location of the configuration YAML file.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th style="background-color: #222;"></th>
<th>Shell</th>
<th>Environmental</th>
</tr>
<tr>
<th>Flags</th>
<td><code>-c</code> or <code>--config</code></td>
<td><code>PMM_CONFIG</code></td>
</tr>
<tr>
<th>Example</th>
<td><code>--config /data/config.yml</code></td>
<td><code>PMM_CONFIG=/data/config.yml</code></td>
</tr>
<tr>
<th>Default</th>
<td colspan="2"><code>config/config.yml</code></td>
</tr>
<tr>
<th>Values</th>
<td colspan="2">Path to YAML config file</td>
</tr>
</table>
<details>
<summary>Local Environment</summary>
```shell
python plex_meta_manager.py --config <path_to_config>
```
</details>
<details>
<summary>Docker Environment</summary>
```shell
docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager --config <path_to_config>
```
</details>
### Time to Run
Specify the time of day that Plex Meta Manager will run.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th style="background-color: #222;"></th>
<th>Shell</th>
<th>Environmental</th>
</tr>
<tr>
<th>Flags</th>
<td><code>-t</code> or <code>--time</code></td>
<td><code>PMM_TIME</code></td>
</tr>
<tr>
<th>Example</th>
<td><code>--time 06:00,18:00</code></td>
<td><code>PMM_TIME=06:00,18:00</code></td>
</tr>
<tr>
<th>Default Value</th>
<td colspan="2"><code>03:00</code></td>
</tr>
<tr>
<th>Available Values</th>
<td colspan="2">comma-separated list in <code>HH:MM</code> format</td>
</tr>
</table>
<details>
<summary>Local Environment</summary>
```shell
python plex_meta_manager.py --time 22:00,03:00
```
</details>
<details>
<summary>Docker Environment</summary>
```shell
docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager --time 22:00,03:00
```
</details>
### Run
Perform a run immediately, bypassing the time to run flag.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th style="background-color: #222;"></th>
<th>Shell</th>
<th>Environmental</th>
</tr>
<tr>
<th>Flags</th>
<td><code>-r</code> or <code>--run</code></td>
<td><code>PMM_RUN</code></td>
</tr>
<tr>
<th>Example</th>
<td><code>--run</code></td>
<td><code>PMM_RUN=true</code></td>
</tr>
</table>
<details>
<summary>Local Environment</summary>
```shell
python plex_meta_manager.py --run
```
</details>
<details>
<summary>Docker Environment</summary>
```shell
docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager --run
```
</details>
### Run Tests
Run Plex Meta Manager in test/debug mode
<table class="dualTable colwidths-auto align-default table">
<tr>
<th style="background-color: #222;"></th>
<th>Shell</th>
<th>Environmental</th>
</tr>
<tr>
<th>Flags</th>
<td><code>-rt</code>, <code>--tests</code>, or <code>--run-tests</code></td>
<td><code>PMM_TEST</code></td>
</tr>
<tr>
<th>Example</th>
<td><code>--run-tests</code></td>
<td><code>PMM_TEST=true</code></td>
</tr>
</table>
* Only collections with `test: true` enabled will be run
<details>
<summary>Local Environment</summary>
```shell
python plex_meta_manager.py --run-tests
```
</details>
<details>
<summary>Docker Environment</summary>
```shell
docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager --run-tests
```
</details>
### Collections Only
Only run collection metadata/YAML files, skip library operations.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th style="background-color: #222;"></th>
<th>Shell</th>
<th>Environmental</th>
</tr>
<tr>
<th>Flags</th>
<td><code>-co</code> or <code>--collections-only</code></td>
<td><code>PMM_COLLECTIONS_ONLY</code></td>
</tr>
<tr>
<th>Example</th>
<td><code>--collections-only</code></td>
<td><code>PMM_COLLECTIONS_ONLY=true</code></td>
</tr>
</table>
<details>
<summary>Local Environment</summary>
```shell
python plex_meta_manager.py --collections-only
```
</details>
<details>
<summary>Docker Environment</summary>
```shell
docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager --collections-only
```
</details>
### Libraries Only
Only run library operations, skip collections.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th style="background-color: #222;"></th>
<th>Shell</th>
<th>Environmental</th>
</tr>
<tr>
<th>Flags</th>
<td><code>-lo</code> or <code>--libraries-only</code></td>
<td><code>PMM_LIBRARIES_ONLY</code></td>
</tr>
<tr>
<th>Example</th>
<td><code>--libraries-only</code></td>
<td><code>PMM_LIBRARIES_ONLY=true</code></td>
</tr>
</table>
<details>
<summary>Local Environment</summary>
```shell
python plex_meta_manager.py --libraries-only
```
</details>
<details>
<summary>Docker Environment</summary>
```shell
docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager --libraries-only
```
</details>
### Run Collections
Run only the pre-defined collections
<table class="dualTable colwidths-auto align-default table">
<tr>
<th style="background-color: #222;"></th>
<th>Shell</th>
<th>Environmental</th>
</tr>
<tr>
<th>Flags</th>
<td><code>-rc</code> or <code>--run-collections</code></td>
<td><code>PMM_COLLECTIONS</code></td>
</tr>
<tr>
<th>Example</th>
<td><code>--run-collections "Harry Potter, Star Wars"</code></td>
<td><code>PMM_COLLECTIONS=Harry Potter, Star Wars</code></td>
</tr>
<tr>
<th>Values</th>
<td colspan="2">Comma-separated list of Collection Names to run</td>
</tr>
</table>
<details>
<summary>Local Environment</summary>
```shell
python plex_meta_manager.py --run-collections "Harry Potter, Star Wars"
```
</details>
<details>
<summary>Docker Environment</summary>
```shell
docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager --run-collections "Harry Potter, Star Wars"
```
</details>
### Run Libraries
Run only the pre-defined libraries
<table class="dualTable colwidths-auto align-default table">
<tr>
<th style="background-color: #222;"></th>
<th>Shell</th>
<th>Environmental</th>
</tr>
<tr>
<th>Flags</th>
<td><code>-rl</code> or <code>--run-libraries</code></td>
<td><code>PMM_LIBRARIES</code></td>
</tr>
<tr>
<th>Example</th>
<td><code>--run-libraries "Movies - 4K, TV Shows - 4K"</code></td>
<td><code>PMM_LIBRARIES=Movies - 4K, TV Shows - 4K</code></td>
</tr>
<tr>
<th>Values</th>
<td colspan="2">Comma-separated list of Library Names to run</td>
</tr>
</table>
<details>
<summary>Local Environment</summary>
```shell
python plex_meta_manager.py --run-libraries "TV Shows"
```
</details>
<details>
<summary>Docker Environment</summary>
```shell
docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager --run-libraries "TV Shows"
```
</details>
### Run Metadata Files
Run only the pre-defined metadata files
<table class="dualTable colwidths-auto align-default table">
<tr>
<th style="background-color: #222;"></th>
<th>Shell</th>
<th>Environmental</th>
</tr>
<tr>
<th>Flags</th>
<td><code>-rm</code> or <code>--run-metadata-files</code></td>
<td><code>PMM_METADATA_FILES</code></td>
</tr>
<tr>
<th>Example</th>
<td><code>--run-metadata-files "Movies.yml, MovieCharts"</code></td>
<td><code>PMM_METADATA_FILES=Movies.yml, MovieCharts</code></td>
</tr>
<tr>
<th>Available Values</th>
<td colspan="2">Comma-separated list of Metadata Filenames to run</td>
</tr>
</table>
* This works for all different metadata paths i.e. `git`, `url`, `file`, or `repo`.
<details>
<summary>Local Environment</summary>
```shell
python plex_meta_manager.py --run-metadata-files "Movies"
```
</details>
<details>
<summary>Docker Environment</summary>
```shell
docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager --run-metadata-files "Movies"
```
</details>
### Libraries First
Run library operations prior to running collections.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th style="background-color: #222;"></th>
<th>Shell</th>
<th>Environmental</th>
</tr>
<tr>
<th>Flags</th>
<td><code>-lf</code> or <code>--libraries-first</code></td>
<td><code>PMM_LIBRARIES_FIRST</code></td>
</tr>
<tr>
<th>Example</th>
<td><code>--libraries-first</code></td>
<td><code>PMM_LIBRARIES_FIRST=true</code></td>
</tr>
</table>
<details>
<summary>Local Environment</summary>
```shell
python plex_meta_manager.py --libraries-first
```
</details>
<details>
<summary>Docker Environment</summary>
```shell
docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager --libraries-first
```
</details>
### Ignore Schedules
Ignore all schedules for the run.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th style="background-color: #222;"></th>
<th>Shell</th>
<th>Environmental</th>
</tr>
<tr>
<th>Flags</th>
<td><code>-is</code> or <code>--ignore-schedules</code></td>
<td><code>PMM_IGNORE_SCHEDULES</code></td>
</tr>
<tr>
<th>Example</th>
<td><code>--ignore-schedules</code></td>
<td><code>PMM_IGNORE_SCHEDULES=true</code></td>
</tr>
</table>
* Range Scheduled collections (such as Christmas movies) will still be ignored.
<details>
<summary>Local Environment</summary>
```shell
python plex_meta_manager.py --ignore-schedules
```
</details>
<details>
<summary>Docker Environment</summary>
```shell
docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager --ignore-schedules
```
</details>
### Ignore Ghost
Ignore all ghost logging for the run. A ghost log is what's printed to the console to show progress during steps.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th style="background-color: #222;"></th>
<th>Shell</th>
<th>Environmental</th>
</tr>
<tr>
<th>Flags</th>
<td><code>-ig</code> or <code>--ignore-ghost</code></td>
<td><code>PMM_IGNORE_GHOST</code></td>
</tr>
<tr>
<th>Example</th>
<td><code>--ignore-ghost</code></td>
<td><code>PMM_IGNORE_GHOST=true</code></td>
</tr>
</table>
<details>
<summary>Local Environment</summary>
```shell
python plex_meta_manager.py --ignore-ghost
```
</details>
<details>
<summary>Docker Environment</summary>
```shell
docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager --ignore-ghost
```
</details>
### Delete Collections
Delete all collections in a Library prior to running collections/operations.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th style="background-color: #222;"></th>
<th>Shell</th>
<th>Environmental</th>
</tr>
<tr>
<th>Flags</th>
<td><code>-dc</code> or <code>--delete-collections</code></td>
<td><code>PMM_DELETE_COLLECTIONS</code></td>
</tr>
<tr>
<th>Example</th>
<td><code>--delete-collections</code></td>
<td><code>PMM_DELETE_COLLECTIONS=true</code></td>
</tr>
</table>
<details>
<summary>Local Environment</summary>
```shell
python plex_meta_manager.py --delete-collections
```
</details>
<details>
<summary>Docker Environment</summary>
```shell
docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager --delete-collections
```
</details>
### Resume Run
Resume a run from a specific collection use the `--resume` option.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th style="background-color: #222;"></th>
<th>Shell</th>
<th>Environmental</th>
</tr>
<tr>
<th>Flags</th>
<td><code>-re</code> or <code>--resume</code></td>
<td><code>PMM_RESUME</code></td>
</tr>
<tr>
<th>Example</th>
<td><code>--resume "Star Wars"</code></td>
<td><code>PMM_RESUME=Star Wars</code></td>
</tr>
<tr>
<th>Available Values</th>
<td colspan="2">Name of collection to resume from</td>
</tr>
</table>
<details>
<summary>Local Environment</summary>
```shell
python plex_meta_manager.py --resume "Star Wars"
```
</details>
<details>
<summary>Docker Environment</summary>
```shell
docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager --resume "Star Wars"
```
</details>
### No Countdown
Run without displaying a countdown to the next scheduled run.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th style="background-color: #222;"></th>
<th>Shell</th>
<th>Environmental</th>
</tr>
<tr>
<th>Flags</th>
<td><code>-nc</code> or <code>--no-countdown</code></td>
<td><code>PMM_NO_COUNTDOWN</code></td>
</tr>
<tr>
<th>Example</th>
<td><code>--no-countdown</code></td>
<td><code>PMM_NO_COUNTDOWN=true</code></td>
</tr>
</table>
<details>
<summary>Local Environment</summary>
```shell
python plex_meta_manager.py --no-countdown
```
</details>
<details>
<summary>Docker Environment</summary>
```shell
docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager --no-countdown
```
</details>
### No Missing
Run without utilizing the missing movie/show functions.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th style="background-color: #222;"></th>
<th>Shell</th>
<th>Environmental</th>
</tr>
<tr>
<th>Flags</th>
<td><code>-nm</code> or <code>--no-missing</code></td>
<td><code>PMM_NO_MISSING</code></td>
</tr>
<tr>
<th>Example</th>
<td><code>--no-missing</code></td>
<td><code>PMM_NO_MISSING=true</code></td>
</tr>
</table>
<details>
<summary>Local Environment</summary>
```shell
python plex_meta_manager.py --no-missing
```
</details>
<details>
<summary>Docker Environment</summary>
```shell
docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager --no-missing
```
</details>
### Read Only Config
Run without writing to the configuration file
<table class="dualTable colwidths-auto align-default table">
<tr>
<th style="background-color: #222;"></th>
<th>Shell</th>
<th>Environmental</th>
</tr>
<tr>
<th>Flags</th>
<td><code>-ro</code> or <code>--read-only-config</code></td>
<td><code>PMM_READ_ONLY_CONFIG</code></td>
</tr>
<tr>
<th>Example</th>
<td><code>--read-only-config</code></td>
<td><code>PMM_READ_ONLY_CONFIG=true</code></td>
</tr>
</table>
<details>
<summary>Local Environment</summary>
```shell
python plex_meta_manager.py --read-only-config
```
</details>
<details>
<summary>Docker Environment</summary>
```shell
docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager --read-only-config
```
</details>
### Divider Character & Screen Width
Change the terminal output divider character or width
#### Divider Character
<table class="dualTable colwidths-auto align-default table">
<tr>
<th style="background-color: #222;"></th>
<th>Shell</th>
<th>Environmental</th>
</tr>
<tr>
<th>Flags</th>
<td><code>-d</code> or <code>--divider</code></td>
<td><code>PMM_DIVIDER</code></td>
</tr>
<tr>
<th>Example</th>
<td><code>--divider *</code></td>
<td><code>PMM_DIVIDER=*</code></td>
</tr>
<tr>
<th>Default</th>
<td colspan="2"><code>=</code></td>
</tr>
<tr>
<th>Values</th>
<td colspan="2">A character</td>
</tr>
</table>
#### Screen Width
<table class="dualTable colwidths-auto align-default table">
<tr>
<th style="background-color: #222;"></th>
<th>Shell</th>
<th>Environmental</th>
</tr>
<tr>
<th>Flags</th>
<td><code>-w</code> or <code>--width</code></td>
<td><code>PMM_WIDTH</code></td>
</tr>
<tr>
<th>Example</th>
<td><code>--width 150</code></td>
<td><code>PMM_WIDTH=150</code></td>
</tr>
<tr>
<th>Default</th>
<td colspan="2">Integer between 90 and 300</td>
</tr>
<tr>
<th>Values</th>
<td colspan="2">A character</td>
</tr>
</table>
<details>
<summary>Local Environment</summary>
```shell
python plex_meta_manager.py --divider * --width 200
```
</details>
<details>
<summary>Docker Environment</summary>
```shell
docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager --divider * --width 200
```
</details>

@ -0,0 +1,217 @@
# Image Asset Directory Guide
The Image Asset Directories can be used to update the posters and backgrounds of collections, movies, shows, seasons, and episodes.
You can specify your asset folders under the `settings` attribute `asset_directory`:
```yaml
settings:
asset_directory: config/assets
```
To use multiple Image Asset Directories specify the directories as a YAML list:
```yaml
settings:
asset_directory:
- config/assets
- config/more_assets
- config/assets_ahoy
```
By default [if no `asset_directory` is specified], the program will look in the same folder as your `config.yml` for a folder called `assets`.
## How assets are run
Assets are searched for only at specific times.
1. Collection assets are searched for whenever that collection is run.
2. Item assets for items in a collection are searched for whenever that collection is run and has `item_assets: true` as a Collection Detail.
3. Item assets and Unmanaged Collections assets are searched for whenever the `assets_for_all` Library Operation is active.
4. Item assets will be searched for any item that has an overlay applied to it.
* If you want to silence the `Asset Warning: No poster or background found in an assets folder for 'TITLE'` you can use the [`show_missing_assets` Setting Attribute](../../config/settings.md#show-missing-assets):
```yaml
settings:
show_missing_assets: false
```
## Asset Naming
The table below shows the asset folder path structures that will be searched for. There are two options for how Plex Meta Manager looks at the files inside your Asset Directories. Choose an option with the [`asset_folders` Setting Attribute](../../config/settings.md#image-asset-folders).
| Image Type | Image Path With Folders<br>`asset_folders: true` | Image Path Without Folder<br>`asset_folders: false` |
|:---------------------------------|:-------------------------------------------------|:----------------------------------------------------|
| Collection/Movie/Show poster | `assets/ASSET_NAME/poster.ext` | `assets/ASSET_NAME.ext` |
| Collection/Movie/Show background | `assets/ASSET_NAME/background.ext` | `assets/ASSET_NAME_background.ext` |
| Season poster | `assets/ASSET_NAME/Season##.ext` | `assets/ASSET_NAME_Season##.ext` |
| Season background | `assets/ASSET_NAME/Season##_background.ext` | `assets/ASSET_NAME_Season##_background.ext` |
| Episode poster | `assets/ASSET_NAME/S##E##.ext` | `assets/ASSET_NAME_S##E##.ext` |
* For **Collections** replace `ASSET_NAME` with the mapping name used with the collection unless `system_name` is specified, which you would then use what's specified in `system_name`.
* For **Movies** replace `ASSET_NAME` with the exact name of the folder the video file is stored in.
* i.e. if you have `Movies/Star Wars (1977)/Star Wars (1977) [1080p].mp4` then your asset directory would look at either `assets/Star Wars (1977)/poster.png` or `assets/Star Wars (1977).png` for the poster.
* For **Shows**, **Seasons**, and **Episodes** replace `ASSET_NAME` with the exact name of the folder for the show as a whole.
* i.e. if you have `Shows/Game of Thrones/Season 1/Game of Thrones - S01E01.mp4` then your asset directory would look at either `assets/Game of Thrones/poster.png` or `assets/Game of Thrones.png` for the poster.
* For **Seasons** replace `##` with the zero padded season number (00 for specials)
* For **Episodes** replacing the first `##` with the zero padded season number (00 for specials), the second `##` with the zero padded episode number
* Replace `.ext` with the image extension
* When `asset_folders` is set to true you can also nest movie/show folders inside other folders, but you must specify how deep you want to search because the more levels to search the longer it takes.
* You can specify how deep you want to scan by using the [`asset_depth` Setting Attribute](../../config/settings.md#asset-depth).
Here's an example config folder structure with an assets directory with `asset_folders` set to true and false.
### `asset_folders: true` without nesting
```
config
├── config.yml
├── Movies.yml
├── TV Shows.yml
├── assets
│ ├── The Lord of the Rings
│ ├── poster.png
│ ├── background.png
│ ├── The Lord of the Rings The Fellowship of the Ring (2001)
│ ├── poster.png
│ ├── background.png
│ ├── The Lord of the Rings The Two Towers (2002)
│ ├── poster.png
│ ├── background.png
│ ├── The Lord of the Rings The Return of the King (2003)
│ ├── poster.png
│ ├── background.png
│ ├── Star Wars (Animated)
│ ├── poster.png
│ ├── background.png
│ ├── Star Wars The Clone Wars
│ ├── poster.png
│ ├── background.png
│ ├── Season00.png
│ ├── Season01.png
│ ├── Season02.png
│ ├── Season03.png
│ ├── Season04.png
│ ├── Season05.png
│ ├── Season06.png
│ ├── Season07.png
│ ├── S07E01.png
│ ├── S07E02.png
│ ├── S07E03.png
│ ├── S07E04.png
│ ├── S07E05.png
│ ├── Star Wars Rebels
│ ├── poster.png
│ ├── background.png
│ ├── Season01.png
│ ├── Season01_background.png
│ ├── Season02.png
│ ├── Season02_background.png
│ ├── Season03.png
│ ├── Season03_background.png
│ ├── Season04.png
│ ├── Season04_background.png
```
### `asset_folders: true` with nesting
```
config
├── config.yml
├── Movies.yml
├── TV Shows.yml
├── assets
│ ├── The Lord of the Rings
│ ├── poster.png
│ ├── background.png
│ ├── The Lord of the Rings The Fellowship of the Ring (2001)
│ ├── poster.png
│ ├── background.png
│ ├── The Lord of the Rings The Two Towers (2002)
│ ├── poster.png
│ ├── background.png
│ ├── The Lord of the Rings The Return of the King (2003)
│ ├── poster.png
│ ├── background.png
│ ├── Star Wars (Animated)
│ ├── poster.png
│ ├── background.png
│ ├── Star Wars The Clone Wars
│ ├── poster.png
│ ├── background.png
│ ├── Season00.png
│ ├── Season01.png
│ ├── Season02.png
│ ├── Season03.png
│ ├── Season04.png
│ ├── Season05.png
│ ├── Season06.png
│ ├── Season07.png
│ ├── S07E01.png
│ ├── S07E02.png
│ ├── S07E03.png
│ ├── S07E04.png
│ ├── S07E05.png
│ ├── Star Wars Rebels
│ ├── poster.png
│ ├── background.png
│ ├── Season01.png
│ ├── Season01_background.png
│ ├── Season02.png
│ ├── Season02_background.png
│ ├── Season03.png
│ ├── Season03_background.png
│ ├── Season04.png
│ ├── Season04_background.png
```
### `asset_folders: false`
```
config
├── config.yml
├── Movies.yml
├── TV Shows.yml
├── assets
│ ├── The Lord of the Rings.png
│ ├── The Lord of the Rings_background.png
│ ├── The Lord of the Rings The Fellowship of the Ring (2001).png
│ ├── The Lord of the Rings The Fellowship of the Ring (2001)_background.png
│ ├── The Lord of the Rings The Two Towers (2002).png
│ ├── The Lord of the Rings The Two Towers (2002)_background.png
│ ├── The Lord of the Rings The Return of the King (2003).png
│ ├── The Lord of the Rings The Return of the King (2003)_background.png
│ ├── Star Wars (Animated).png
│ ├── Star Wars (Animated)_background.png
│ ├── Star Wars The Clone Wars.png
│ ├── Star Wars The Clone Wars_background.png
│ ├── Star Wars The Clone Wars_Season00.png
│ ├── Star Wars The Clone Wars_Season01.png
│ ├── Star Wars The Clone Wars_Season02.png
│ ├── Star Wars The Clone Wars_Season03.png
│ ├── Star Wars The Clone Wars_Season04.png
│ ├── Star Wars The Clone Wars_Season05.png
│ ├── Star Wars The Clone Wars_Season06.png
│ ├── Star Wars The Clone Wars_Season07.png
│ ├── Star Wars The Clone Wars_S07E01.png
│ ├── Star Wars The Clone Wars_S07E02.png
│ ├── Star Wars The Clone Wars_S07E03.png
│ ├── Star Wars The Clone Wars_S07E04.png
│ ├── Star Wars The Clone Wars_S07E05.png
│ ├── Star Wars Rebels.png
│ ├── Star Wars Rebels_background.png
│ ├── Star Wars Rebels_Season01.png
│ ├── Star Wars Rebels_Season01_background.png
│ ├── Star Wars Rebels_Season02.png
│ ├── Star Wars Rebels_Season02_background.png
│ ├── Star Wars Rebels_Season03.png
│ ├── Star Wars Rebels_Season03_background.png
│ ├── Star Wars Rebels_Season04.png
│ ├── Star Wars Rebels_Season04_background.png
```

@ -0,0 +1,213 @@
# Configuration File Walkthrough
This example outlines what a "standard" config.yml file might look like when in use.
<details>
<summary>Example config.yml file</summary>
<br />
```yaml
libraries:
Movies - 4K:
metadata_path:
- file: config/Movies.yml
- git: meisnate12/MovieCharts
TV Shows:
metadata_path:
- file: config/TVShows.yml
- folder: config/TV Shows/
- git: meisnate12/ShowCharts
Animé:
metadata_path:
- file: config/Anime.yml
Music:
metadata_path:
- file: config/Music.yml
playlist_files:
- file: config/playlists.yml
- git: meisnate12/Playlists
settings:
cache: true
cache_expiration: 60
asset_directory: config/assets
asset_folders: true
asset_depth: 0
create_asset_folders: 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: true
show_filtered: false
show_options: false
show_missing: true
show_missing_assets: true
save_missing: true
tvdb_language: eng
ignore_ids:
ignore_imdb_ids:
item_refresh_delay: 0
playlist_sync_to_user: all
verify_ssl: true
webhooks:
error:
run_start:
run_end:
changes:
plex:
url: http://192.168.1.12:32400
token: ####################
timeout: 60
clean_bundles: false
empty_trash: false
optimize: false
tmdb:
apikey: ################################
language: en
tautulli:
url: http://192.168.1.12:8181
apikey: ################################
omdb:
apikey: ########
notifiarr:
apikey: ####################################
anidb:
username: ######
password: ######
radarr:
url: http://192.168.1.12:7878
token: ################################
add_missing: false
add_existing: false
root_folder_path: S:/Movies
monitor: true
availability: announced
quality_profile: HD-1080p
tag:
search: false
radarr_path:
plex_path:
sonarr:
url: http://192.168.1.12:8989
token: ################################
add_missing: false
add_existing: false
root_folder_path: "S:/TV Shows"
monitor: all
quality_profile: HD-1080p
language_profile: English
series_type: standard
season_folder: true
tag:
search: false
cutoff_search: false
sonarr_path:
plex_path:
trakt:
client_id: ################################################################
client_secret: ################################################################
authorization:
# everything below is autofilled by the script
access_token:
token_type:
expires_in:
refresh_token:
scope: public
created_at:
mal:
client_id: ################################
client_secret: ################################################################
authorization:
# everything below is autofilled by the script
access_token:
token_type:
expires_in:
refresh_token:
```
</details>
**Expand the above to see the full config.yml file before continuing.**
<br/>
## Library Mappings (`libraries:`)
`libraries:` is used to tell PMM that the following code relates to Plex libraries. `libraries:` should only be seen once within the configuration file.
In this specific example there are four Plex libraries that are being connected to: `Movies - 4K`, `TV Shows`, `Animé` and `Music`. These names **must** match the name of the library as it appears within Plex, including any special characters such as the é within `Animé`.
Using `Movies - 4K:` as an example, `metadata_path:` instructs PMM that the next piece of code is where to look for the [Metadata Files](../../metadata/metadata) which will be covered in the next section.
<br/>
<br/>
## Metadata/YAML files (`metadata_path:` mappings)
As can be seen in the original config.yml example, there are three metadata_paths being pointed to for the TV Shows library:
```yaml
TV Shows:
metadata_path:
- file: config/TVShows.yml
- folder: config/TV Shows/
- git: meisnate12/ShowCharts
```
These path types are outlined as follows:
* `- file:` refers to a YAML file which is located within the system that PMM is being run from.
* `- folder:` refers to a directory containing YAML files which is located within the system that PMM is being run from.
* `- git:` refers to a YAML file which is hosted on the [GitHub Configs Repo](https://github.com/meisnate12/Plex-Meta-Manager-Configs) unless the user has specified a custom repository within the settings section of the config.yml file.
Within the above example, PMM will:
* First, look within the root of the PMM directory (also known as `config/`) for a metadata file named `Movies.yml`. If this file does not exist, PMM will skip the entry and move to the next one in the list.
* Then, look within the root of the PMM directory (also known as `config/`) for a directory called `TV Shows`, and then load any metadata/YAML files within that directory.
* Finally, look at the [meisnate12 folder](https://github.com/meisnate12/Plex-Meta-Manager-Configs/tree/master/meisnate12) within the GitHub Configs Repo for a file called `MovieCharts.yml` which it finds [here](https://github.com/meisnate12/Plex-Meta-Manager-Configs/blob/master/meisnate12/MovieCharts.yml).
It should be noted that whilst the user should be able to edit any metadata files which are `- file:` or `- folder:` based, they have little to no control over `- git:` metadata files **unless a copy of the YAML file is downloaded and ran locally**. In the above example, if the user downloaded the [MovieCharts.yml file](https://github.com/meisnate12/Plex-Meta-Manager-Configs/blob/master/meisnate12/MovieCharts.yml) from the [GitHub Configs Repo](https://github.com/meisnate12/Plex-Meta-Manager-Configs) and placed it in the root directory of PMM (`config/`), then the metadata_path mapping would be updated to reflect this as follows:
```yaml
Movies - 4K:
metadata_path:
- file: config/Movies.yml
- file: config/MovieCharts.yml <------ HERE
```
## Playlists (`playlist_files:` mappings)
Playlists can be seen as an extension of Libraries in that they are both handled very similarly within PMM:
```yaml
playlist_files:
- file: config/playlists.yml
- git: meisnate12/Playlists
```
As with `libraries:`, YAML files are defined to create the Playlists. It should be noted that whilst in `libraries:` when working with `playlist_files:` you call out the libraries being connected to within the Metadata/YAML file as Playlists can combine media from multiple libraries. You can view an example playlists.yml file as follows:
<details>
<summary>Example playlists.yml file</summary>
<br />
```yaml
playlists:
Marvel Cinematic Universe:
sync_to_users: all
sync_mode: sync
libraries: Movies, TV Shows
trakt_list: https://trakt.tv/users/donxy/lists/marvel-cinematic-universe?sort=rank,asc
summary: Marvel Cinematic Universe In Order
Star Wars Clone Wars Chronological Order:
sync_to_users: all
sync_mode: sync
libraries: Movies, TV Shows
trakt_list: https://trakt.tv/users/tomfin46/lists/star-wars-the-clone-wars-chronological-episode-order
```
</details>
As can be seen in the above examples, multiple libraries are being used to combine different types of media (movies and tv shows in this case) into one playlist.

@ -0,0 +1,536 @@
# Docker Walkthrough
This article will walk you through getting Plex-Meta-Manager [PMM] set up and running via Docker. It will cover:
1. Installing Docker
2. Retrieving the image
3. Setting up the initial config file
4. Setting up a metadata file and creating a couple sample collections
5. Creating a docker container that will keep running in the background
## Prerequisites.
Anywhere you see
```
something like this
```
Thats a command youre going to type or paste into your terminal (OSX or Linux) or Powershell (Windows).
IMPORTANT NOTE:
This walkthrough is going to be pretty pedantic. Im assuming youre reading it because you have no idea how to get a Docker container going, so Im proceeding from the assumption that you want to be walked through every little detail. Youre going to deliberately cause errors and then fix them as you go through it. This is to help you understand what exactly is going on behind the scenes so that when you see these sorts of problems in the wild you will have some background to understand whats happening. If I only give you the happy path walkthrough, then when you make a typo later on youll have no idea where that typo might be or why its breaking things.
I am assuming you do not have any of these tools already installed. When writing this up I started with a brand new Windows 10 install.
### Installing Docker.
The Docker install is discussed here: [Installing Docker](https://docs.docker.com/engine/install/)
ONce you have Docker installed, test it at the command line with:
```
docker run --rm hello-world
```
You should see something that starts with:
```
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
```
---
The great thing about Docker is that all the setup you'd have to do to run PMM is already done inside docker image.
That means we can just jump right into running it. At the command prompt, type:
```
docker run --rm meisnate12/plex-meta-manager --run
```
[This is going to fail with an error, dont panic]
You should see something like this:
```
Unable to find image 'meisnate12/plex-meta-manager:latest' locally
latest: Pulling from meisnate12/plex-meta-manager
7d63c13d9b9b: Already exists
6ad2a11ca37b: Already exists
8076cdef4689: Pull complete
0ba90f5a7dd0: Pull complete
27c191df269f: Pull complete
c75e4c0924fa: Pull complete
ed6716577767: Pull complete
0547721ab7a3: Pull complete
ea4d35bce959: Pull complete
Digest: sha256:472be179a75259e07e68a3da365851b58c2f98383e02ac815804299da6f99824
Status: Downloaded newer image for meisnate12/plex-meta-manager:latest
Config Error: config not found at //config
```
That error means you dont have a config file, but we know that most everything is in place to run the image.
### Setting up a volume map
PMM, inside that Docker container, can only see other things *inside the container*. We want to add our own files for config and metadata, so we need to set something up that lets PMM see files we create *outside* the container. This is called a "volume map".
Go to your home directory and create a new directory:
```
cd ~
mkdir plex-meta-manager
```
cd into that directory:
```
cd ~/plex-meta-manager
```
get the full path:
```
pwd
```
This will display a full path:
<details>
<summary>OS X</summary>
<br />
```
/Users/YOURUSERNAME/plex-meta-manager
```
</details>
<details>
<summary>Linux</summary>
<br />
```
/home/YOURUSERNAME/plex-meta-manager
```
</details>
<details>
<summary>Windows</summary>
<br />
```
C:\Users\YOURUSERNAME\plex-meta-manager
```
</details>
You'll need to add this to the docker command every time you run it:
```
docker run --rm -it -v "PMM_PATH_GOES_HERE:/config:rw" meisnate12/plex-meta-manager
```
as an example:
```
docker run --rm -it -v "/Users/mroche/plex-meta-manager:/config:rw" meisnate12/plex-meta-manager
```
If you run that command now it will display a similar error to before, but without all the image loading:
```
$ docker run --rm -it -v "/Users/mroche/plex-meta-manager:/config:rw" meisnate12/plex-meta-manager --run
Config Error: config not found at //config
```
Note that I show the example path there.
### Setting up the initial config file
Next youll set up the config file. ThIs tells PMM how to connect to Plex and a variety of other services.
Before you do this youll need:
1. TMDb API key. Theyre free.
1. Plex URL and Token
There are a bunch of other services you *can* configure in the config file, but these two are the bare minimum.
#### Getting a TMDb API Key
Note that if you already have an API key, you can use that one. You dont need another.
Go to https://www.themoviedb.org/. Log into your account [or create one if you dont have one already], then go to “Settings” under your account menu.
In the sidebar menu on the left, select “API”.
Click to generate a new API key under "Request an API Key". If there is already one there, copy it and go to the next step.
There will be a form to fill out; the answers are arbitrary. The URL can be your personal website, or probably even google.com or the like.
Once youve done that there should be an API Key available on this screen.
Copy that value, youll need it for the config file.
#### Getting a Plex URL and Token
The Plex URL is whatever URL youd use **from this machine** to connect directly to your Plex server [i.e. NOT app.plex.tv].
As with the TMDb API Key, if you already have a Plex Token, you can use that one.
This article will describe how to get a token: [Finding an authentication token](https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/)
#### Editing the config template
First, make a copy of the template, then open the copy in an editor:
<details>
<summary>OS X/Linux</summary>
<br />
Get a copy of the template to edit:
```
curl -fLvo config.yml https://raw.githubusercontent.com/meisnate12/Plex-Meta-Manager/master/config/config.yml.template
```
Open it in an editor:
```
nano config.yml
```
Im using `nano` here simply because its built into OSX. On Linux you may need to install `nano`, or you can use any other text editor you wish provided it saves files as PLAIN TEXT.
</details>
<details>
<summary>Windows</summary>
<br />
Download the file `https://raw.githubusercontent.com/meisnate12/Plex-Meta-Manager/master/config/config.yml.template` using a web browser or whatever means and save it in this directory as `config.yml`
```
notepad config.yml
```
Im using `notepad` here simply because its built into Windows. You can use any other text editor provided it saves files as PLAIN TEXT.
</details>
From here on in, when I say "open the config file", I mean the `nano` or `notepad` command. You don't want to download the template again.
---
Scroll down a bit and update the three things you just collected; Plex URL, Plex Token, and TMDb API Key.
```
plex: # Can be individually specified per library as well
url: http://bing.bang.boing <<< ENTER YOUR PLEX URL
token: XXXXXXXXXXXXXXXXXXXX <<< ENTER YOUR PLEX TOKEN
timeout: 60
clean_bundles: false
empty_trash: false
optimize: false
tmdb:
apikey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX <<< ENTER YOUR TMDb API
language: en
```
Now scroll up and look at the top section:
```
libraries: # Library mappings must have a colon (:) placed after them
Movies:
metadata_path:
- file: config/Movies.yml # You have to create this file the other is online
- git: meisnate12/MovieCharts
TV Shows:
metadata_path:
- file: config/TV Shows.yml # You have to create this file the other is online
- git: meisnate12/ShowCharts
Anime:
metadata_path:
- file: config/Anime.yml # You have to create this file the other is online
- git: meisnate12/AnimeCharts
```
You need an entry here for each of the libraries on which you want PMM to act. Those top-level elements [Movies, TV Shows, Anime] are names of libraries on your Plex server.
Delete the “TV Shows” and “Anime” sections and change the name of the “Movies” section to something that is NOT included in your Plex. Im using “Movies-HIDDEN":
```
libraries: # Library mappings must have a colon (:) placed after them
Movies-HIDDEN:
metadata_path:
- file: config/Movies.yml # You have to create this file the other are online
- git: meisnate12/MovieCharts
```
This is intended to cause an error, so bear with me.
#### Testing the config file
Save the file:
<details>
<summary>OS X/Linux</summary>
<br />
If you're using `nano`, type control-`x`, then `y`, then the enter key.
</details>
<details>
<summary>Windows</summary>
<br />
If you're using `notepad`, type alt-`s` of choose `Save` from the `File` menu.
</details>
Then run the script again:
```
docker run --rm -it -v "PMM_PATH_GOES_HERE:/config:rw" meisnate12/plex-meta-manager --run
```
Ive removed some of the lines for space, but have left the important bits:
```
...
| Starting Run|
...
| Locating config...
|
| Using /Users/mroche/Plex-Meta-Manager/config/config.yml as config
...
| Connecting to TMDb...
| TMDb Connection Successful
...
| Connecting to Plex Libraries...
...
| Connecting to Movies-HIDDEN Library... |
...
| Plex Error: Plex Library Movies-HIDDEN not found |
| Movies-HIDDEN Library Connection Failed |
|====================================================================================================|
| Plex Error: No Plex libraries were connected to |
...
```
You can see there that PMM found its config file, was able to connect to TMDb, was able to connect to Plex, and then failed trying to read the “Movies-HIDDEN” library, which of course doesnt exist.
Open the config file again and change "Movies-HIDDEN" [or whatever you used in the previous step] to reflect your Plex. Also fix the name of the config file to match the library. Then delete any lines that start with “git”. Those are all sets of collections, and we just want to create a few as examples.
My Movies library is called “Main Movies", so mine looks like this:
```
libraries: # Library mappings must have a colon (:) placed after them
Main Movies:
metadata_path:
- file: config/Main Movies.yml # You have to create this file the other are online
```
NOTE: the matching naming of Library and YML is not actually required, I'm doing it here for clarity.
Save the file:
<details>
<summary>OS X/Linux</summary>
<br />
If you're using `nano`, type control-`x`, then `y`, then the enter key.
</details>
<details>
<summary>Windows</summary>
<br />
If you're using `notepad`, type alt-`s` of choose `Save` from the `File` menu.
</details>
Then run the script again:
```
docker run --rm -it -v "PMM_PATH_GOES_HERE:/config:rw" meisnate12/plex-meta-manager --run
```
Now youll see some more activity in the Plex connection section:
```
$ docker run --rm -it -v "/Users/mroche/plex-meta-manager:/config:rw" meisnate12/plex-meta-manager --run
...
| Connecting to Plex Libraries...
...
| Connecting to Main Movies Library...
...
| Loading Metadata File: config/Main Movies.yml
|
| YAML Error: File Error: File does not exist config/Main Movies.yml
...
| Metadata File Error: No valid metadata files found
|
| Main Movies Library Connection Failed
...
```
We can see there that it connected to the Plex Library, failed to find a metadata file, and then quit.
So far so good.
### Setting up a metadata file and creating a few sample collections.
Now we have to set up that metadata file that PMM just complained about.
This metadata file contains definitions of the actions you want PMM to take. You can find lots of examples [here](https://github.com/meisnate12/Plex-Meta-Manager-Configs):
For now were going to create a few collections so you can watch the process work, then youre on your own to create whatever others you want.
First, open the metadata file [this will create the file if it doesn't already exist]:
<details>
<summary>OS X/Linux</summary>
<br />
```
nano "Main Movies.yml"
```
</details>
<details>
<summary>Windows</summary>
<br />
```
notepad "Main Movies.yml"
```
</details>
[of course, that should be the file name you just entered in config.yml, if you changed it from the default]
In this file, add the following, exactly as it is shown here:
```
templates:
Actor:
actor: tmdb
tmdb_person: <<person>>
tmdb_actor_details: <<person>>
sort_title: +_<<collection_name>>
sync_mode: sync
collection_order: release
collection_mode: hide
collections:
Bill Murray:
template: {name: Actor, person: 1532}
Best of the 1980s:
tmdb_discover:
primary_release_date.gte: 01/01/1980
primary_release_date.lte: 12/31/1989
with_original_language: en
sort_by: popularity.desc
limit: 100
summary: A collection of the Top Content of the 1980s
Vultures 101 Best Movie Endings:
letterboxd_list: https://letterboxd.com/brianformo/list/vultures-101-best-movie-endings/
```
I chose a letterboxd list for the last one since trakt requires authentication and again, I didnt want to complicate this walkthrough.
This is going to create three collections. One contains movies that feature Bill Murray. One is up to 100 movies that came out in the 1980s sorted by popularity. The last are movies that appear on a list of good endings according to Vulture.
The first one is based on a template, so if you wanted to create a collection for another actor you just have to copy and edit those two lines [the ID comes from TMDb]. All the other config details come from the template.
```
Amy Adams:
template: {name: Actor, person: 9273}
```
Save the file:
<details>
<summary>OS X/Linux</summary>
<br />
If you're using `nano`, type control-`x`, then `y`, then the enter key.
</details>
<details>
<summary>Windows</summary>
<br />
If you're using `notepad`, type alt-`s` of choose `Save` from the `File` menu.
</details>
Then run the script again:
```
docker run --rm -it -v "PMM_PATH_GOES_HERE:/config:rw" meisnate12/plex-meta-manager --run
```
This time you should see that the metadata file gets loaded:
```
| Loading Metadata File: config/Main Movies.yml
| Metadata File Loaded Successfully
```
And this time it will catalog all your movies. This could take a while depending on how many movies are in that library.
Once this mapping is complete it will move on to build those three collections.
As it builds the collections, you should see a fair amount of logging about which movies are being added and which ones arent found. Once it completes, go to Plex, go to your Movies library, and click “Collections” at the top.
You should see the three new collections:
![Finished Collections](finished.png)
When you click into each, youll see the movies that PMM added to each collection.
Each time you run the script, new movies that match the collection definition will be added. For example, if you dont have “The Razors Edge” now, when you download it and run PMM again it will be added to the Bill Murray collection.
If you download any of the missing 22 movies on the Vulture list, running PMM would add them to that collection. And so on.
### What comes next:
Delete these three collections if you want, from both Plex and the metadata file. If you add that “git” line you removed back into the config file:
```
- git: meisnate12/MovieCharts
```
then run PMM again, the script will add a whole bunch of new collections [which are defined in that file] you may be interested in.
That line is a link into the github repo of examples I referred to above, so you can review what it contains there. You can also add others from that repo using this same pattern.
If you prefer to create your own, do that in the metadata file.
TV Shows and other libraries work the same way. Create a `Libraries:` section in the config.yml, create a metadata file, define collections, run the script.
Investigate the rest of the wiki to learn about everything else Plex-Meta-Manager can do for you.
### Running the container in the background:
The docker commands in this article are creating and deleting containers.
However, you probably ultimately want a container that runs all the time, even after reboots, and wakes up to do its thing.
This would be the minimal case:
```
docker run -d \
--restart=unless-stopped \
-v PMM_PATH_GOES_HERE:/config:rw \
meisnate12/plex-meta-manager
```
That will create a container that will run in the background until you explicitly stop it, surviving reboots, and waking up every morning at 3AM to process collections.
There are of course other flags you can add, which are discussed elsewhere in the wiki, but this is the minimal command to create this container.

@ -0,0 +1,398 @@
# Kubernetes Walkthrough
This article will walk you through getting Plex-Meta-Manager [PMM] set up and running in Kubernetes. It will cover:
1. Creating the Kubernetes CronJob
1. Creating configuration files as Config Maps
1. (Advanced) Creating dynamic configuration files with an Init Container
## Prerequisites.
This walk through assumes you are familiar with Kubernetes concepts and have an exiting cluster to deploy into. If you
do not, but are interested, [minikube](https://minikube.sigs.k8s.io/docs/start/) is a great place to start.
## Creating the Kubernetes CronJob
When running PMM in Kubernetes, executing it as a CronJob gives us the ability to define a schedule for execution and have
Kubernetes manage the rest.
Some parts of this to tweak to your needs:
1. The namespace should be set to whatever you desire, in this example it runs in the `media` namespace.
2. The schedule, in this example it runs at 00:00 UTC. [https://crontab.guru/](https://crontab.guru/) is a good
site if you aren't sure on how to create a schedule.
```
apiVersion: batch/v1
kind: CronJob
metadata:
name: plex-media-manager
namespace: media
spec:
schedule: "0 0 * * *"
jobTemplate:
spec:
template:
spec:
securityContext:
runAsUser: 1000
runAsGroup: 1000
containers:
- name: plex-media-manager
image: meisnate12/plex-meta-manager:v1.15.1
imagePullPolicy: IfNotFound
args: [ "--run", "--read-only-config" ]
resources:
limits:
cpu: 100m
memory: 256Mi
requests:
cpu: 100m
memory: 125Mi
volumeMounts:
- name: config
mountPath: /config
- name: pmm-config
mountPath: /config/config.yml
subPath: config.yml
- name: movie-config
mountPath: /config/movies.yaml
subPath: movies.yaml
- name: tv-config
mountPath: /config/tv.yaml
subPath: tv.yaml
volumes:
- name: config
persistentVolumeClaim:
claimName: plex-media-manager
- configMap:
name: pmm-config
name: pmm-config
- configMap:
name: movie-config
name: movie-config
- configMap:
name: tv-config
name: tv-config
restartPolicy: OnFailure
```
This CronJob also requires
1. A Persistent Volume Claim
2. 3 Config Maps (see next section)
The Persistent Volume Claim (PVC) can be as simple as:
```
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
labels:
app: plex-media-manager
name: plex-media-manager
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 128Mi
```
## Creating the Config Maps
In Kubernetes, configurations are managed via Config Maps. So we deploy the configurations for PMM as config maps. The
minimum requirement is the PMM config, but the example here assumes you have a separate config for movies and tv shows.
### PMM Config
Here's a config map for the `config.yml` file for PMM. Note there are many placeholders that will need update based on
your environment and needs.
Follow the [Trakt Attributes](../../config/trakt) directions for generating the OAuth authorization
values.
```
apiVersion: v1
data:
config.yml: |
libraries:
Movies:
metadata_path:
- file: config/movies.yaml
TV Shows:
metadata_path:
- file: config/tv.yaml
settings:
cache: true
cache_expiration: 60
asset_directory: config/assets
asset_folders: true
asset_depth: 0
create_asset_folders: false
dimensional_asset_rename: false
download_url_assets: false
show_missing_season_assets: false
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: true
show_filtered: false
show_options: false
show_missing: true
show_missing_assets: true
save_missing: true
tvdb_language: eng
ignore_ids:
ignore_imdb_ids:
playlist_sync_to_user: all
verify_ssl: true
plex:
url: http://PLEX_IP_HERE:32400
token: YOUR_TOKEN_HERE
timeout: 60
clean_bundles: false
empty_trash: false
optimize: false
tmdb:
apikey: YOUR_API_KEY_HERE
language: en
tautulli:
url: http://TAUTULLI_IP_HERE:8182
apikey: TAUTULLI_API_KEY_HERE
omdb:
apikey: OMDB_API_KEY
radarr:
url: http://RADARR_IP_HERE:7878
token: RADARR_TOKEN_HERE
add_missing: false
root_folder_path: /movies
monitor: false
availability: cinemas
quality_profile: HD - 720p/1080p
tag: pmm
add_existing: false
search: false
radarr_path:
plex_path:
sonarr:
url: http://SONARR_IP_HERE:8989
token: SONARR_TOKEN_HERE
add_missing: false
add_existing: false
root_folder_path: /tv
monitor: pilot
quality_profile: HD - 720p/1080p
language_profile: English
series_type: standard
season_folder: true
tag: pmm
search: true
cutoff_search: false
sonarr_path:
plex_path:
trakt:
client_id: YOUR_CLIENT_ID_HERE
client_secret: YOUR_CLIENT_SECRET_HERE
authorization:
access_token: YOUR_ACCESS_TOKEN_HERE
token_type: Bearer
expires_in: 7889237
refresh_token: YOUR_REFERSH_TOKEN_HERE
scope: public
created_at: 1642462048
kind: ConfigMap
metadata:
name: pmm-config
namespace: media
```
### Movie Config Map
Config maps for collections (movies in this example) are more simple!
```
apiVersion: v1
data:
movies.yaml: |
collections:
Trakt Popular:
trakt_popular: 200
collection_order: custom
sync_mode: sync
sort_title: Traktpopular
summary: The most popular movies for all time.
radarr_add_missing: true
radarr_search: true
radarr_monitor: true
Tautulli Most Popular Movies:
sync_mode: sync
collection_order: custom
tautulli_watched:
list_days: 180
list_size: 10
list_minimum: 1
kind: ConfigMap
metadata:
name: movie-config
namespace: media
```
### TV Config Map
```
apiVersion: v1
data:
tv.yaml: |
collections:
Most Popular:
smart_label: originally_available.desc
sync_mode: sync
imdb_list:
url: https://www.imdb.com/search/title/?title_type=tv_series,tv_miniseries
limit: 10
summary: The 10 most popular shows across the internet
sonarr_add_missing: true
sonarr_search: true
sonarr_monitor: pilot
Tautulli Most Popular:
sync_mode: sync
collection_order: custom
summary: The 10 most popular shows from Plex users
tautulli_popular:
list_days: 180
list_size: 10
kind: ConfigMap
metadata:
name: tv-config
namespace: media
```
## Creating dynamic configuration files with an Init Container
IMDb search results may include results for media which has not yet been released, resulting in a collection that is
incomplete. In order to solve for this you can replace a static config map with a config file that is (re)generated when
the cronjob starts each time. This can be done by including an init container which renders a
[Jinja](https://jinja.palletsprojects.com/en/3.0.x/templates/) template to a file in the PVC.
### Including the Init Container in the Cron Job
NOTE the environment value nameed `JINJA_DEST_FILE` is the resulting name of the generated config file.
```
apiVersion: batch/v1
kind: CronJob
metadata:
name: plex-media-manager
namespace: media
spec:
schedule: "0 0 * * *"
jobTemplate:
spec:
template:
spec:
securityContext:
runAsUser: 1000
runAsGroup: 1000
initContainers:
- name: render-dynamic-config
image: chrisjohnson00/jinja-init:v1.0.0
env:
# source and destination files
- name: JINJA_SRC_FILE
value: /config_src/tv.yaml
- name: JINJA_DEST_FILE
value: /config/tv.yaml
# let's be verbose
- name: VERBOSE
value: "1"
volumeMounts:
# configMap mount point
- name: tv-config-template
mountPath: /config_src
# target directory mount point; the final config file will be created here
- name: config
mountPath: /config
containers:
- name: plex-media-manager
image: meisnate12/plex-meta-manager:v1.15.1
imagePullPolicy: Always
args: [ "--run", "--read-only-config" ]
resources:
limits:
cpu: 100m
memory: 256Mi
requests:
cpu: 100m
memory: 125Mi
volumeMounts:
- name: config
mountPath: /config
- name: pmm-config
mountPath: /config/config.yml
subPath: config.yml
- name: movie-config
mountPath: /config/movies.yaml
subPath: movies.yaml
volumes:
- name: config
persistentVolumeClaim:
claimName: plex-media-manager
- configMap:
name: pmm-config
name: pmm-config
- configMap:
name: movie-config
name: movie-config
- configMap:
name: tv-config-jinja-template
name: tv-config-template
restartPolicy: OnFailure
```
### Templatizing your configuration
This example will (re)generate the IMBD list URL and include the current date as the end date for the `release_date` value.
`https://www.imdb.com/search/title/?title_type=tv_series,tv_miniseries&release_date=1980-01-01,{{ now().strftime('%Y-%m-%d') }}`
`{{ now().strftime('%Y-%m-%d') }}` is the Jinja code, which when rendered will be replaced with the current date in
YYYY-MM-DD format. `now()` is a special method defined in the Python code running in the init container to allow access
to the current date, so changing the output format is as simple as changing the string in `strftime` to your desired
date/time format for your list source.
```
apiVersion: v1
data:
tv.yaml: |
collections:
Most Popular:
smart_label: originally_available.desc
sync_mode: sync
imdb_list:
url: https://www.imdb.com/search/title/?title_type=tv_series,tv_miniseries&release_date=1980-01-01,{{ now().strftime('%Y-%m-%d') }}
limit: 10
summary: The 10 most popular shows across the internet
sonarr_add_missing: true
sonarr_search: true
sonarr_monitor: pilot
Tautulli Most Popular:
sync_mode: sync
collection_order: custom
summary: The 10 most popular shows from Plex users
tautulli_popular:
list_days: 180
list_size: 10
kind: ConfigMap
metadata:
name: tv-config-jinja-template
namespace: media
```

@ -0,0 +1,717 @@
# Local Walkthrough
This article will walk you through getting Plex-Meta-Manager [PMM] set up and running. It will cover:
1. Retrieving the PMM code
2. Installing requirements
3. Setting up the initial config file
4. Setting up a metadata file and creating a couple sample collections.
## Prerequisites.
Nearly anywhere you see
```
something like this
```
Thats a command youre going to type or paste into your terminal (OSX or Linux) or Powershell (Windows). In some cases it's displaying *output* from a command you've typed, but the difference should be apparent in context.
IMPORTANT NOTE:
This walkthrough is going to be pretty pedantic. Im assuming youre reading it because you have no idea how to get a Python script going, so Im proceeding from the assumption that you want to be walked through every little detail. Youre going to deliberately cause errors and then fix them as you go through it. This is to help you understand what exactly is going on behind the scenes so that when you see these sorts of problems in the wild you will have some background to understand whats happening. If I only give you the happy path, then when you make a typo later on youll have no idea where that typo might be or why its breaking things.
I am assuming you do not have any of these tools already installed. When writing this up I started with a brand new Windows 10 install.
<h4>If you are using Windows, do everything here in Powershell. You don't need to run it as an Administrator. Git, notably, installs its own command line interface. Don't use that. Do everything here in Powershell.</h4>
<h4>On OSX or Linux, you can use any terminal or shell.</h4>
### Installing Python.
NOTE:
You need to use Python 3.9, not Python 3.10. There's one specific requirement that has not yet been updated for Python 3.10, and if you use Python 3.10 the requirements step will fail with a non-obvious error.
<details>
<summary>Linux</summary>
<br />
First let's check if it's installed already:
```
python3 --version
```
If this doesn't return `3.9.[something]`, you'll need to get Python 3.9 installed. Describing this for any arbitrary linux is out of scope here, but if you're using Ubuntu, [this](https://techviewleo.com/how-to-install-python-on-ubuntu-linux/) might be useful.
</details>
<details>
<summary>OS X</summary>
<br />
First let's check if it's installed already:
```
python3 --version
```
If this doesn't return `3.9.[something]`, you'll need to get Python 3.9 installed.
Follow the instructions here: [Installing Python 3 on Mac OS X](https://docs.python-guide.org/starting/install3/osx/)
</details>
<details>
<summary>Windows</summary>
<br />
Go to http://www.python.org/download and download the latest version of Python for Windows **version 3.9** in 32 or 64-bit as appropriate for your system. As this is written, that's 3.9.6. **Don't download 3.10, even though it's the default offered.**
Once downloaded, run the installer. Tick “Add to path” checkbox at the bottom and click “Install Now”.
For Windows 10, you will need to enable scripts in PowerShell. Follow the instructions [here](https://windowsloop.com/enable-powershell-scripts-execution-windows-10) to do so. If you skip this step you're going to hit a hard stop in a couple steps.
</details>
---
### Installing git
<details>
<summary>Linux</summary>
<br />
First let's check if it's installed already:
```
git --version
```
If this doesn't return a version number, you'll need to get git installed.
The git install is discussed here: [Download for Linux and Unix](https://git-scm.com/download/linux)
</details>
<details>
<summary>OS X</summary>
<br />
First let's check if it's installed already:
```
git --version
```
If this doesn't return a version number, you'll need to get git installed.
The git install is discussed here: [Git - Downloading Package](https://git-scm.com/download/mac)
</details>
<details>
<summary>Windows</summary>
<br />
Download the installer from [here](https://git-scm.com/download/windows)
Run the install; you can probably just accept the defaults and click through except for the step that asks you to choose an editor; you probably want to choose something other than the default there:
![Git Install](git-install.png)
This install comes with its own command line interface. **Do not use this interface in this walkthrough**. Continue to do everything here in Powershell.
</details>
---
### Retrieving the Plex-Meta-Manager code
Clone the repo into your home directory:
```
cd ~
git clone https://github.com/meisnate12/Plex-Meta-Manager
```
Later on you can move it elsewhere if you want, but for now put it there. This will ensure that everything to follow works just like it says here. Presumably youre reading this because the other docs are unclear to you. Dont make unilateral changes to my assumptions while doing this.
<details>
<summary>Why use git instead of downloading the release ZIP?</summary>
<br />
Retrieving the code with `git` makes updating simpler. When you want to update to the newest version, you can go into this directory and type:
```
git pull
```
No need to download a new ZIP, uncompress it, etc.
Also, if you are asked to [or want to] switch to the latest develop code, you can do so with:
```
git checkout develop
```
</details>
---
Now move into that directory:
```
cd ~/Plex-Meta-Manager
```
**NOTE: The rest of this walkthrough assumes you are staying in this directory.**
### Setting up a virtual environment
This walkthrough is going to use a "virtual environment", since that provides a simple way to keep the requirements for a given thing self-contained; think of it as a "sandbox" for this script. It also provides a clean way to recover from mistakes, and keeps the host system clean.
<details>
<summary>OS X/Linux</summary>
<br />
```
python3 -m venv pmm-venv
```
If you see an error like:
```
Error: Command '['/home/mroche/Plex-Meta-Manager/pmm-venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1.
```
You probably need to make sure the Python 3.9-specific virtualenv support library is installed.
On Linux [which is the one platform where this was seen at this point]:
```
sudo apt-get install python3.9-venv
```
</details>
<details>
<summary>Windows</summary>
<br />
```
python -m venv pmm-venv
```
If you see:
```
Python was not found; run without arguments to install from the Microsoft Store, or disable this shortcut from Settings > Manage App Execution Aliases.
```
You apparently didn't check the “Add to path” checkbox above under [installing Python](#installing-python). "Repair" your Python install and check "add python to environment variables".
</details>
---
That will create the virtual environment, and then you need to activate it:
<details>
<summary>OS X/Linux</summary>
<br />
```
source pmm-venv/bin/activate
```
</details>
<details>
<summary>Windows</summary>
<br />
```
.\pmm-venv\Scripts\activate
```
If you see something like this:
```powershell
.\pmm-venv\Scripts\activate : File C:\Users\mroche\Plex-Meta-Manager\pmm-venv\Scripts\Activate.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at https:/go.microsoft.com/fwlink LinkID=135170.
At line:1 char:1
+ .\pmm-venv\Scripts\activate
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : SecurityError: (:) [], PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess
```
You apparently skipped the "enable scripts in Powershell" step above under [installing Python](#installing-python) for Windows.
You will need to take care of that before moving on.
</details>
---
An advantage of doing this in a venv is that in the event something goes wrong, you can delete that pmm-venv directory and do the setup again.
**IMPORTANT: In the future, when you want to run the script, you will need to do this "activation" step every time. Not the venv creation, just the activation**:
<details>
<summary>OS X/Linux</summary>
<br />
```
source pmm-venv/bin/activate
```
</details>
<details>
<summary>Windows</summary>
<br />
```
.\pmm-venv\Scripts\activate
```
</details>
### Installing requirements
Plex-Meta-Manager, like every other Python script, depends on support libraries that manage things like connections to Plex, or getting things from the internet, or writing files and so on.
These support libraries are called “requirements”, and they are defined in that file called `requirements.txt`. To install them, type the following command:
```
python -m pip install -r requirements.txt
```
You should see something like this [Ive removed a few lines for space, and the specific versions may have changed since this was captured]:
```
Collecting PlexAPI==4.7.0
Downloading PlexAPI-4.7.0-py3-none-any.whl (133 kB)
|████████████████████████████████| 133 kB 821 kB/s
Collecting tmdbv3api==1.7.6
Downloading tmdbv3api-1.7.6-py2.py3-none-any.whl (17 kB)
...
Installing collected packages: urllib3, idna, charset-normalizer, certifi, six, ruamel.yaml.clib, requests, tmdbv3api, schedule, ruamel.yaml, retrying, PlexAPI, pillow, pathvalidate, lxml, arrapi
Running setup.py install for retrying ... done
Running setup.py install for arrapi ... done
Successfully installed PlexAPI-4.7.0 arrapi-1.1.3 certifi-2021.10.8 charset-normalizer-2.0.7 idna-3.3 lxml-4.6.3 pathvalidate-2.4.1 pillow-8.3.2 requests-2.26.0 retrying-1.3.3 ruamel.yaml-0.17.10 ruamel.yaml.clib-0.2.6 schedule-1.1.0 six-1.16.0 tmdbv3api-1.7.6 urllib3-1.26.7
WARNING: You are using pip version 21.1.3; however, version 21.3 is available.
You should consider upgrading via the '/Users/mroche/Plex-Meta-Manager/pmm-venv/bin/python -m pip install --upgrade pip' command.
```
Don't worry about the WARNING if it comes up.
Lets make sure its working so far. At the command prompt, type:
```
python plex_meta_manager.py -r
```
[This is going to fail with an error, dont panic]
You should see something like this:
```
Config Error: config not found at /Users/mroche/Plex-Meta-Manager/config
```
That error means you dont have a config file, but we at least know that the requirements are in place and the script can run.
### Setting up the initial config file
Next youll set up the config file. ThIs tells PMM how to connect to Plex and a variety of other services.
Before you do this youll need:
1. TMDb API key. Theyre free.
1. Plex URL and Token
There are a bunch of other services you *can* configure in the config file, but these two are the bare minimum.
#### Getting a TMDb API Key
Note that if you already have an API key, you can use that one. You dont need another.
Go to https://www.themoviedb.org/. Log into your account [or create one if you dont have one already], then go to “Settings” under your account menu.
In the sidebar menu on the left, select “API”.
Click to generate a new API key under "Request an API Key". If there is already one there, copy it and go to the [next step](#getting-a-plex-url-and-token).
There will be a form to fill out; the answers are arbitrary. The URL can be your personal website, or probably even google.com or the like.
Once youve done that there should be an API Key available on this screen.
Copy that value, youll need it for the config file.
#### Getting a Plex URL and Token
The Plex URL is whatever URL youd use **from this machine** to connect directly to your Plex server [i.e. NOT app.plex.tv].
As with the TMDb API Key, if you already have a Plex Token, you can use that one.
This article describes how to get a token: [Finding an authentication token](https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/)
#### Editing the config template
First, make a copy of the template. This is going to create a copy of the base template that you can then edit. You only need to do this once.
<details>
<summary>OS X/Linux</summary>
<br />
```
cp config/config.yml.template config/config.yml
```
</details>
<details>
<summary>Windows</summary>
<br />
```
copy .\config\config.yml.template .\config\config.yml
```
</details>
---
Now open the copy in an editor:
<details>
<summary>OS X/Linux</summary>
<br />
```
nano config/config.yml
```
Im using `nano` here simply because its built into OSX. On Linux you may need to install `nano`, or you can use any other text editor you wish provided it saves files as PLAIN TEXT.
</details>
<details>
<summary>Windows</summary>
<br />
```
notepad .\config\config.yml
```
Im using `notepad` here simply because its built into Windows. You can use any other text editor provided it saves files as PLAIN TEXT.
</details>
From here on in, when I say "open the config file", I mean this `nano` or `notepad` command. **Don't copy the template again**.
---
Scroll down a bit and update the three things you just collected; Plex URL, Plex Token, and TMDb API Key.
```
plex: # Can be individually specified per library as well
url: http://bing.bang.boing <<< ENTER YOUR PLEX URL
token: XXXXXXXXXXXXXXXXXXXX <<< ENTER YOUR PLEX TOKEN
timeout: 60
clean_bundles: false
empty_trash: false
optimize: false
tmdb:
apikey: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX <<< ENTER YOUR TMDb API
language: en
```
Now scroll up and look at the top section:
```
libraries: # Library mappings must have a colon (:) placed after them
Movies:
metadata_path:
- file: config/Movies.yml # You have to create this file the other is online
- git: meisnate12/MovieCharts
TV Shows:
metadata_path:
- file: config/TV Shows.yml # You have to create this file the other is online
- git: meisnate12/ShowCharts
Anime:
metadata_path:
- file: config/Anime.yml # You have to create this file the other is online
- git: meisnate12/AnimeCharts
```
You need an entry here for each of the libraries on which you want PMM to act. Those top-level elements [Movies, TV Shows, Anime] are names of libraries on your Plex server.
Delete the “TV Shows” and “Anime” sections and change the name of the “Movies” section to something that is NOT included in your Plex. Im using “Movies-HIDDEN":
```
libraries: # Library mappings must have a colon (:) placed after them
Movies-HIDDEN:
metadata_path:
- file: config/Movies.yml # You have to create this file the other are online
- git: meisnate12/MovieCharts
```
This is intended to cause an error, so bear with me.
#### Testing the config file
Save the file [in nano that would be cntl-x, y, return], then run the script again:
```
python plex_meta_manager.py -r
```
Ive removed some of the lines for space, but have left the important bits:
```
...
| Starting Run|
...
| Locating config...
|
| Using /Users/mroche/Plex-Meta-Manager/config/config.yml as config
...
| Connecting to TMDb...
| TMDb Connection Successful
...
| Connecting to Plex Libraries...
...
| Connecting to Movies-HIDDEN Library...
| Plex Error: Plex Library Movies-HIDDEN not found
| Movies-HIDDEN Library Connection Failed
...
```
You can see there that PMM found its config file, was able to connect to TMDb, was able to connect to Plex, and then failed trying to read the “Movies-HIDDEN” library, which of course doesnt exist.
Open the config file again and change "Movies-HIDDEN" [or whatever you used in the previous step] to reflect your Plex. Also fix the name of the config file to match the library. Then delete any lines that start with “git”. Those are all sets of collections, and we just want to create a few as examples.
My Movies library is called “Main Movies", so mine looks like this:
```
libraries: # Library mappings must have a colon (:) placed after them
Main Movies:
metadata_path:
- file: config/Main Movies.yml # You have to create this file the other are online
```
NOTE: the matching naming of Library and YML is not actually required, I'm doing it here for clarity.
Save the file and run the script again:
```
python plex_meta_manager.py -r
```
Now youll see some more activity in the Plex connection section:
```
$ python plex_meta_manager.py -r
...
| Connecting to Plex Libraries...
...
| Connecting to Main Movies Library...
...
| Loading Metadata File: config/Main Movies.yml
|
| YAML Error: File Error: File does not exist config/Main Movies.yml
...
| Metadata File Error: No valid metadata files found
|
| Main Movies Library Connection Failed
...
```
We can see there that it connected to the Plex Library, failed to find that `Main Movies.yml` metadata file, and then quit.
So far so good.
### Setting up a metadata file and creating a few sample collections.
Now we have to set up that metadata file that PMM just complained about.
This metadata file contains definitions of the actions you want PMM to take. You can find lots of examples [here](https://github.com/meisnate12/Plex-Meta-Manager-Configs):
For now were going to create a few collections so you can watch the process work, then youre on your own to create whatever others you want.
First, open the metadata file [this will create the file if it doesn't already exist]:
<details>
<summary>OS X/Linux</summary>
<br />
```
nano "config\Main Movies.yml"
```
</details>
<details>
<summary>Windows</summary>
<br />
```
notepad "config\Main Movies.yml"
```
</details>
[of course, that should be the file name you just entered in config.yml, if you changed it from the default]
In this file, add the following, exactly as it is shown here:
```
templates:
Actor:
actor: tmdb
tmdb_person: <<person>>
tmdb_actor_details: <<person>>
sort_title: +_<<collection_name>>
sync_mode: sync
collection_order: release
collection_mode: hide
collections:
Bill Murray:
template: {name: Actor, person: 1532}
Best of the 1980s:
tmdb_discover:
primary_release_date.gte: 01/01/1980
primary_release_date.lte: 12/31/1989
with_original_language: en
sort_by: popularity.desc
limit: 100
summary: A collection of the Top Content of the 1980s
Vultures 101 Best Movie Endings:
letterboxd_list: https://letterboxd.com/brianformo/list/vultures-101-best-movie-endings/
```
I chose a letterboxd list for the last one since trakt requires authentication and again, I didnt want to complicate this walkthrough.
This is going to create three collections. One contains movies that feature Bill Murray. One is up to 100 movies that came out in the 1980s sorted by popularity. The last are movies that appear on a list of good endings according to Vulture.
The first one is based on a template, so if you wanted to create a collection for another actor you just have to copy and edit those two lines [the ID comes from TMDb]. All the other config details come from the template.
```
Amy Adams:
template: {name: Actor, person: 9273}
```
Save the file and run the script again.
```
python plex_meta_manager.py -r
```
This time you should see that the metadata file gets loaded:
```
| Loading Metadata File: config/Movies.yml
| Metadata File Loaded Successfully
```
And this time it will catalog all your movies. This could take a while depending on how many movies are in that library.
Once this cataloging is complete it will move on to build those three collections.
As it builds the collections, you should see a fair amount of logging about which movies are being added and which ones arent found. Once it completes, go to Plex, go to your Movies library, and click “Collections” at the top.
![Finished Collections](finished.png)
When you click into each, youll see the movies that PMM added to each collection.
Each time you run the script, new movies that match the collection definition will be added. For example, if you dont have “The Razors Edge” now, when you download it and run PMM again it will be added to the Bill Murray collection.
If you download any of the missing 22 movies on the Vulture list, running PMM would add them to that collection. And so on.
What comes next:
Delete these three collections if you want, from both Plex and the metadata file. If you add that “git” line you removed back into the config file:
```
- git: meisnate12/MovieCharts
```
then run PMM again, the script will add a whole bunch of new collections [which are defined in that file] you may be interested in.
That line is a link into the github repo of examples I referred to above, so you can review what it contains there. You can also add others from that repo using this same pattern.
If you prefer to create your own, do that in the metadata file.
TV Shows and other libraries work the same way. Create a section under `Libraries:` in the config.yml, create a metadata file, define collections, run the script.
Investigate the rest of the wiki to learn about everything else Plex-Meta-Manager can do for you.
When you are done, deactivate the virtual environment:
```
deactivate
```
## Advanced Topics
### I want to use this in a context where I can't be manually activating/deactivating the virtual environment [scheduled. etc]
All you need do is point to the python executable inside the virtual env. In our example, that means that if your scheduled job normally would be:
```
cd /Users/mroche/Plex-Meta-Manager
python plex-meta-manager.py -r
```
You would instead use:
```
cd /Users/mroche/Plex-Meta-Manager
pmm-venv/bin/python plex-meta-manager.py -r
```
On Windows that path is:
```
cd C:\Users\mroche\Plex-Meta-Manager
pmm-venv\Scripts\python.exe plex-meta-manager.py -r
```
### I want to update to the latest version of the code
<details>
<summary>OS X/Linux</summary>
<br />
```
cd /Users/mroche/Plex-Meta-Manager
git pull
source pmm-venv/bin/activate
python -m pip install -r requirements.txt
```
</details>
<details>
<summary>Windows</summary>
<br />
```
cd C:\Users\mroche\Plex-Meta-Manager
git pull
.\pmm-venv\Scripts\activate
python -m pip install -r requirements.txt
```
</details>
You're set to go.
### I want to use the develop branch
<details>
<summary>OS X/Linux</summary>
<br />
```
cd /Users/mroche/Plex-Meta-Manager
git checkout develop
source pmm-venv/bin/activate
python -m pip install -r requirements.txt
```
</details>
<details>
<summary>Windows</summary>
<br />
```
cd C:\Users\mroche\Plex-Meta-Manager
git checkout develop
.\pmm-venv\Scripts\activate
python -m pip install -r requirements.txt
```
</details>
You can switch back to the `master` branch by changing `develop` to `master`.
The reinstall of requirements every time is probably overkill, but it's harmless and ensures that you always get any new versions or new requirements.

@ -0,0 +1,387 @@
# Scheduling Guide
Plex Meta Manager is designed to be a background running service that "wakes up" and "sleeps" when it is scheduled to do so. By default and unless configured using the [Time to Run Command](../environmental.md#time-to-run), Plex Meta Manager expects to run every day at 3AM local time.
Whilst it is possible to have `python plex-meta-manager.py` running in an open window constantly, this is not the recommended approach as it relies on an always-open command window that can be obtrusive to the user.
Instead, it is recommended to set an automated scheduling service so that Plex Meta Manager can run in the background when scheduled to without any visible impact to the user (other than the Plex libraries and playlists updating).
## Docker Run
<details>
<summary>Click to Expand</summary>
<br />
Using docker is the simplest and most robust solution to automating Plex Meta Manager scheduling.
When running Plex Meta Manager within docker, the session will resume after a system reboot (assuming Docker is set to start at system startup, which is the default) and Plex Meta Manager will run in the background at all times.
There's a [Docker Walkthrough](docker) with more detailed instructions on setting up Plex Meta Manager within docker. The simplest command to facilitate a docker run is:
```
docker run -d \
--restart=unless-stopped \
-v /path/to/config:/config:rw \
meisnate12/plex-meta-manager
```
This will run Plex Meta Manager in the background persistently until it is stopped by the user. While the docker container will be persistently running, Plex Meta Manager will not begin the run until the scheduled time.
Further customizations of the docker run command can be used to specify set times to run Plex Meta Manager, further information on this and other Run Commands can be found [here](../environmental.md#time-to-run)
</details>
## Windows
<details>
<summary>Click to Expand</summary>
<br />
### Task Scheduler
Windows Task Scheduler is advised for those who followed the Windows instructions in the [Local Walkthrough Guides](local) and/or do not want to run Plex Meta Manager within docker.
Windows Task Scheduler allows the user to run commands and services at scheduled times and intervals.
There are two methods of running Plex Meta Manager:
* Single run Scheduled Task
* Background run Scheduled Task
These will be explained further down this page.
These guides assume the user has followed the Windows instructions in the [Local Walkthrough Guides](local) which includes setting up the [virtual environment](local.md#setting-up-a-virtual-environment). Please also ensure to edit any commands to be reflective of the live environment (such as usernames, installation directories).
### Background Run Scheduled Task
This method will start Plex Meta Manager at system startup and will keep the script running in the background indefinitely. The user can then define set days and times for the Configuration File to be processed, and Plex Meta Manager will handle processing as and when required.
This is the recommended approach as it allows the user additional control over how and when Plex Meta Manager processes.
<details>
<summary>Background Run Scheduled Task</summary>
<br />
1. Create a `waiter.cmd` file by opening the text editor (i.e. Notepad, TextEdit) and pasting the following code:
```batch
cd C:\User\USERNAMEHERE\Plex-Meta-Manager
.\pmm-venv\Scripts\python .\plex_meta_manager.py
```
* This will navigate to the PMM directory, then run PMM. At the scheduled time [as defined within Plex Meta Manager], PMM will process the Configuration File and will then wait until the next scheduled time.
1. Open Task Scheduler by searching for it in the Start Menu or by opening the Run window (Windows + R) and typing taskschd.msc before hitting OK.
* ** Ensure that Task Scheduler is opened and not Task Manager **
![task-scheduler](task-scheduler/02-open-task-scheduler.png)
3. Select "Create a basic task" on the right-hand column
![task-scheduler](task-scheduler/03-task-scheduler-main.png)
4. Give the task a name, in this example `Background PMM` and then select "Next"
![task-scheduler](task-scheduler/06-basic-task-02.png)
5. Choose the frequency that PMM should run and then select "Next", `When the computer starts` is recommended.
![task-scheduler](task-scheduler/06-basic-task-03.png)
6. Choose the action "Start a program" and select "Next".
![task-scheduler](task-scheduler/06-basic-task-04.png)
7. Click "Browse", Navigate to the PMM directory and choose `waiter.cmd`, which was created in Step 1, then select "Open".
![task-scheduler](task-scheduler/06-basic-task-05.png)
8. Copy the directory everything up to but not including `runner.cmd` from the "Program/Script" field, and paste it into the "Start in" field. This is `C:\User\IEUser\Plex-Meta-Manager-1.15.1` in the example below, then select "next".
![task-scheduler](task-scheduler/04-basic-task-06.png)
9. Check "Open the properties dialog" if desired (not required) then select "Finish".
![task-scheduler](task-scheduler/04-basic-task-07.png)
10. Click "Task Schedule Library" on the left. The PMM Run task should be visible.
![task-scheduler](task-scheduler/04-basic-task-09.png)
Plex Meta Manager will now launch at system startup, but will wait until the user-specified scheduled time before executing, and will then wait in the background for the next scheduled run.
</details>
### Single Run Scheduled Task
This method will start Plex Meta Manager at the desired time, immediately begin running the Configuration File and will then kill the process once it has completed.
<details>
<summary>Single Run Scheduled Task</summary>
<br />
1. Create a `runner.cmd` file by opening the text editor (i.e. Notepad, TextEdit) and pasting the following code:
```batch
cd C:\Users\USERNAMEHERE\Plex-Meta-Manager
.\pmm-venv\Scripts\python .\plex_meta_manager.py --run
```
* This will navigate to the PMM directory, then launch PMM using the `-r`/`--run` flag which triggers an immediate run. Once complete, Plex Meta Manager will exit.
Save this file to C:\Users\USERNAMEHERE\Plex-Meta-Manager\runner.cmd`.
2. Open Task Scheduler by searching for it in the Start Menu or by opening the Run window (Windows + R) and typing taskschd.msc before hitting OK.
* ** Ensure that Task Scheduler is opened and not Task Manager **
![task-scheduler](task-scheduler/02-open-task-scheduler.png)
3. Select "Create a basic task" on the right-hand column
![task-scheduler](task-scheduler/03-task-scheduler-main.png)
4. Give the task a name, in this example `Run PMM` and then select "Next"
![task-scheduler](task-scheduler/04-basic-task-01.png)
5. Choose the frequency that PMM should run and then select "Next", `Daily` is recommended.
![task-scheduler](task-scheduler/04-basic-task-02.png)
6. Specify the first date and time at which PMM should run and then select "Next".
![task-scheduler](task-scheduler/04-basic-task-03.png)
7. Choose the action "Start a program" and select "Next".
![task-scheduler](task-scheduler/04-basic-task-04.png)
8. Click "Browse", Navigate to the PMM directory and choose `runner.cmd`, which was created in Step 1, then select "Open".
![task-scheduler](task-scheduler/04-basic-task-05.png)
9. Copy the directory everything up to but not including `runner.cmd` from the "Program/Script" field, and paste it into the "Start in" field. This is `C:\User\IEUser\Plex-Meta-Manager-1.15.1` in the example below, then select "next".
![task-scheduler](task-scheduler/04-basic-task-06.png)
10. Check "Open the properties dialog" if desired (not required) then select "Finish".
![task-scheduler](task-scheduler/04-basic-task-07.png)
11. Click "Task Schedule Library" on the left. The PMM Run task should be visible.
![task-scheduler](task-scheduler/04-basic-task-09.png)
Plex Meta Manager will now run at the set date/time you selected in Step 6, and will run each subsequent day at the same time.
</details><br />
</details>
## MacOS
<details>
<summary>Click to Expand</summary>
<br />
<br />
<details>
<summary>Launchd Service</summary>
<br />
1. Create launchd service:
A couple examples; you'll want to edit the THINGS IN ALL CAPS to reflect your system.
Keep PMM running constantly, let it wait to do its thing at 3AM:
```
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.YOUR_USERNAME.plex-meta-manager</string>
<key>ProgramArguments</key>
<array>
<string>sh</string>
<string>-c</string>
<string>pmm-venv/bin/python plex-meta-manager.py --config /PATH/TO/PMM/config/config.yml</string>
</array>
<key>UserName</key>
<string>YOUR_USERNAME</string>
<key>WorkingDirectory</key>
<string>/PATH/TO/PMM</string>
</dict>
</plist>
```
Run PMM every 6 hours, running it immediately and letting it quit:
```
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.YOUR_USERNAME.plex-meta-manager</string>
<key>ProgramArguments</key>
<array>
<string>sh</string>
<string>-c</string>
<string>pmm-venv/bin/python plex-meta-manager.py --config /PATH/TO/PMM/config/config.yml --run</string>
</array>
<key>StartCalendarInterval</key>
<array>
<dict>
<key>Hour</key>
<integer>6</integer>
</dict>
<dict>
<key>Hour</key>
<integer>12</integer>
</dict>
<dict>
<key>Hour</key>
<integer>18</integer>
</dict>
<dict>
<key>Hour</key>
<integer>24</integer>
</dict>
</array>
<key>UserName</key>
<string>YOUR_USERNAME</string>
<key>WorkingDirectory</key>
<string>/PATH/TO/PMM</string>
</dict>
</plist>
```
A useful tool to generate these plist files is [https://zerolaunched.herokuapp.com/](https://zerolaunched.herokuapp.com/)
Save this file as `com.YOUR_USERNAME.plex-meta-manager.plist` in `~/Library/LaunchAgents`.
2. Load and start the agent 🚀
Retrieve your user id with `id -u` in Terminal. You'll need it for the commands in this step.
Load the agent by executing the following commands:
```
cd ~/Library/LaunchAgents/
launchctl bootstrap gui/YOUR-USER-ID com.YOUR_USERNAME.plex-meta-manager.plist
```
And then kick-start it with:
```
launchctl kickstart -k gui/YOUR-USER-ID/com.YOUR_USERNAME.plex-meta-manager
```
Note that this command uses the *label*, not the plist filename. The -k options means that the service will first be killed, if running.
The agent should now be active and starting the program according to the schedule you set.
</details><br />
<details>
<summary>cron Schedule</summary>
<br />
See the cron section below.
</details><br />
</details>
## Linux
<details>
<summary>Click to Expand</summary>
<br />
<br />
<details>
<summary>cron Schedule</summary>
<br />
1. Decide when you want to run Plex Meta Manager
`cron` needs a specific syntax to express schedules. A cron schedule is something like "Every Tuesday at 4" or "5 minutes past every other hour".
You can generate the required line by checking boxes using something like [crontab-generator](https://crontab-generator.org/).
The command you use in crontab will probably be the command you use to run it on the command line.
A command you could use for this:
```
/path/to/plex-meta-manager/pmm-venv/bin/python /path/to/plex-meta-manager/plex_meta_manager.py --config /path/to/plex-meta-manager/config/config.yml --run
```
NOTE: This is assuming you created the `pmm-venv` virtual environment as described in the [Local Walkthrough](local)
2. Open the system crontab for editing:
```bash
sudo crontab -e
```
3. Paste in the crontab line you got from `crontab-generator`, or type in one of your own.
4. Save and close the file.
</details><br />
<details>
<summary>Systemctl Service</summary>
<br />
1. Create the service file:
```bash
sudo nano /etc/systemd/system/plex-meta-manager.service
```
Put the following into the file:
```
# /etc/systemd/system/plex-meta-manager.service
[Unit]
Description=Plex Meta Manager
After=network-online.target
[Service]
User=USER
Group=GROUP
Type=simple
Environment=LC_ALL=C.UTF-8
Environment=LANG=C.UTF-8
WorkingDirectory=/path/to/plex-meta-manager
ExecStart=/path/to/plex-meta-manager/pmm-venv/bin/python /path/to/plex-meta-manager/plex_meta_manager.py
Restart=always
RestartSec=10
[Install]
WantedBy=default.target
```
Change `USER` and `GROUP` to reflect your user and group.
Change `/path/to/plex-meta-manager` to reflect where you've installed Plex Meta Manager.
NOTE: This is assuming you created the `pmm-venv` virtual environment as described in the [Local Walkthrough](local)
Save and close the file.
2. Load and start the service
```shell
sudo systemctl daemon-reload
sudo systemctl start plex-meta-manager.service
```
3. You can check whether the service is running with:
```shell
sudo systemctl status plex-meta-manager.service
```
</details><br />
</details>

@ -0,0 +1,56 @@
# unRAID Walkthrough
Thankfully, getting Plex Meta Manager working on unRAID is a fairly simple task. unRAID works mostly with docker containers, so the pre-built container available on docker hub works perfectly with a little configuration.
To install a container from docker hub, you will need community applications - a very popular plugin for unRAID servers. If you don't already have this installed, you can install it [here](https://forums.unraid.net/topic/38582-plug-in-community-applications/)
## Basic Installation
1. Head to the `Apps` tab of unRAID (Community Applications), and search `plex-meta-manager` in the upper right search box. No results will show, because plex-meta-manager has not been added to community applications yet. No need to fear, however, because the pre-built docker container is on docker hub. Click `Click Here To Get More Results From DockerHub`.
2. Click the download icon on the `plex meta manager` container by `meisnate12`.
3. Create your [Docker values](../../home/environmental) using `Add another Path, Port, Variable, Label or Device`. Example config:
| Config Type | Name | Key | Value | Container Path | Host Path | Access Mode | Description |
|:------------|:--------------------|:--------------|:-------|:---------------|:--------------------------------------|:------------|:----------------------------------------------------|
| Variable | Time to Run | `PMM_TIME` | `6:00` | N/A | N/A | N/A | Time to update each day. Format: HH:MM |
| Variable | Divider Character | `PMM_DIVIDER` | `=` | N/A | N/A | N/A | The character that divides the sections |
| Variable | Screen Width | `PMM_WIDTH` | `100` | N/A | N/A | N/A | An integer between 90 and 300 |
| Path | Config Storage Path | N/A | N/A | `/config` | `/mnt/user/appdata/plex-meta-manager` | Read/Write | Translation from docker container path to host path |
* Full list of docker values can be found on the [Run Commands & Environmental Variables Page](../../home/environmental).
* If you wish to enable one-time [Run]([Run Commands & Environmental Variables Page](../environmental.md#run)), add `-r` to `Post Arguments` by enabling Advanced View in the top right of unRAID.
* The Image below shows the above values in the unRAID WebUI.
![unRAID WebUI](unraid-webui.png)
4. Hit `Apply`, and allow unRAID to download the docker container.
5. Navigate to the `Docker` tab in unRAID, and stop the `plex-meta-manager` container if it has auto-started.
6. Create `config.yml` and `library.yml` files as-per the [documentation](../../config/configuration) in the Host Path you set (/mnt/user/appdata/plex-meta-manager in the example)
7. Once finished, run the container. Voila! Logs are located in `yourhostpath/logs`.
## Advanced Installation (Authenticating Trakt or MyAnimeList)
Due to how unRAID handles docker containers, it can be a little confusing at first to enable Trakt, MyAnimeList, and other sources. At this time, these sources require you to follow through to a URL, and provide a code or link to Plex Meta Manager. unRAID doesn't have a built-in way to interact with the terminals of docker containers, so a workaround must be used:
1. Stop the Plex Meta Manager docker container if it's currently running.
2. Follow the instructions for either [Trakt](../../config/trakt) or [MyAnimeList](../../config/myanimelist), and add the relevant values to your `config.yml`
3. Edit the `Time to Run` variable to reflect a time that is NOT the current time. We don't want the script to be running right now. Set `Run` to `false` if you've chosen to add that variable. Then, start the container.
4. Click the Terminal button in the upper right corner of the unRAID WebUI (`>_`)
5. Run `docker exec -it plex-meta-manager /bin/bash`
Note: this name is case-sensitive. If this gives you an error like "Error: No such container: plex-meta-manager"; check the container config to see if you've named it something like "Plex-Meta-Manager", If that's the case, change the name in the command to match your container.
6. Run `ls` to make sure you're in the same directory as `plex_meta_manager.py`. If you don't see the script, run `cd /`
7. Run `python plex_meta_manager.py -r`, and watch as the script comes to life.
8. You'll now notice, as per the [configuration documentation](../../config/configuration) on these sources, the script will ask you to click a URL and return an input. Go ahead and do so in this terminal window.
9. Once finished, and the script succeeds in connecting to your source, press `Ctrl + C` to cancel the script - and close out of the terminal window. Go ahead and stop the docker container, restore your container settings to your original preferences (restore `Time to Run`), and start the container.

@ -0,0 +1,77 @@
# Installing Plex Meta Manager
## Install Walkthroughs
These installation overviews are aimed at users who have previous experience of installing services via command-line terminal commands. For those who need full installation walkthroughs, please refer to the following walkthrough guides:
* [Local Walkthrough](guides/local)
* [Docker Walkthrough](guides/docker)
* [unRAID Walkthrough](guides/unraid)
* [Kubernetes Walkthrough](guides/kubernetes)
## Local Install Overview
Plex Meta Manager is compatible with Python 3.7, 3.8 or 3.9 only. Later versions may function but are untested.
These are high-level steps which assume the user has knowledge of python and pip, and the general ability to troubleshoot issues. For a detailed step-by-step walkthrough, refer to the [Local Walkthrough](guides/local) guide.
1. Clone or [download and unzip](https://github.com/meisnate12/Plex-Meta-Manager/archive/refs/heads/master.zip) the repo.
```shell
git clone https://github.com/meisnate12/Plex-Meta-Manager
```
2. Install dependencies:
```shell
pip install -r requirements.txt
```
3. If the above command fails, run the following command:
```shell
pip install -r requirements.txt --ignore-installed
```
At this point Plex Meta Manager has been installed, and you can verify installation by running:
```shell
python plex_meta_manager.py
```
## Docker Install Overview
### Docker Run:
```shell
docker run -it -v <PATH_TO_CONFIG>:/config:rw meisnate12/plex-meta-manager
```
* The `-it` flag allows you to interact with the script when needed (such as for Trakt or MyAnimeList authentication).
* The `-v <PATH_TO_CONFIG>:/config:rw` flag mounts the location you choose as a persistent volume to store your files.
* Change `<PATH_TO_CONFIG>` to a folder where your config.yml and other files are.
* The docker image defaults to running the configuration file named `config.yml` which resides in your persistent volume.
* If your directory has spaces (such as "My Documents"), place quotation marks around your directory pathing as shown here: `-v "<PATH_TO_CONFIG>:/config:rw"`
Example Docker Run command:
```shell
docker run -it -v "X:\Media\Plex Meta Manager\config:/config:rw" meisnate12/plex-meta-manager
```
### Docker Compose:
Example Docker Compose file:
```yaml
version: "2.1"
services:
plex-meta-manager:
image: meisnate12/plex-meta-manager
container_name: plex-meta-manager
environment:
- TZ=TIMEZONE #optional
volumes:
- /path/to/config:/config
restart: unless-stopped
```
## Dockerfile
A `Dockerfile` is included within the GitHub repository for those who require it, although this is only suggested for those with knowledge of dockerfiles. The official Plex Meta Manager build is available on the [Dockerhub Website](https://hub.docker.com/r/meisnate12/plex-meta-manager).

@ -0,0 +1,144 @@
# <img width="80px" src="_static/pmm.png" alt="PMM"> Plex Meta Manager
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/meisnate12/Plex-Meta-Manager?style=plastic)](https://github.com/meisnate12/Plex-Meta-Manager/releases)
[![Docker Image Version (latest semver)](https://img.shields.io/docker/v/meisnate12/plex-meta-manager?label=docker&sort=semver&style=plastic)](https://hub.docker.com/r/meisnate12/plex-meta-manager)
[![Docker Pulls](https://img.shields.io/docker/pulls/meisnate12/plex-meta-manager?style=plastic)](https://hub.docker.com/r/meisnate12/plex-meta-manager)
[![GitHub commits since latest release (by SemVer)](https://img.shields.io/github/commits-since/meisnate12/plex-meta-manager/latest/develop?label=Commits%20in%20Develop&style=plastic)](https://github.com/meisnate12/Plex-Meta-Manager/tree/develop)
[![Discord](https://img.shields.io/discord/822460010649878528?label=Discord&style=plastic)](https://discord.gg/NfH6mGFuAB)
[![Docker Cloud Build Status](https://img.shields.io/docker/cloud/build/meisnate12/plex-meta-manager?style=plastic)](https://hub.docker.com/r/meisnate12/plex-meta-manager)
[![Read the Docs](https://img.shields.io/readthedocs/plex-meta-manager-wiki?style=plastic)](https://metamanager.wiki)
[![Sponsor or Donate](https://img.shields.io/badge/-Sponsor_or_Donate-blueviolet?style=plastic)](https://github.com/sponsors/meisnate12)
Plex Meta Manager is an open source Python 3 project that has been designed to ease the creation and maintenance of metadata, collections, and playlists within a Plex Media Server. The script is designed to be run continuously and be able to update information based on sources outside your plex environment. Plex Meta Manager supports Movie/TV/Music libraries and Playlists.
## Getting Started
1. Install Plex Meta Manager; this process is described [here](/home/installation).
2. Once installed, you have to create a [Configuration File](config/configuration), which contains URLs and credentials and the like which are used to connect to services like Plex and TMDB.
3. After that you can start updating Metadata and building automatic Collections by creating a [Metadata File](metadata/metadata) for each Library you want to interact with.
4. After that, explore the Wiki to see all the different Collection Builders that can be used to create collections.
## Walkthroughs
If you find steps 1-3 above daunting, there are some walkthroughs available that will take you through those three steps: getting Plex Meta Manager installed, creating a config file, and creating a couple collections to show how the process works.
1. The [Local Walkthrough](home/guides/local) covers installing the script natively [not in docker] on your local computer or a remote server.
2. The [Docker Walkthrough](home/guides/docker) covers the same thing, running the script via Docker.
3. The [unRAID Walkthrough](home/guides/unraid) gets you started configuring the script in UNRaid. It doesn't go through the same steps with regard to creating the config file and metadata file, so you may want to go through the [Docker Walkthrough](home/guides/docker) first on your computer to gain that understanding.
## Development & Nightly Builds
### Development
The [develop](https://github.com/meisnate12/Plex-Meta-Manager/tree/develop) branch has the most updated **documented** fixes and enhancements to Plex Meta Manager. This version is tested and documented to some degree, but it is still an active development branch, so there may be rough edges.
Switching to `develop`:
````{tab} if running in Docker
<br/>
Add ":develop" to the image name in your run command or configuration:
```
meisnate12/plex-meta-manager:develop
```
<br/>
````
````{tab} if running on the host:
In the directory where you cloned PMM:
```bash
git checkout develop
```
To switch back:
```bash
git checkout master
```
<br/>
````
If switching to the develop build, it is recommended to also use the [develop](https://metamanager.wiki/en/develop/) branch of the wiki, which documents any changes made from the Master build.
### Nightly
There is also a [nightly](https://github.com/meisnate12/Plex-Meta-Manager/tree/nightly) build which will have the absolute latest version of the script, but it could easily break, there is no guarantee that it even works, and any new features will not be documented.
Switching to `nightly`:
````{tab} if running in Docker
<br/>
Add ":nightly" to the image name in your run command or configuration:
```
meisnate12/plex-meta-manager:nightly
```
<br/>
````
````{tab} if running on the host:
In the directory where you cloned PMM:
```bash
git checkout nightly
```
To switch back:
```bash
git checkout master
```
<br/>
````
As this build is subject to extreme change, there is no nightly branch of the wiki and all discussions relating to changes made in the nightly build will be held within the [Plex Meta Manager Discord Server](https://discord.gg/NfH6mGFuAB).
## Example Usage
Plex Meta Manager gives the user the power to curate a set of Collections to make discovering and organizing media easy. They can be built either using plex-based searches/filters, or by using popular builders such as TMDb, IMDb, Trakt, MDBList, MyAnimeList and many more.
Some example collections that can be created are:
* Trending/Popular (based on TMDb, IMDb, Trakt, etc.)
* Streaming Service (such as Netflix, Disney+, etc.)
* Networks
* Studios
* Genres
* Actors
* Decades
Below are some user-curated collections which have been created by Plex Meta Manager.
![Movie Preview](home/movie-preview.png)
![Show Preview](home/show-preview.png)
To see user submitted Metadata configuration files, and you to even add your own, go to the [Plex Meta Manager Configs](https://github.com/meisnate12/Plex-Meta-Manager-Configs).
Plex Meta Manager can manage the metadata fields for movies, shows, seasons, episodes, artists, albums, tracks, and collections, which can allow you to have a full backup of your customizations in case of a database loss.
## Discord Support Server
Before posting on GitHub about an enhancement, error, or configuration question please visit the [Plex Meta Manager Discord Server](https://discord.gg/NfH6mGFuAB). we have a dedicated support thread system so that your query can be dealt with efficiently by our team and community.
## Feature Requests, Errors, and Configuration Questions
If you are unable to use the [Plex Meta Manager Discord Server](https://discord.gg/NfH6mGFuAB), please follow this guidance:
* If you have an idea for how to enhance Plex Meta Manager please open a new [Feature Request](https://github.com/meisnate12/Plex-Meta-Manager/issues/new?assignees=meisnate12&labels=status%3Anot-yet-viewed%2C+enhancement&template=feature_request.md&title=Feature+Request%3A+).
* If you're getting an Error please update to the latest version and then open a [Bug Report](https://github.com/meisnate12/Plex-Meta-Manager/issues/new?assignees=meisnate12&labels=status%3Anot-yet-viewed%2C+bug&template=bug_report.md&title=Bug%3A+) if the error persists.
* If you have a metadata configuration query please post in the [Discussions](https://github.com/meisnate12/Plex-Meta-Manager/discussions).
## Contributing
* Pull Requests are greatly encouraged, please submit all Pull Requests to the nightly branch.
* If you wish to contribute to the Wiki please fork and send a pull request on the [Plex Meta Manager Wiki Repository](https://github.com/meisnate12/Plex-Meta-Manager-Wiki).
## IBRACORP Video Walkthrough
[IBRACORP](https://ibracorp.io/) made a video walkthough for installing Plex Meta Manager on unRAID. While you might not be using unRAID the video goes over many key aspects of Plex Meta Manager and can be a great place to start learning how to use the script.
<div style="margin: 40px 0 40px 0;" align="center">
<iframe width="560" height="315" src="https://www.youtube.com/embed/dF69MNoot3w" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>

@ -0,0 +1,35 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd

@ -0,0 +1,89 @@
# AniDB Builders
You can find anime using the features of [AniDB.net](https://anidb.net/) (AniDB).
No configuration is required for these builders.
| Attribute | Description | Works with Movies | Works with Shows | Works with Playlists and Custom Sort |
|:------------------------------------|:-----------------------------------------------------------------------------------------------|:-----------------:|:----------------:|:------------------------------------:|
| [`anidb_id`](#anidb-id) | Finds the anime specified by the AniDB ID | &#9989; | &#9989; | &#10060; |
| [`anidb_relation`](#anidb-relation) | Finds all anime in the relation graph of the specified AniDB ID | &#9989; | &#9989; | &#10060; |
| [`anidb_popular`](#anidb-popular) | Finds every anime in AniDB's [Popular Anime](https://anidb.net/latest/anime/popular/?h=1) list | &#9989; | &#9989; | &#9989; |
| [`anidb_tags`](#anidb-tag) | Finds every anime in a AniDB Tag | &#9989; | &#9989; | &#10060; |
## AniDB ID
Finds the anime specified by the AniDB ID.
The expected input is an AniDB ID or AniDB Anime URL. Multiple values are supported as either a list or a comma-separated string.
```yaml
collections:
Sword Art Online Shows:
anidb_id: 8692, 8691, 13494
```
```yaml
collections:
Sword Art Online Shows:
anidb_id: https://anidb.net/anime/8692, https://anidb.net/anime/8691, https://anidb.net/anime/13494
```
## AniDB Relation
Finds all anime in the relation graph of the specified AniDB ID.
To see the relation graph of an anime use: `https://anidb.net/anime/<ANIDB_ID>/relation/graph` but replace `<ANIDB_ID>` with the AniDB ID you want to see the relations for.
The expected input is an AniDB ID, AniDB Anime URL, or AniDB Anime Relation URL. Multiple values are supported as either a list or a comma-separated string.
```yaml
collections:
All Sword Art Online:
anidb_relation: 8692
```
```yaml
collections:
All Sword Art Online:
anidb_relation: https://anidb.net/anime/8692
```
```yaml
collections:
All Sword Art Online:
anidb_relation: https://anidb.net/anime/8692/relation/graph
```
## AniDB Popular
Finds every anime in AniDB's [Popular Anime](https://anidb.net/latest/anime/popular/?h=1) list.
The expected input is a single integer value of how much anime to query with a max of 30.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
AniDB Popular:
anidb_popular: 30
collection_order: custom
sync_mode: sync
```
## AniDB Tag
Finds anime with the specified AniDB Tag the options are detailed below.
| Attribute | Description | Required | Default |
|:----------|:--------------------------------------------------------------|:--------:|:-------:|
| `tag` | AniDB Tag ID to search by | &#9989; | N/A |
| `limit` | Number of Anime to query from AniDB (use 0 for all; max: 500) | &#10060; | 0 |
```yaml
collections:
Pirates Anime:
anidb_tag:
tag: 1700
limit: 500
sync_mode: sync
```
* To find possible tags go to the [AniDB Anime](https://anidb.net/tag) page to find the tags available. Copy the link and find the tag ID at the end of the url.

@ -0,0 +1,231 @@
# AniList Builders
You can find anime using the features of [AniList.co](https://anilist.co/) (AniList).
No configuration is required for these builders.
| Attribute | Description | Works with Movies | Works with Shows | Works with Playlists and Custom Sort |
|:------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------|:-----------------:|:----------------:|:------------------------------------:|
| [`anilist_top_rated`](#anilist-top-rated-anime) | Finds every anime in AniList's [Top Rated Anime](https://anilist.co/search/anime?sort=SCORE_DESC) list | &#9989; | &#9989; | &#9989; |
| [`anilist_popular`](#anilist-popular-anime) | Finds every anime in AniList's [Popular Anime](https://anilist.co/search/anime/popular) list | &#9989; | &#9989; | &#9989; |
| [`anilist_trending`](#anilist-trending-anime) | Finds every anime in AniList's [Trending Anime](https://anilist.co/search/anime/trending) list | &#9989; | &#9989; | &#9989; |
| [`anilist_relations`](#anilist-relations) | Finds the anime specified by the AniList ID and every relation in its relation tree except Character and Other relations | &#9989; | &#9989; | &#10060; |
| [`anilist_studio`](#anilist-studio) | Finds all anime specified by the AniList Studio ID | &#9989; | &#9989; | &#10060; |
| [`anilist_id`](#anilist-id) | Finds the anime specified by the AniList ID | &#9989; | &#9989; | &#10060; |
| [`anilist_search`](#anilist-search) | Finds the anime specified by the AniList search parameters provided | &#9989; | &#9989; | &#9989; |
## AniList Top Rated Anime
Finds every anime in AniList's [Top Rated Anime](https://anilist.co/search/anime?sort=SCORE_DESC) list.
The expected input is a single integer value of how many movies/shows to query.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Top Rated Anime:
anilist_top_rated: 30
collection_order: custom
sync_mode: sync
```
## AniList Popular Anime
Finds every anime in AniList's [Popular Anime](https://anilist.co/search/anime/popular) list.
The expected input is a single integer value of how many movies/shows to query.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Popular Anime:
anilist_popular: 10
collection_order: custom
sync_mode: sync
```
## AniList Trending Anime
Finds every anime in AniList's [Trending Anime](https://anilist.co/search/anime/trending) list.
The expected input is a single integer value of how many movies/shows to query.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Trending Anime:
anilist_trending: 10
collection_order: custom
sync_mode: sync
```
## AniList Relations
Finds the anime specified by the AniList ID and every relation in its relation tree except Character and Other relations.
The expected input is an AniList ID. Multiple values are supported as either a list or a comma-separated string.
```yaml
collections:
One Piece:
anilist_relations: 21
```
## AniList Studio
Finds all anime specified by the AniList Studio ID.
The expected input is an AniList ID. Multiple values are supported as either a list or a comma-separated string.
```yaml
collections:
Studio Ghibli:
anilist_studio: 21
```
## AniList ID
Finds the anime specified by the AniList ID.
The expected input is an AniList ID. Multiple values are supported as either a list or a comma-separated string.
```yaml
collections:
Cowboy Bebop:
anilist_id: 23, 219
```
## AniList Search
Finds the anime specified by the AniList Search the options are detailed below.
There are three fields per search option when using AniList's Search just like Plex's Advanced Filters in the Web UI. The first is the **Attribute** (what attribute you wish to search), the second is the **Modifier** (which modifier to use), and the third is the **Term** (actual term to search).
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
## Special Attributes
Special attributes do not support any modifiers.
| Special Attribute | Description & Values |
|:------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `sort_by` | **Description:** How to sort the Anime<br>**Default:** `score`<br>**Values:**<table class="clearTable"><tr><td>`score`</td><td>Sort by Average Score</td></tr><tr><td>`popular`</td><td>Sort by Popularity</td></tr><tr><td>`trending`</td><td>Sort by Trending</td></tr></table> |
| `limit` | **Description:** Number of Anime to query<br>**Values:** Number greater or equal to 0` (use 0 or don't use it at all for all anime)<br>**Default:** `0` |
| `search` | **Description:** Text to search<br>**Values:** Any Text |
| `season` | **Description:** Season to search for<br>**Default:** `current`<br>**Values:** <table class="clearTable"><tr><td>`winter`</td><td>For winter season December, January, February</td></tr><tr><td>`spring`</td><td>For spring season March, April, May</td></tr><tr><td>`summer`</td><td>For summer season June, July, August</td></tr><tr><td>`fall`</td><td>For fall season September, October, November</td></tr><tr><td>`current`</td><td>For current Season</td></tr></table> |
| `year` | **Description:** Season year to search for<br>**Default:** Current Year<br>**Values:** Number between `1917` and next year or leave blank for the current year |
| `min_tag_percent` | **Description:** Minimum tag percentage for the Anime<br>**Values:** Number between `0`-`100` |
| `adult` | **Description:** Search for or not for Adult Anime<br>**Values:** `true` or `false` |
| `country` | **Description:** Search for anime from a specific country<br>**Values:** [ISO 3166-1 alpha-2 country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) |
| `source` | **Description:** Uses the anime's source to match<br>**Values:** `original`, `manga`, `light_novel`, `visual_novel`, `video_game`, `other`, `novel`, `doujinshi`, or `anime` |
## Tag Attributes
Tag attributes can be used with either no modifier or with `.not`.
String attributes can take multiple values as a **list or a comma-separated string**.
### Tag Modifiers
| Tag Modifier | Description |
|:-------------|:-----------------------------------------------------------------------|
| No Modifier | Matches every item where the attribute matches the given string |
| `.not` | Matches every item where the attribute does not match the given string |
### Tag Attributes
| Tag Attribute | Description & Values |
|:---------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `format` | **Description:** Uses the anime's format to match<br>**Values:** `tv`, `short`, `movie`, `special`, `ova`, `ona`, `music` |
| `status` | **Description:** Uses the anime's status to match<br>**Values:** `finished`, `airing`, `not_yet_aired`, `cancelled`, `hiatus` |
| `genre` | **Description:** Uses the anime's genre to match<br>**Values:** Any Genre in the Genre Dropdown box on the [AniList Search Page](https://anilist.co/search/anime) |
| `tag` | **Description:** Uses the anime's tag to match<br>**Values:** Any Tag in the Genre Dropdown box on the [AniList Search Page](https://anilist.co/search/anime) |
| `tag_category` | **Description:** Uses the anime's tag category to match<br>**Values:** Any Tag Category in the Advanced Genres & Tag Filters Menu on the [AniList Search Page](https://anilist.co/search/anime) |
## Date Attributes
Date attributes can be used with either `.before`, or `.after`.
No date attribute can take multiple values.
### Date Modifiers
| Date Modifier | Description |
|:--------------|:-----------------------------------------------------------------------------------------------------------------|
| `.before` | Matches every item where the date attribute is before the given date<br>**Format:** MM/DD/YYYY e.g. `01/01/2000` |
| `.after` | Matches every item where the date attribute is after the given date<br>**Format:** MM/DD/YYYY e.g. `01/01/2000` |
### Date Attributes
| Date Attributes | Description |
|:----------------|:---------------------------------------------|
| `start` | Uses the anime start date attribute to match |
| `end` | Uses the anime end date attribute to match |
## Number Searches
Number attributes must use `.gt`, `.gte`, `.lt`, or `.lte` as a modifier.
No number attribute can take multiple values.
### Number Modifiers
| Number Modifier | Description |
|:----------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------|
| `.gt` | Matches every item where the number attribute is greater then the given number<br>**Format:** number<br>**Example:** `30`, `1995`, or `7.5` |
| `.gte` | Matches every item where the number attribute is greater then or equal to the given number<br>**Format:** number<br>**Example:** `30`, `1995`, or `7.5` |
| `.lt` | Matches every item where the number attribute is less then the given number<br>**Format:** number<br>**Example:** `30`, `1995`, or `7.5` |
| `.lte` | Matches every item where the number attribute is less then or equal to the given number<br>**Format:** number<br>**Example:** `30`, `1995`, or `7.5` |
### Number Attributes
| Number Attribute | Description |
|:-----------------|:------------------------------------------------------------------------------------------------------|
| `duration` | **Description:** Uses the duration attribute to match using minutes<br>**Restrictions:** minimum: `1` |
| `episodes` | **Description:** Uses the number of episodes attribute to match<br>**Restrictions:** minimum: `1` |
| `score` | **Description:** Uses the score attribute to match<br>**Restrictions:** minimum: `1` |
| `popularity` | **Description:** Uses the popularity attribute to match<br>**Restrictions:** minimum: `1` |
## AniList Search Examples
```yaml
collections:
Current Anime Season:
anilist_search:
season:
year:
sort_by: popular
collection_order: custom
sync_mode: sync
```
```yaml
collections:
Fall 2020 Anime:
anilist_search:
season: fall
year: 2020
collection_order: custom
sync_mode: sync
```
```yaml
collections:
Pirates Anime:
anilist_search:
tag: Pirates
sort_by: popular
collection_order: custom
sync_mode: sync
```
```yaml
collections:
Top Sports Anime:
anilist_genre:
genre: Sports
limit: 20
sort_by: popular
collection_order: custom
sync_mode: sync
```

@ -0,0 +1,119 @@
# FlixPatrol Builders
You can find items using the features of [FlixPatrol.com](https://flixpatrol.com/) (FlixPatrol).
No configuration is required for this builder.
| Attribute | Description | Works with Movies | Works with Shows | Works with Playlists and Custom Sort |
|:------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------:|:----------------:|:------------------------------------:|
| [`flixpatrol_top`](#flixpatrol-top-platform) | Finds every item from [FlixPatrol's Top Platform Lists](https://flixpatrol.com/top10/) based on the attributes provided. | &#9989; | &#9989; | &#9989; |
| [`flixpatrol_popular`](#flixpatrol-popular) | Finds every movie/show from FlixPatrol's Popular [Movies](https://flixpatrol.com/popular/movies/)/[Shows](https://flixpatrol.com/popular/tv-shows/) Lists based on the attributes provided. | &#9989; | &#9989; | &#9989; |
| [`flixpatrol_demographics`](#flixpatrol-demographics) | Finds every item from [FlixPatrol's Demographics Lists](https://flixpatrol.com/demographics/) based on the attributes provided. | &#9989; | &#9989; | &#9989; |
| [`flixpatrol_url`](#flixpatrol-url) | Finds every item found at a FlixPatrol URL. | &#9989; | &#9989; | &#9989; |
## FlixPatrol Top Platform
Finds every item from [FlixPatrol's Top Platform Lists](https://flixpatrol.com/top10/) based on the attributes provided.
The only required attribute is `platform`.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
### Top Platform Attributes
| Attribute | Description & Values |
|:--------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `platform` | **Description:** Streaming Platform to filter on.<br>**Values:** `netflix`, `hbo`, `disney`, `amazon`, `itunes`, `google`, `paramount_plus`, `hulu`, `vudu`, `imdb`, `amazon_prime`, `star_plus` |
| `location` | **Description:** Location to filter on.<br>**Default:** `world`<br>**Values:** `world`, `albania`, `argentina`, `armenia`, `australia`, `austria`, `azerbaijan`, `bahamas`, `bahrain`, `bangladesh`, `belarus`, `belgium`, `belize`, `benin`, `bolivia`, `bosnia_and_herzegovina`, `botswana`, `brazil`, `bulgaria`, `burkina_faso`, `cambodia`, `canada`, `chile`, `colombia`, `costa_rica`, `croatia`, `cyprus`, `czech_republic`, `denmark`, `dominican_republic`, `ecuador`, `egypt`, `estonia`, `finland`, `france`, `gabon`, `germany`, `ghana`, `greece`, `guatemala`, `guinea_bissau`, `haiti`, `honduras`, `hong_kong`, `hungary`, `iceland`, `india`, `indonesia`, `ireland`, `israel`, `italy`, `ivory_coast`, `jamaica`, `japan`, `jordan`, `kazakhstan`, `kenya`, `kuwait`, `kyrgyzstan`, `laos`, `latvia`, `lebanon`, `lithuania`, `luxembourg`, `malaysia`, `maldives`, `mali`, `malta`, `mexico`, `moldova`, `mongolia`, `montenegro`, `morocco`, `mozambique`, `namibia`, `netherlands`, `new_zealand`, `nicaragua`, `niger`, `nigeria`, `north_macedonia`, `norway`, `oman`, `pakistan`, `panama`, `papua_new_guinea`, `paraguay`, `peru`, `philippines`, `poland`, `portugal`, `qatar`, `romania`, `russia`, `rwanda`, `salvador`, `saudi_arabia`, `senegal`, `serbia`, `singapore`, `slovakia`, `slovenia`, `south_africa`, `south_korea`, `spain`, `sri_lanka`, `sweden`, `switzerland`, `taiwan`, `tajikistan`, `tanzania`, `thailand`, `togo`, `trinidad_and_tobago`, `turkey`, `turkmenistan`, `uganda`, `ukraine`, `united_arab_emirates`, `united_kingdom`, `united_states`, `uruguay`, `uzbekistan`, `venezuela`, `vietnam`, `zambia`, `zimbabwe` |
| `time_window` | **Description:** Time window to filter on.<br>**Default:** `today`<br>**Values:** `today`, `yesterday`,`this_week`, `last_week`, `this_month`, `last_month`, `this_year`, `last_year` |
| `limit` | **Description:** Number of items to return.<br>**Default:** `10`<br>**Values:** Integer greater then 0 |
```yaml
collections:
US Netflix Monthly Top 20:
flixpatrol_top:
platform: netflix
location: united_states
time_window: this_month
limit: 20
collection_order: custom
sync_mode: sync
```
## FlixPatrol Popular
Finds every movie/show from FlixPatrol's Popular [Movies](https://flixpatrol.com/popular/movies/)/[Shows](https://flixpatrol.com/popular/tv-shows/) Lists based on the attributes provided.
The only required attribute is `source`.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
### Popular Attributes
| Attribute | Description |
|:--------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `source` | **Description:** Source to filter on.<br>**Values:** `movie_db`, `facebook`, `google`, `twitter`, `twitter_trends`, `instagram`, `instagram_trends`, `youtube`, `imdb`, `letterboxd`, `rotten_tomatoes`, `tmdb`, `trakt` |
| `time_window` | **Description:** Time window to filter on.<br>**Default:** `today`<br>**Values:** `today`, `yesterday`,`this_week`, `last_week`, `this_month`, `last_month`, `this_year`, `last_year` |
| `limit` | **Description:** Number of items to return.<br>**Default:** `10`<br>**Values:** Integer greater then 0 |
```yaml
collections:
Instagram Popular:
flixpatrol_popular:
source: instagram
time_window: all
limit: 20
collection_order: custom
sync_mode: sync
```
## FlixPatrol Demographics
Finds every item from [FlixPatrol's Demographics Lists](https://flixpatrol.com/demographics/) based on the attributes provided.
The only required attribute is `generation`.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
### Demographics Attribute
| Attribute | Description |
|:-------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `generation` | Generation to filter on.<br>**Values:** `all`, `boomers`, `x`, `y`, `z` |
| `gender` | Gender to filter on.<br>**Default:** `all`<br>**Values:** `all`, `men`, `women` |
| `location` | Location to filter on.<br>**Default:** `world`<br>**Values:** `world`, `brazil`, `canada`, `france`, `germany`, `india`, `mexico`, `united_kingdom`, `united_states` |
| `limit` | Number of items to return.<br>**Default:** `10`<br>**Values:** Integer greater then 0 |
```yaml
collections:
Gen X Male US Demographic:
flixpatrol_demographics:
generation: x
gender: men
location: united_states
limit: 20
collection_order: custom
sync_mode: sync
```
## FlixPatrol URL
Finds every item found at a FlixPatrol URL.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
US Netflix Monthly:
flixpatrol_url: https://flixpatrol.com/top10/netflix/united-states/2021-11/full/
collection_order: custom
sync_mode: sync
Instagram Monthly Popular:
flixpatrol_url: https://flixpatrol.com/popular/movies/instagram/all-time/
collection_order: custom
sync_mode: sync
Gen X Male US Demographic:
flixpatrol_url: https://flixpatrol.com/demographics/generation-x/men/united-states/
collection_order: custom
sync_mode: sync
```

@ -0,0 +1,37 @@
# ICheckMovies Builders
You can find items using the lists on [icheckmovies.com](https://www.icheckmovies.com/) (ICheckMovies).
No configuration is required for these builders.
| Attribute | Description | Works with Movies | Works with Shows | Works with Playlists and Custom Sort |
|:--------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------|:-----------------:|:----------------:|:------------------------------------:|
| [`icheckmovies_list`](#icheckmovies-list) | Finds every movie in the ICheckMovies List | &#9989; | &#10060; | &#9989; |
| [`icheckmovies_list_details`](#icheckmovies-list) | Finds every movie in the ICheckMovies List and updates the collection with the description of the ICheckMovies list | &#9989; | &#10060; | &#9989; |
## ICheckMovies List
Finds every movie in the ICheckMovies List.
The expected input is a ICheckMovies List URL. Multiple values are supported as either a list or a comma-separated string.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Vultures 101 Best Movie Endings:
icheckmovies_list: https://www.icheckmovies.com/lists/academy+award+-+best+picture
collection_order: custom
sync_mode: sync
```
* You can update the collection details with the ICheckMovies List's description by using `icheckmovies_list_details`.
* You can specify multiple collections in `icheckmovies_list_details` but it will only use the first one to update the collection summary.
```yaml
collections:
Vultures 101 Best Movie Endings:
icheckmovies_list_details: https://www.icheckmovies.com/lists/academy+award+-+best+picture
collection_order: custom
sync_mode: sync
```

@ -0,0 +1,121 @@
# IMDb Builders
You can find items using the features of [IMDb.com](https://www.imdb.com/) (IMDb).
| Attribute | Description | Works with Movies | Works with Shows | Works with Playlists and Custom Sort |
|:----------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------:|:----------------:|:------------------------------------:|
| [`imdb_id`](#imdb-id) | Gets the movie/show specified. | &#9989; | &#9989; | &#10060; |
| [`imdb_chart`](#imdb-chart) | Gets every movie/show in an IMDb Chart like [IMDb Top 250 Movies](https://www.imdb.com/chart/top). | &#9989; | &#9989; | &#9989; |
| [`imdb_list`](#imdb-list) | Gets every movie/show in an IMDb List, [IMDb Keyword Search](https://www.imdb.com/search/keyword/), or [IMDb Search](https://www.imdb.com/search/title/). | &#9989; | &#9989; | &#9989; |
## IMDb ID
Gets the movie/show specified.
The expected input is an IMDb ID. Multiple values are supported as either a list or a comma-separated string.
```yaml
collections:
Star Wars (Animated Shows):
imdb_id: tt0458290, tt2930604
```
## IMDb Chart
Finds every item in an IMDb Chart.
The expected input are the options below. Multiple values are supported as either a list or a comma-separated string.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
| Name | Attribute | Works with Movies | Works with Shows |
|:-------------------------------------------------------------------------------|:-----------------|:-----------------:|:----------------:|
| [Box Office](https://www.imdb.com/chart/boxoffice) | `box_office` | &#9989; | &#10060; |
| [Most Popular Movies](https://www.imdb.com/chart/moviemeter) | `popular_movies` | &#9989; | &#10060; |
| [Top 250 Movies](https://www.imdb.com/chart/top) | `top_movies` | &#9989; | &#10060; |
| [Top Rated English Movies](https://www.imdb.com/chart/top-english-movies) | `top_english` | &#9989; | &#10060; |
| [Most Popular TV Shows](https://www.imdb.com/chart/tvmeter) | `popular_shows` | &#10060; | &#9989; |
| [Top 250 TV Shows](https://www.imdb.com/chart/toptv) | `top_shows` | &#10060; | &#9989; |
| [Top Rated Indian Movies](https://www.imdb.com/india/top-rated-indian-movies/) | `top_indian` | &#9989; | &#10060; |
| [Lowest Rated Movies](https://www.imdb.com/chart/bottom) | `lowest_rated` | &#9989; | &#10060; |
```yaml
collections:
IMDb Top 250:
imdb_chart: top_movies
collection_order: custom
sync_mode: sync
```
## IMDb List
Finds every item in an IMDb List, [IMDb Keyword Search](https://www.imdb.com/search/keyword/), or [IMDb Title Search](https://www.imdb.com/search/title/).
The expected input is an IMDb List URL or IMDb Search URL. Multiple values are supported as a list only a comma-separated string will not work.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
James Bonds:
imdb_list: https://www.imdb.com/list/ls006405458
collection_order: custom
sync_mode: sync
```
```yaml
collections:
IMDb Top 250:
imdb_list: https://www.imdb.com/search/title/?groups=top_250
collection_order: custom
sync_mode: sync
```
```yaml
collections:
Christmas:
imdb_list:
- https://www.imdb.com/list/ls025976544/
- https://www.imdb.com/list/ls003863000/
- https://www.imdb.com/list/ls027454200/
- https://www.imdb.com/list/ls027886673/
- https://www.imdb.com/list/ls097998599/
sync_mode: sync
collection_order: alpha
```
You can also limit the number of items to search for by using the `limit` and `url` parameters under `imdb_list`.
```yaml
collections:
IMDb Popular:
imdb_list:
url: https://www.imdb.com/search/title/?title_type=feature,tv_movie,documentary,short
limit: 50
collection_order: custom
sync_mode: sync
```
This can be used for multiple lists as seen below.
```yaml
collections:
Top Action:
imdb_list:
- url: https://www.imdb.com/search/title/?title_type=feature&release_date=1990-01-01,&user_rating=5.0,10.0&num_votes=100000,&genres=action
limit: 100
- url: https://www.imdb.com/search/title/?title_type=feature&release_date=1990-01-01,&user_rating=5.0,10.0&num_votes=100000,&genres=action&sort=user_rating,desc
limit: 100
```
You can also find episodes using `imdb_list` like so.
```yaml
collections:
The Simpsons Top 100 Episodes:
collection_order: custom
collection_level: episode
sync_mode: sync
imdb_list:
url: https://www.imdb.com/search/title/?series=tt0096697&sort=user_rating,desc
limit: 100
summary: The top 100 Simpsons episodes by IMDb user rating
```

@ -0,0 +1,37 @@
# Letterboxd Builders
You can find items using the lists on [Letterboxd.com](https://letterboxd.com/) (Letterboxd).
No configuration is required for these builders.
| Attribute | Description | Works with Movies | Works with Shows | Works with Playlists and Custom Sort |
|:----------------------------------------------|:----------------------------------------------------------------------------------------------------------------|:-----------------:|:-----------------:|:------------------------------------:|
| [`letterboxd_list`](#letterboxd-list) | Finds every movie in the Letterboxd List | &#9989; | &#10060; | &#9989; |
| [`letterboxd_list_details`](#letterboxd-list) | Finds every movie in the Letterboxd List and updates the collection with the description of the Letterboxd list | &#9989; | &#10060; | &#9989; |
## Letterboxd List
Finds every movie in the Letterboxd List.
The expected input is a Letterboxd List URL. Multiple values are supported as either a list or a comma-separated string.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Vultures 101 Best Movie Endings:
letterboxd_list: https://letterboxd.com/brianformo/list/vultures-101-best-movie-endings/
collection_order: custom
sync_mode: sync
```
* You can update the collection details with the Letterboxd List's description by using `letterboxd_list_details`.
* You can specify multiple collections in `letterboxd_list_details` but it will only use the first one to update the collection summary.
```yaml
collections:
Vultures 101 Best Movie Endings:
letterboxd_list_details: https://letterboxd.com/brianformo/list/vultures-101-best-movie-endings/
collection_order: custom
sync_mode: sync
```

@ -0,0 +1,64 @@
# MdbList Builders
You can find items using the features of [MdbList.com](https://mdblist.com/) (MdbList).
| Attribute | Description | Works with Movies | Works with Shows | Works with Playlists and Custom Sort |
|:--------------------------------|:--------------------------------------------------------------------------|:-----------------:|:----------------:|:------------------------------------:|
| [`mdblist_list`](#mdblist-list) | Gets every movie/show in a [MdbList List](https://mdblist.com/toplists/). | &#9989; | &#9989; | &#9989; |
## MdbList List
Finds every item in a [MdbList List](https://mdblist.com/toplists/).
The expected input is an MdbList List URL. Multiple values are supported as a list only a comma-separated string will not work.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Top Movies of The Week:
mdblist_list: https://mdblist.com/lists/linaspurinis/top-watched-movies-of-the-week
collection_order: custom
sync_mode: sync
```
You can also limit the number of items to search for by using the `limit` and `url` attributes under `mdblist_list`.
```yaml
collections:
Top 10 Movies of The Week:
mdblist_list:
url: https://mdblist.com/lists/linaspurinis/top-watched-movies-of-the-week
limit: 10
collection_order: custom
sync_mode: sync
```
You can also sort the items by using the `sort_by` and `url` attributes under `mdblist_list`.
The default `sort_by` when it's not specified is `score.desc`.
### Sort Options
| Option | Description |
|:----------------------------------------|:-------------------------|
| `score.asc`<br>`score.desc` | Sort by MdbList Score |
| `released.asc`<br>`released.desc` | Sort by Release Date |
| `imdbrating.asc`<br>`imdbrating.desc` | Sort by IMDb Rating |
| `imdbvotes.asc`<br>`imdbvotes.desc` | Sort by IMDb Votes |
| `imdbpopular.asc`<br>`imdbpopular.desc` | Sort by IMDb Popular |
| `tmdbpopular.asc`<br>`tmdbpopular.desc` | Sort by TMDb Popular |
| `rogerebert.asc`<br>`rogerebert.desc` | Sort by RogerEvert Score |
| `budget.asc`<br>`budget.desc` | Sort by Budget |
| `revenue.asc`<br>`revenue.desc` | Sort by Revenue |
| `added.asc`<br>`added.desc` | Sort by Date Added |
For these sorts to be reflected in your collection you must use `collection_order: custom`.
```yaml
collections:
Top 10 Movies of The Week:
mdblist_list:
url: https://mdblist.com/lists/linaspurinis/top-watched-movies-of-the-week
sort_by: imdbrating.desc
collection_order: custom
sync_mode: sync
```

@ -0,0 +1,298 @@
# MyAnimeList Builders
You can find anime using the features of [MyAnimeList.net](https://myanimelist.net/) (MyAnimeList).
[Configuring MyAnimeList](../../config/myanimelist) in the config is required for any of these builders.
| Attribute | Description | Works with Movies | Works with Shows | Works with Playlists and Custom Sort |
|:----------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------:|:----------------:|:------------------------------------:|
| [`mal_all`](#myanimelist-top-all-anime) | Finds every anime in MyAnimeList's [Top All Anime](https://myanimelist.net/topanime.php) list | &#9989; | &#9989; | &#9989; |
| [`mal_airing`](#myanimelist-top-airing-anime) | Finds every anime in MyAnimeList's [Top Airing Anime](https://myanimelist.net/topanime.php?type=airing) list | &#9989; | &#9989; | &#9989; |
| [`mal_upcoming`](#myanimelist-top-upcoming-anime) | Finds every anime in MyAnimeList's [Top Upcoming Anime](https://myanimelist.net/topanime.php?type=upcoming) list | &#9989; | &#9989; | &#9989; |
| [`mal_tv`](#myanimelist-top-anime-tv-series) | Finds every anime in MyAnimeList's [Top Anime TV Series](https://myanimelist.net/topanime.php?type=tv) list | &#9989; | &#9989; | &#9989; |
| [`mal_movie`](#myanimelist-top-anime-movies) | Finds every anime in MyAnimeList's [Top Anime Movies](https://myanimelist.net/topanime.php?type=movie) list | &#9989; | &#9989; | &#9989; |
| [`mal_ova`](#myanimelist-top-anime-ova-series) | Finds every anime in MyAnimeList's [Top Anime OVA Series](https://myanimelist.net/topanime.php?type=ova) list | &#9989; | &#9989; | &#9989; |
| [`mal_special`](#myanimelist-top-anime-specials) | Finds every anime in MyAnimeList's [Top Anime Specials](https://myanimelist.net/topanime.php?type=special) list | &#9989; | &#9989; | &#9989; |
| [`mal_popular`](#myanimelist-most-popular-anime) | Finds every anime in MyAnimeList's [Most Popular Anime](https://myanimelist.net/topanime.php?type=bypopularity) list | &#9989; | &#9989; | &#9989; |
| [`mal_favorite`](#myanimelist-most-favorited-anime) | Finds every anime in MyAnimeList's [Most Favorited Anime](https://myanimelist.net/topanime.php?type=favorite) list | &#9989; | &#9989; | &#9989; |
| [`mal_suggested`](#myanimelist-suggested-anime) | Finds the suggested anime in by MyAnimeList for the authorized user | &#9989; | &#9989; | &#9989; |
| [`mal_id`](#myanimelist-id) | Finds the anime specified by the MyAnimeList ID | &#9989; | &#9989; | &#10060; |
| [`mal_userlist`](#myanimelist-user-anime-list) | Finds anime in MyAnimeList User's Anime list the options are detailed below | &#9989; | &#9989; | &#9989; |
| [`mal_season`](#myanimelist-seasonal-anime) | Finds anime in MyAnimeList's [Seasonal Anime](https://myanimelist.net/anime/season) list the options are detailed below | &#9989; | &#9989; | &#9989; |
| [`mal_genre`](#myanimelist-genre) | Finds every anime tagged with the specified genre id. Genre options can be found on [MyAnimeList's Search](https://myanimelist.net/anime.php) | &#9989; | &#9989; | &#9989; |
| [`mal_studio`](#myanimelist-studio) | Finds every anime tagged with the specified studio/producer/licensor id. Studio options can be found on [MyAnimeList's Search](https://myanimelist.net/anime.php) | &#9989; | &#9989; | &#9989; |
## Expected Input
The builders below are expected to have a single integer value of how many movies/shows to query.
* [MyAnimeList Top All Anime](#myanimelist-top-all-anime)
* [MyAnimeList Top Airing Anime](#myanimelist-top-airing-anime)
* [MyAnimeList Top Upcoming Anime](#myanimelist-top-upcoming-anime)
* [MyAnimeList Top Anime TV Series](#myanimelist-top-anime-tv-series)
* [MyAnimeList Top Anime Movies](#myanimelist-top-anime-movies)
* [MyAnimeList Top Anime OVA Series](#myanimelist-top-anime-ova-series)
* [MyAnimeList Top Anime Specials](#myanimelist-top-anime-specials)
* [MyAnimeList Most Popular Anime](#myanimelist-most-popular-anime)
* [MyAnimeList Most Favorited Anime](#myanimelist-most-favorited-anime)
* [MyAnimeList Suggested Anime](#myanimelist-suggested-anime)
The attributes of [MyAnimeList ID](#myanimelist-id), [MyAnimeList Seasonal Anime](#myanimelist-seasonal-anime), [MyAnimeList User Anime List](#myanimelist-user-anime-list), [MyAnimeList Genre](#myanimelist-genre), and [MyAnimeList Studio](#myanimelist-studio) are detailed in their sections below.
## MyAnimeList Top All Anime
Gets every anime in MyAnimeList's [Top Airing Anime](https://myanimelist.net/topanime.php?type=airing) list. (Maximum: 500)
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Top All Anime:
mal_all: 30
collection_order: custom
sync_mode: sync
```
## MyAnimeList Top Airing Anime
Gets every anime in MyAnimeList's [Top Airing Anime](https://myanimelist.net/topanime.php?type=airing) list. (Maximum: 500)
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Top Airing Anime:
mal_airing: 10
collection_order: custom
sync_mode: sync
```
## MyAnimeList Top Upcoming Anime
Gets every anime in MyAnimeList's [Top Upcoming Anime](https://myanimelist.net/topanime.php?type=upcoming) list. (Maximum: 500)
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Top Upcoming Anime:
mal_upcoming: 10
collection_order: custom
sync_mode: sync
```
## MyAnimeList Top Anime TV Series
Gets every anime in MyAnimeList's [Top Anime TV Series](https://myanimelist.net/topanime.php?type=tv) list. (Maximum: 500)
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Top Anime TV Series:
mal_tv: 20
collection_order: custom
sync_mode: sync
```
## MyAnimeList Top Anime Movies
Gets every anime in MyAnimeList's [Top Anime Movies](https://myanimelist.net/topanime.php?type=movie) list. (Maximum: 500)
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Top Anime Movies:
mal_movie: 20
collection_order: custom
sync_mode: sync
```
## MyAnimeList Top Anime OVA Series
Gets every anime in MyAnimeList's [Top Anime OVA Series](https://myanimelist.net/topanime.php?type=ova) list. (Maximum: 500)
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Top Anime OVA Series:
mal_ova: 20
collection_order: custom
sync_mode: sync
```
## MyAnimeList Top Anime Specials
Gets every anime in MyAnimeList's [Top Anime Specials](https://myanimelist.net/topanime.php?type=special) list. (Maximum: 500)
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Top Anime Specials:
mal_special: 20
collection_order: custom
sync_mode: sync
```
## MyAnimeList Most Popular Anime
Gets every anime in MyAnimeList's [Most Popular Anime](https://myanimelist.net/topanime.php?type=bypopularity) list. (Maximum: 500)
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Most Popular Anime:
mal_popular: 20
collection_order: custom
sync_mode: sync
```
## MyAnimeList Most Favorited Anime
Gets every anime in MyAnimeList's [Most Favorited Anime](https://myanimelist.net/topanime.php?type=favorite) list. (Maximum: 500)
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Most Favorited Anime:
mal_favorite: 20
collection_order: custom
sync_mode: sync
```
## MyAnimeList Suggested Anime
Gets the suggested anime in by MyAnimeList for the authorized user. (Maximum: 100)
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Suggested Anime:
mal_suggested: 20
collection_order: custom
sync_mode: sync
```
## MyAnimeList ID
Gets the anime specified by the MyAnimeList ID.
The expected input is a MyAnimeList ID. Multiple values are supported as either a list or a comma-separated string.
```yaml
collections:
Cowboy Bebop:
mal_id: 23, 219
```
## MyAnimeList User Anime List
Gets anime in MyAnimeList User's Anime list. The different sub-attributes are detailed below. The only required attribute is `username`
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
| Attribute | Description |
|:-----------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `username` | **Description:** A user's MyAnimeList Username or `@me` for the authorized user |
| `status` | **Description:** Status to search for<br>**Default:** `all`<br>**Values:**<table class="clearTable"><tr><td>`all`</td><td>All Anime List</td></tr><tr><td>`watching`</td><td>Currently Watching List</td></tr><tr><td>`completed`</td><td>Completed List</td></tr><tr><td>`on_hold`</td><td>On Hold List</td></tr><tr><td>`dropped`</td><td>Dropped List</td></tr><tr><td>`plan_to_watch`</td><td>Plan to Watch</td></tr></table> |
| `sort_by` | **Description:** Sort Order to return<br>**Default:** `score`<br>**Values:**<table class="clearTable"><tr><td>`score`</td><td>Sort by Score</td></tr><tr><td>`last_updated`</td><td>Sort by Last Updated</td></tr><tr><td>`title`</td><td>Sort by Anime Title</td></tr><tr><td>`start_date`</td><td>Sort by Start Date</td></tr></table> |
| `limit` | **Description:** Don't return more then this number<br>**Default:** `100`<br>**Values:** Number of Anime to query from MyAnimeList (max: 1000) |
```yaml
collections:
Currently Watching Anime:
mal_userlist:
username: "@me"
status: watching
sort_by: score
limit: 500
collection_order: custom
sync_mode: sync
```
## MyAnimeList Seasonal Anime
Gets anime in MyAnimeList's [Seasonal Anime](https://myanimelist.net/anime/season) list the options are detailed below.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
| Attribute | Description & Values |
|:----------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `season` | **Description:** Season to search<br>**Default:** `current`<br>**Values:**<table class="clearTable"><tr><td>`winter`</td><td>For winter season January, February, March</td></tr><tr><td>`spring`</td><td>For spring season April, May, June</td></tr><tr><td>`summer`</td><td>For summer season July, August, September</td></tr><tr><td>`fall`</td><td>For fall season October, November, December</td></tr><tr><td>`current`</td><td>For the current Season</td></tr></table> |
| `year` | **Description:** Year to search<br>**Default:** Current Year<br>**Values:** Number between `1917` and the current year. |
| `sort_by` | **Description:** Sort Order<br>**Default:** `members`<br>**Values:**<table class="clearTable"><tr><td>`members`</td><td>Sort by Most Members</td></tr><tr><td>`score`</td><td>Sort by Score</td></tr></table> |
| `limit` | **Description:** Don't return more then this number<br>**Default:** `100`<br>**Values:** Number of Anime to query from MyAnimeList (max: 500) |
```yaml
collections:
Current Anime Season:
mal_season:
sort_by: members
limit: 50
collection_order: custom
sync_mode: sync
```
```yaml
collections:
Fall 2020 Anime:
mal_season:
season: fall
year: 2020
limit: 50
collection_order: custom
sync_mode: sync
```
## MyAnimeList Genre
Gets every anime tagged with the specified genre ID sorted by members the options are detailed below. `genre_id` is the only required attribute.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
* Genre options can be found on [MyAnimeList's Search](https://myanimelist.net/anime.php) Page.
* To find the ID click on a Genre in the link above and there should be a number in the URL that's the `genre_id`.
* For example if the url is `https://myanimelist.net/anime/genre/1/Action` the `genre_id` would be `1`.
| Attribute | Description |
|:-----------|:--------------------------------------------------------------------|
| `genre_id` | The ID of Genre from MyAnimeList |
| `limit` | Number of Anime to query from MyAnimeList<br>**Default:** `0` (All) |
```yaml
collections:
Sports Anime:
mal_genre:
genre_id: 30
collection_order: custom
sync_mode: sync
```
## MyAnimeList Studio
Gets every anime tagged with the specified studio/producer/licensor ID sorted by members the options are detailed below. `studio_id` is the only required attribute.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
* Studio options can be found on [MyAnimeList's Search](https://myanimelist.net/anime.php) Page.
* To find the ID click on a Studio in the link above and there should be a number in the URL that's the `studio_id`.
* For example if the url is `https://myanimelist.net/anime/producer/4/Bones` the `studio_id` would be `4`.
| Attribute | Description |
|:------------|:--------------------------------------------------------------------|
| `studio_id` | The ID of Studio/Producer/Licensor from MyAnimeList |
| `limit` | Number of Anime to query from MyAnimeList<br>**Default:** `0` (All) |
```yaml
collections:
Bones Studio Anime:
mal_studio:
studio_id: 4
collection_order: custom
sync_mode: sync
```

@ -0,0 +1,413 @@
# Plex Builders
This builder finds its items by using the features of Plex.
No configuration is required for these builders.
| Attribute | Description | Works with Movies | Works with Shows | Works with Playlists and Custom Sort |
|:----------------------------------------------|:-------------------------------------------------------------------------|:-----------------:|:----------------:|:------------------------------------:|
| [`plex_all`](#plex-all) | Gets every movie/show in your library. Useful with [Filters](../filters) | &#9989; | &#9989; | &#10060; |
| [`plex_pilots`](#plex-pilots) | Gets the first episode of every show in your library | &#10060; | &#9989; | &#9989; |
| [`plex_collectionless`](#plex-collectionless) | Gets every movie/show that is not in a collection | &#9989; | &#9989; | &#10060; |
| [`plex_search`](#plex-search) | Gets every movie/show based on the search parameters provided | &#9989; | &#9989; | &#9989; |
## Plex All
Finds every item in your library. Useful with [Filters](../filters).
The expected input is either true or false.
```yaml
collections:
9.0 Movies:
plex_all: true
filters:
rating.gte: 9
```
## Plex Pilots
Gets the first episode of every show in your library. This Only works with `collection_level: episode`
```yaml
collection:
Pilots:
collection_level: episode
plex_pilots: true
```
## Plex Collectionless
**This is not needed if you're using [Smart Label Collections](smart.md#smart-label).**
Finds every item that is not in a collection unless the collection is in the exclusion list. This is a special collection type to help keep your library looking correct. When items in your library are in multiple collections it can mess up how they're displayed in your library.
For Example, if you have a `Marvel Cinematic Universe` Collection set to `Show this collection and its items` and an `Iron Man` Collection set to `Hide items in this collection` what happens is the show overrides the hide, and you end up with both the collections and the 3 Iron Man movies all displaying.
Alternatively, if you set the `Marvel Cinematic Universe` Collection to `Hide items in this collection` then movies without a collection like `The Incredible Hulk` will be hidden from the library view.
To combat the problem above you set all collections to `Hide items in this collection` then create a collection set to `Hide collection` and put every movie that you still want to display in that collection.
With the variability of collections generated by the Plex Meta Manager maintaining a collection like this becomes very difficult, so in order to automate it, you can use `plex_collectionless`. You just have to tell it what collections to exclude or what collection prefixes to exclude.
There are two attributes for `plex_collectionless`, `exclude` (To exclude specific collections) and `exclude_prefix` (To exclude every collection whose title or sort title starts with the prefix). At least one exclusion is required.
```yaml
collections:
Collectionless:
plex_collectionless:
exclude_prefix:
- +
- ~
exclude: Marvel Cinematic Universe
sort_title: ~_Collectionless
collection_order: alpha
```
* Both `exclude` and `exclude_prefix` can take multiple values as a List.
* This is a known issue with Plex Collection and there is a [Feature Suggestion](https://forums.plex.tv/t/collection-display-issue/305406) detailing the issue more on their forms.
## Plex Search
Uses Plex's [Advanced Filters](https://support.plex.tv/articles/201273953-collections/) to find all items based on the search parameters provided.
Any Advanced Filter made using the Plex UI should be able to be recreated using `plex_search`. If you're having trouble getting `plex_search` to work correctly, build the collection you want inside of Plex's Advanced Filters and take a screenshot of the parameters in the Plex UI and post it in either the [Discussions](https://github.com/meisnate12/Plex-Meta-Manager/discussions) or on [Discord](https://discord.gg/TsdpsFYqqm), and I'll do my best to help you.
like Plex's [Advanced Filters](https://support.plex.tv/articles/201273953-collections/) you have to start each search with either `any` or `all` as a base. You can only have one base attribute and all search attributes must be under the base.
Inside the base attribute you can use any search below or nest more `any` or `all`. You can have as many nested `any` or `all` next to each other as you want. If using multiple `any` or `all` you will have to do so in the form of a list.
There are a couple other attributes you can have at the top level only along with the base attribute are:
## Special Attributes
| Attribute | Description & Values |
|:-----------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `type` | **Description:** The Type of items inside this collection/playlist.<br>**Default:**<table class="clearTable"><tr><td>`movies` for Movies Libraries</td></tr><tr><td>`shows` for Show Libraries</td></tr><tr><td>`artists` for Music Libraries</td></tr></table>**Values:** `movies`, `shows`, `seasons`, `episodes`, `artists`, `albums`, or `tracks` |
| `limit` | **Description:** The max number of item for the search.<br>**Default:** `all`<br>**Values:** `all` or a number greater then 0 |
| `sort_by` | **Description:** This will control how the filter is sorted in your library.<br>**Default:** `random`<br>**Values:** Any sort options for your search type in the [Sorts Options Table](#sort-options) |
| `validate` | **Description:** Determines if a collection/playlist will fail on a validation error<br>**Default:** `true`<br>**Values**: `true` or `false` |
## Sort Options
| Sort Option | Description | Movies | Shows | Seasons | Episodes | Artists | Albums | Tracks |
|:------------------------------------------------|:--------------------------------------------|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|
| `title.asc`<br>`title.desc` | Sort by Title | &#9989; | &#9989; | &#10060; | &#9989; | &#9989; | &#9989; | &#9989; |
| `season.asc`<br>`season.desc` | Sort by Season | &#10060; | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; | &#10060; |
| `show.asc`<br>`show.desc` | Sort by Show | &#10060; | &#10060; | &#9989; | &#9989; | &#10060; | &#10060; | &#10060; |
| `album_artist.asc`<br>`album_artist.desc` | Sort by Album Artist | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; | &#9989; | &#9989; |
| `artist.asc`<br>`artist.desc` | Sort by Artist | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; | &#9989; |
| `album.asc`<br>`album.desc` | Sort by Album | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; | &#9989; |
| `year.asc`<br>`year.desc` | Sort by Year | &#9989; | &#9989; | &#10060; | &#9989; | &#10060; | &#9989; | &#10060; |
| `release.asc`<br>`release.desc` | Sort by Release Date (Originally Available) | &#9989; | &#9989; | &#10060; | &#9989; | &#10060; | &#9989; | &#10060; |
| `critic_rating.asc`<br>`critic_rating.desc` | Sort by Critic Rating | &#9989; | &#9989; | &#10060; | &#9989; | &#10060; | &#9989; | &#10060; |
| `audience_rating.asc`<br>`audience_rating.desc` | Sort by Audience Rating | &#9989; | &#9989; | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; |
| `user_rating.asc`<br>`user_rating.desc` | Sort by User Rating | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; |
| `content_rating.asc`<br>`content_rating.desc` | Sort by Content Rating | &#9989; | &#9989; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; |
| `duration.asc`<br>`duration.desc` | Sort by Duration | &#9989; | &#10060; | &#10060; | &#9989; | &#10060; | &#10060; | &#9989; |
| `progress.asc`<br>`progress.desc` | Sort by Progress | &#10060; | &#10060; | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; |
| `played.asc`<br>`played.desc` | Sort by Date Last Played | &#10060; | &#10060; | &#10060; | &#10060; | &#9989; | &#9989; | &#9989; |
| `plays.asc`<br>`plays.desc` | Sort by Number of Plays | &#9989; | &#10060; | &#10060; | &#9989; | &#9989; | &#9989; | &#9989; |
| `unplayed.asc`<br>`unplayed.desc` | Sort by Unplayed | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; |
| `episode_added.asc`<br>`episode_added.desc` | Sort by Last Episode Date Added | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; |
| `added.asc`<br>`added.desc` | Sort by Date Added | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; |
| `viewed.asc`<br>`viewed.desc` | Sort by Date Last Viewed | &#9989; | &#9989; | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; |
| `rated.asc`<br>`rated.desc` | Sort by Date Last Rated | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; | &#9989; |
| `popularity.asc`<br>`popularity.desc` | Sort by Popularity | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; | &#9989; |
| `resolution.asc`<br>`resolution.desc` | Sort by Resolution | &#9989; | &#10060; | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; |
| `bitrate.asc`<br>`bitrate.desc` | Sort by Bitrate | &#9989; | &#10060; | &#10060; | &#9989; | &#10060; | &#10060; | &#9989; |
| `random` | Sort by Random | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; |
## Searches
There are three fields per search option when using Plex's Advanced Filters in the Web UI.
1. **Attribute:** What attribute you wish to search.
2. **Modifier:** Which modifier to use.
3. **Value:** Actual value to search.
**Example:** `Attribute.Modifier: Value`
## String Searches
String searches can be used with either no modifier or with `.not`, `.is`, `.isnot`, `.begins`, or `.ends`.
String search can take multiple values **only as a list**.
### String Modifiers
| String Modifier | Description | Plex Web UI Display |
|:----------------|:-------------------------------------------------------------------------------|:-------------------:|
| No Modifier | Matches every item where the attribute contains the given string | `contains` |
| `.not` | Matches every item where the attribute does not contain the given string | `does not contain` |
| `.is` | Matches every item where the attribute exactly matches the given string | `is` |
| `.isnot` | Matches every item where the attribute does not exactly match the given string | `is not` |
| `.begins` | Matches every item where the attribute begins with the given string | `begins with` |
| `.ends` | Matches every item where the attribute ends with the given string | `ends with` |
### String Attributes
| String Search | Description | Movie<br>Libraries | Show<br>Libraries | Music<br>Libraries |
|:---------------------|:---------------------------------------------------------|:------------------:|:-----------------:|:------------------:|
| `title` | Uses the title attribute to match | &#9989; | &#9989; | &#10060; |
| `episode_title` | Uses the title attribute of the show's episodes to match | &#10060; | &#9989; | &#10060; |
| `studio` | Uses the studio attribute to match | &#9989; | &#9989; | &#10060; |
| `artist_title` | Uses the Artist's Title attribute to match | &#10060; | &#10060; | &#9989; |
| `album_title` | Uses the Album's Title attribute to match | &#10060; | &#10060; | &#9989; |
| `track_title` | Uses the Track's Title attribute to match | &#10060; | &#10060; | &#9989; |
| `album_record_label` | Uses the Album's Record Label attribute to match | &#10060; | &#10060; | &#9989; |
## Tag Searches
Tag searches can be used with either no modifier or with `.not` except for `decade` and `resolution` which can only be used with no modifier.
Tag search can take multiple values as a **list or a comma-separated string**.
### Tag Modifiers
| Tag Modifier | Description | Plex Web UI Display |
|:-------------|:-----------------------------------------------------------------------|:-------------------:|
| No Modifier | Matches every item where the attribute matches the given string | `is` |
| `.not` | Matches every item where the attribute does not match the given string | `is not` |
### Tag Attributes
| Tag Search | Description | Movie<br>Libraries | Show<br>Libraries | Music<br>Libraries |
|:--------------------|:----------------------------------------------------------------------------|:------------------:|:-----------------:|:------------------:|
| `actor` | Uses the actor tags to match | &#9989; | &#9989; | &#10060; |
| `audio_language` | Uses the audio language tags to match | &#9989; | &#9989; | &#10060; |
| `collection` | Uses the collection tags to match | &#9989; | &#9989; | &#10060; |
| `content_rating` | Uses the content rating tags to match | &#9989; | &#9989; | &#10060; |
| `country` | Uses the country tags to match | &#9989; | &#10060; | &#10060; |
| `decade` | Uses the year tag to match the decade | &#9989; | &#10060; | &#10060; |
| `director` | Uses the director tags to match | &#9989; | &#10060; | &#10060; |
| `genre` | Uses the genre tags to match | &#9989; | &#9989; | &#10060; |
| `label` | Uses the label tags to match | &#9989; | &#9989; | &#10060; |
| `network` | Uses the network tags to match<br>**Only works with the New Plex TV Agent** | &#10060; | &#9989; | &#10060; |
| `producer` | Uses the actor tags to match | &#9989; | &#10060; | &#10060; |
| `resolution` | Uses the resolution tags to match | &#9989; | &#9989; | &#10060; |
| `subtitle_language` | Uses the subtitle language tags to match | &#9989; | &#9989; | &#10060; |
| `writer` | Uses the writer tags to match | &#9989; | &#10060; | &#10060; |
| `year` | Uses the year tag to match | &#9989; | &#9989; | &#10060; |
| `episode_year` | Uses the year tag to match | &#10060; | &#9989; | &#10060; |
| `artist_genre` | Uses the Artist's Genre attribute to match | &#10060; | &#10060; | &#9989; |
| `artist_collection` | Uses the Artist's Collection attribute to match | &#10060; | &#10060; | &#9989; |
| `artist_country` | Uses the Artist's Country attribute to match | &#10060; | &#10060; | &#9989; |
| `artist_mood` | Uses the Artist's Mood attribute to match | &#10060; | &#10060; | &#9989; |
| `artist_style` | Uses the Artist's Style attribute to match | &#10060; | &#10060; | &#9989; |
| `album_genre` | Uses the Album's Genre attribute to match | &#10060; | &#10060; | &#9989; |
| `album_mood` | Uses the Album's Mood attribute to match | &#10060; | &#10060; | &#9989; |
| `album_style` | Uses the Album's Style attribute to match | &#10060; | &#10060; | &#9989; |
| `album_format` | Uses the Album's Format attribute to match | &#10060; | &#10060; | &#9989; |
| `album_type` | Uses the Album's Type attribute to match | &#10060; | &#10060; | &#9989; |
| `album_collection` | Uses the Album's Collection attribute to match | &#10060; | &#10060; | &#9989; |
| `album_source` | Uses the Album's Source attribute to match | &#10060; | &#10060; | &#9989; |
| `album_label` | Uses the Album's Label attribute to match | &#10060; | &#10060; | &#9989; |
| `track_mood` | Uses the Track's Mood attribute to match | &#10060; | &#10060; | &#9989; |
| `track_source` | Uses the Track's Style attribute to match | &#10060; | &#10060; | &#9989; |
## Date Searches
Date searches can be used with either no modifier or with `.not`, `.before`, or `.after`.
No date search can take multiple values.
### Date Modifiers
| Date Modifier | Description | Plex Web UI Display |
|:--------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------:|
| No Modifier | Matches every item where the date attribute is in the last X days<br>**Format:** number of days<br>**Example:** `30` | `is in the last` |
| `.not` | Matches every item where the date attribute is not in the last X days<br>**Format:** number of days<br>**Example:** `30` | `is not in the last` |
| `.before` | Matches every item where the date attribute is before the given date<br>**Format:** MM/DD/YYYY or `today` for the current day<br>**Example:** `01/01/2000` | `is before` |
| `.after` | Matches every item where the date attribute is after the given date<br>**Format:** MM/DD/YYYY or `today` for the current day<br>**Example:** `01/01/2000` | `is after` |
### Date Attributes
| Date Search | Description | Movie<br>Libraries | Show<br>Libraries | Music<br>Libraries |
|:----------------------|:-----------------------------------------------------------------------------------|:------------------:|:-----------------:|:------------------:|
| `added` | Uses the date added attribute to match | &#9989; | &#9989; | &#10060; |
| `episode_added` | Uses the date added attribute of the show's episodes to match | &#10060; | &#9989; | &#10060; |
| `release` | Uses the release date attribute (originally available) to match | &#9989; | &#9989; | &#10060; |
| `episode_air_date` | Uses the air date attribute (originally available) of the show's episodes to match | &#10060; | &#9989; | &#10060; |
| `last_played` | Uses the date last played attribute to match | &#9989; | &#9989; | &#10060; |
| `episode_last_played` | Uses the date last played attribute of the show's episodes to match | &#10060; | &#9989; | &#10060; |
| `artist_added` | Uses the Artist's date added attribute to match | &#10060; | &#10060; | &#9989; |
| `artist_last_played` | Uses the Artist's last played attribute to match | &#10060; | &#10060; | &#9989; |
| `album_last_played` | Uses the Album's last played attribute to match | &#10060; | &#10060; | &#9989; |
| `album_added` | Uses the Album's date added attribute to match | &#10060; | &#10060; | &#9989; |
| `album_released` | Uses the Album's release date attribute to match | &#10060; | &#10060; | &#9989; |
| `track_last_played` | Uses the Track's date last played attribute to match | &#10060; | &#10060; | &#9989; |
| `track_last_skipped` | Uses the Track's date last skipped attribute to match | &#10060; | &#10060; | &#9989; |
| `track_last_rated` | Uses the Track's date last rated attribute to match | &#10060; | &#10060; | &#9989; |
| `track_added` | Uses the Track's date added attribute to match | &#10060; | &#10060; | &#9989; |
## Number Searches
Number searches must use `.gt`, `.gte`, `.lt`, or `.lte` as a modifier.
No number search can take multiple values.
### Number Modifiers
| Number Modifier | Description | Plex Web UI Display |
|:----------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------:|
| `.gt` | Matches every item where the number attribute is greater then the given number<br>**Format:** number<br>**Example:** `30`, `1995`, or `7.5` | `is greater than` |
| `.gte` | Matches every item where the number attribute is greater then or equal to the given number<br>**Format:** number<br>**Example:** `30`, `1995`, or `7.5` | N/A |
| `.lt` | Matches every item where the number attribute is less then the given number<br>**Format:** number<br>**Example:** `30`, `1995`, or `7.5` | `is less than` |
| `.lte` | Matches every item where the number attribute is less then or equal to the given number<br>**Format:** number<br>**Example:** `30`, `1995`, or `7.5` | N/A |
### Number Attributes
| Number Search | Description | Movie<br>Libraries | Show<br>Libraries | Music<br>Libraries |
|:----------------------|:--------------------------------------------------------------------------------------------|:------------------:|:-----------------:|:------------------:|
| `duration` | Uses the duration attribute to match using minutes<br>**Minimum:** `1` | &#9989; | &#10060; | &#10060; |
| `plays` | Uses the plays attribute to match<br>**Minimum:** `1` | &#9989; | &#9989; | &#10060; |
| `episode_plays` | Uses the Episode's plays attribute to match<br>**Minimum:** `1` | &#10060; | &#9989; | &#10060; |
| `critic_rating` | Uses the critic rating attribute to match<br>**Range:** `0.0` - `10.0` | &#9989; | &#9989; | &#10060; |
| `audience_rating` | Uses the audience rating attribute to match<br>**Range:** `0.0` - `10.0` | &#9989; | &#9989; | &#10060; |
| `user_rating` | Uses the user rating attribute to match<br>**Range:** `0.0` - `10.0` | &#9989; | &#9989; | &#10060; |
| `episode_user_rating` | Uses the user rating attribute of the show's episodes to match<br>**Range:** `0.0` - `10.0` | &#10060; | &#9989; | &#10060; |
| `year` | Uses the year attribute to match<br>**Minimum:** `1` | &#9989; | &#9989; | &#10060; |
| `episode_year` | Uses the Episode's year attribute to match<br>**Minimum:** `1` | &#10060; | &#9989; | &#10060; |
| `album_year` | Uses the Album's year attribute to match<br>**Minimum:** `1` | &#10060; | &#10060; | &#9989; |
| `album_decade` | Uses the Album's decade attribute to match<br>**Minimum:** `1` | &#10060; | &#10060; | &#9989; |
| `album_plays` | Uses the Album's plays attribute to match<br>**Minimum:** `1` | &#10060; | &#10060; | &#9989; |
| `track_plays` | Uses the Track's plays attribute to match<br>**Minimum:** `1` | &#10060; | &#10060; | &#9989; |
| `track_skips` | Uses the Track's skips attribute to match<br>**Minimum:** `1` | &#10060; | &#10060; | &#9989; |
| `artist_user_rating` | Uses the Artist's user rating attribute to match<br>**Range:** `0.0` - `10.0` | &#10060; | &#10060; | &#9989; |
| `album_user_rating` | Uses the Album's user rating attribute to match<br>**Range:** `0.0` - `10.0` | &#10060; | &#10060; | &#9989; |
| `album_critic_rating` | Uses the Album's critic rating attribute to match<br>**Range:** `0.0` - `10.0` | &#10060; | &#10060; | &#9989; |
| `track_user_rating` | Uses the Track's user rating attribute to match<br>**Range:** `0.0` - `10.0` | &#10060; | &#10060; | &#9989; |
## Boolean Searches
Boolean Searches take no modifier and can only be either `true` or `false`.
### Boolean Attributes
| Boolean Search | Description | Movie<br>Libraries | Show<br>Libraries | Music<br>Libraries |
|:--------------------|:-----------------------|:------------------:|:-----------------:|:------------------:|
| `hdr` | Is HDR | &#9989; | &#9989; | &#10060; |
| `unmatched` | Is Unmatched | &#9989; | &#10060; | &#10060; |
| `duplicate` | Is Duplicate | &#9989; | &#10060; | &#10060; |
| `unplayed` | Is Unplayed | &#9989; | &#10060; | &#10060; |
| `progress` | Is In Progress | &#9989; | &#10060; | &#10060; |
| `trash` | Is Trashed | &#9989; | &#9989; | &#10060; |
| `unplayed_episodes` | Has Unplayed Episodes | &#10060; | &#9989; | &#10060; |
| `episode_unplayed` | Has Episodes Unplayed | &#10060; | &#9989; | &#10060; |
| `episode_duplicate` | Has Duplicate Episodes | &#10060; | &#9989; | &#10060; |
| `episode_progress` | Has Episode Progress | &#10060; | &#9989; | &#10060; |
| `episode_unmatched` | Has Episodes Unmatched | &#10060; | &#9989; | &#10060; |
| `artist_unmatched` | Is Artist's Unmatched | &#10060; | &#10060; | &#9989; |
| `album_unmatched` | Is Album's Unmatched | &#10060; | &#10060; | &#9989; |
| `track_trash` | Is Track Trashed | &#10060; | &#10060; | &#9989; |
## Plex Search Examples
A few examples are listed below:
```yaml
collections:
Documentaries:
plex_search:
all:
genre: Documentary
```
```yaml
collections:
Dave Chappelle Comedy:
plex_search:
all:
actor: Dave Chappelle
genre: Comedy
```
```yaml
collections:
Top Action Movies:
collection_order: custom
plex_search:
all:
genre: Action
sort_by: audience_rating.desc
limit: 20
```
```yaml
collections:
90s Movies:
plex_search:
any:
year:
- 1990
- 1991
- 1992
- 1993
- 1994
- 1995
- 1996
- 1997
- 1998
- 1999
```
```yaml
collections:
90s Movies:
plex_search:
any:
decade: 1990
```
```yaml
collections:
Best 2010+ Movies:
collection_order: custom
plex_search:
all:
year.gte: 2010
sort_by: audience_rating.desc
limit: 20
```
Here's an example of an episode collection using `plex_search`.
```yaml
collections:
Top 100 Simpsons Episodes:
collection_order: custom
collection_level: episode
plex_search:
type: episodes
sort_by: audience_rating.desc
limit: 100
all:
title.ends: "Simpsons"
summary: A collection of the highest rated simpsons epsodes.
```
If you specify TMDb Person ID's using the Detail `tmdb_person` and then tell either `actor`, `director`, `producer`, or `writer` to add `tmdb`, the script will translate the TMDb Person IDs into their names and run the search on those names.
```yaml
collections:
Robin Williams:
plex_search:
all:
actor: tmdb
tmdb_person: 2157
```
```yaml
collections:
Steven Spielberg:
plex_search:
all:
director: tmdb
tmdb_person: https://www.themoviedb.org/person/488-steven-spielberg
```
```yaml
collections:
Quentin Tarantino:
plex_search:
any:
actor: tmdb
director: tmdb
producer: tmdb
writer: tmdb
tmdb_person: 138
```

@ -0,0 +1,362 @@
# Smart Builders
Smart Builders allow Plex Meta Manager to create Smart Collections in two different ways.
## Smart Label
A Smart Label Collection is a smart collection that grabs every item with a specific label generated by the program. That label is added to all the items the Collection Builders find instead of being added to a normal collection.
To make a collection a Smart Label Collection,the `smart_label` attribute must added to the collection definition. It functions in two different ways:
1. Define the sort using the Movies/Shows column of the [Sorts Table](#sort-options) below along with any other builder to make that collection a Smart Label Collection.
```yaml
collections:
Marvel Cinematic Universe:
trakt_list: https://trakt.tv/users/jawann2002/lists/marvel-cinematic-universe-movies?sort=rank,asc
smart_label: release.desc
```
2. Provide a whole `smart_filter` to determine exactly how the smart collection should be built, ensuring to include `label: <<smart_label>>`, which will link it to the collection labels.
```yaml
collections:
Unplayed Marvel Cinematic Universe:
trakt_list: https://trakt.tv/users/jawann2002/lists/marvel-cinematic-universe-movies?sort=rank,asc
smart_label:
sort_by: release.desc
all:
label: <<smart_label>>
unplayed: True
```
This is extremely useful because smart collections don't follow normal show/hide rules and can eliminate the need to have [Plex Collectionless](plex.md#plex-collectionless) when used correctly. To fix the issue described in [Plex Collectionless](plex.md#plex-collectionless) you would make `Marvel Cinematic Universe` a Smart Label Collection and all other Marvel collection just normal collections, and they will show/hide all the movie properly.
To have the Smart Label Collections to eliminate Plex Collectionless you have to go all in on using them. A good rule of thumb to make sure this works correctly is that every item in your library should have a max of one non-smart collection.
Reach out on the [Plex Meta Manager Discord](https://discord.gg/TsdpsFYqqm) or in the [GitHub Discussions](https://github.com/meisnate12/Plex-Meta-Manager/discussions) for help if you're having any issues getting this to work properly.
## Smart Filter
Uses Plex's [Advanced Filters](https://support.plex.tv/articles/201273953-collections/) to create a smart collection based on the filter parameters provided.
Any Advanced Filter made using the Plex UI should be able to be recreated using `smart_filter`. If you're having trouble getting `smart_filter` to work correctly, build the collection you want inside of Plex's Advanced Filters and take a screenshot of the parameters in the Plex UI and post it in either the [Discussions](https://github.com/meisnate12/Plex-Meta-Manager/discussions) or on [Discord](https://discord.gg/TsdpsFYqqm), and I'll do my best to help you.
like Plex's [Advanced Filters](https://support.plex.tv/articles/201273953-collections/) you have to start each filter with either `any` or `all` as a base. You can only have one base attribute and all filter attributes must be under the base.
Inside the base attribute you can use any filter below or nest more `any` or `all`. You can have as many nested `any` or `all` next to each other as you want. If using multiple `any` or `all` you will have to do so in the form of a list.
There are a couple other attributes you can have at the top level only along with the base attribute are:
## Special Attributes
| Attribute | Description & Values |
|:-----------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `type` | **Description:** The Type of items inside this collection.<br>**Default:**<table class="clearTable"><tr><td>`movies` for Movies Libraries</td></tr><tr><td>`shows` for Show Libraries</td></tr><tr><td>`artists` for Music Libraries</td></tr></table>**Values:** `movies`, `shows`, `seasons`, `episodes`, `artists`, `albums`, or `tracks` |
| `limit` | **Description:** The max number of item for the filter.<br>**Default:** `all`<br>**Values:** `all` or a number greater then 0 |
| `sort_by` | **Description:** This will control how the filter is sorted in your library.<br>**Default:** `random`<br>**Values:** Any sort options for your filter type in the [Sorts Options Table](#sort-options) |
| `validate` | **Description:** Determines if a collection will fail on a validation error<br>**Default:** `true`<br>**Values**: `true` or `false` |
## Sort Options
| Sort Option | Description | Movies | Shows | Seasons | Episodes | Artists | Albums | Tracks |
|:------------------------------------------------|:--------------------------------------------|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|
| `title.asc`<br>`title.desc` | Sort by Title | &#9989; | &#9989; | &#10060; | &#9989; | &#9989; | &#9989; | &#9989; |
| `season.asc`<br>`season.desc` | Sort by Season | &#10060; | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; | &#10060; |
| `show.asc`<br>`show.desc` | Sort by Show | &#10060; | &#10060; | &#9989; | &#9989; | &#10060; | &#10060; | &#10060; |
| `album_artist.asc`<br>`album_artist.desc` | Sort by Album Artist | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; | &#9989; | &#9989; |
| `artist.asc`<br>`artist.desc` | Sort by Artist | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; | &#9989; |
| `album.asc`<br>`album.desc` | Sort by Album | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; | &#9989; |
| `year.asc`<br>`year.desc` | Sort by Year | &#9989; | &#9989; | &#10060; | &#9989; | &#10060; | &#9989; | &#10060; |
| `release.asc`<br>`release.desc` | Sort by Release Date (Originally Available) | &#9989; | &#9989; | &#10060; | &#9989; | &#10060; | &#9989; | &#10060; |
| `critic_rating.asc`<br>`critic_rating.desc` | Sort by Critic Rating | &#9989; | &#9989; | &#10060; | &#9989; | &#10060; | &#9989; | &#10060; |
| `audience_rating.asc`<br>`audience_rating.desc` | Sort by Audience Rating | &#9989; | &#9989; | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; |
| `user_rating.asc`<br>`user_rating.desc` | Sort by User Rating | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; |
| `content_rating.asc`<br>`content_rating.desc` | Sort by Content Rating | &#9989; | &#9989; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; |
| `duration.asc`<br>`duration.desc` | Sort by Duration | &#9989; | &#10060; | &#10060; | &#9989; | &#10060; | &#10060; | &#9989; |
| `progress.asc`<br>`progress.desc` | Sort by Progress | &#10060; | &#10060; | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; |
| `played.asc`<br>`played.desc` | Sort by Date Last Played | &#10060; | &#10060; | &#10060; | &#10060; | &#9989; | &#9989; | &#9989; |
| `plays.asc`<br>`plays.desc` | Sort by Number of Plays | &#9989; | &#10060; | &#10060; | &#9989; | &#9989; | &#9989; | &#9989; |
| `unplayed.asc`<br>`unplayed.desc` | Sort by Unplayed | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; |
| `episode_added.asc`<br>`episode_added.desc` | Sort by Last Episode Date Added | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; |
| `added.asc`<br>`added.desc` | Sort by Date Added | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; |
| `viewed.asc`<br>`viewed.desc` | Sort by Date Last Viewed | &#9989; | &#9989; | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; |
| `rated.asc`<br>`rated.desc` | Sort by Date Last Rated | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; | &#9989; |
| `popularity.asc`<br>`popularity.desc` | Sort by Popularity | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; | &#9989; |
| `resolution.asc`<br>`resolution.desc` | Sort by Resolution | &#9989; | &#10060; | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; |
| `bitrate.asc`<br>`bitrate.desc` | Sort by Bitrate | &#9989; | &#10060; | &#10060; | &#9989; | &#10060; | &#10060; | &#9989; |
| `random` | Sort by Random | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; |
## Filters
There are three fields per filter option when using Plex's Advanced Filters in the Web UI.
1. **Attribute:** What attribute you wish to filter.
2. **Modifier:** Which modifier to use.
3. **Value:** Actual value to filter.
**Example:** `Attribute.Modifier: Value`
## String Filters
String filters can be used with either no modifier or with `.not`, `.is`, `.isnot`, `.begins`, or `.ends`.
String filter can take multiple values **only as a list**.
### String Modifiers
| String Modifier | Description | Plex Web UI Display |
|:----------------|:-------------------------------------------------------------------------------|:-------------------:|
| No Modifier | Matches every item where the attribute contains the given string | `contains` |
| `.not` | Matches every item where the attribute does not contain the given string | `does not contain` |
| `.is` | Matches every item where the attribute exactly matches the given string | `is` |
| `.isnot` | Matches every item where the attribute does not exactly match the given string | `is not` |
| `.begins` | Matches every item where the attribute begins with the given string | `begins with` |
| `.ends` | Matches every item where the attribute ends with the given string | `ends with` |
### String Attributes
| String Search | Description | Movie<br>Libraries | Show<br>Libraries | Music<br>Libraries |
|:---------------------|:---------------------------------------------------------|:------------------:|:-----------------:|:------------------:|
| `title` | Uses the title attribute to match | &#9989; | &#9989; | &#10060; |
| `episode_title` | Uses the title attribute of the show's episodes to match | &#10060; | &#9989; | &#10060; |
| `studio` | Uses the studio attribute to match | &#9989; | &#9989; | &#10060; |
| `artist_title` | Uses the Artist's Title attribute to match | &#10060; | &#10060; | &#9989; |
| `album_title` | Uses the Album's Title attribute to match | &#10060; | &#10060; | &#9989; |
| `track_title` | Uses the Track's Title attribute to match | &#10060; | &#10060; | &#9989; |
| `album_record_label` | Uses the Album's Record Label attribute to match | &#10060; | &#10060; | &#9989; |
## Tag Filters
Tag filters can be used with either no modifier or with `.not` except for `decade` and `resolution` which can only be used with no modifier.
Tag filter can take multiple values as a **list or a comma-separated string**.
### Tag Modifiers
| Tag Modifier | Description | Plex Web UI Display |
|:-------------|:-----------------------------------------------------------------------|:-------------------:|
| No Modifier | Matches every item where the attribute matches the given string | `is` |
| `.not` | Matches every item where the attribute does not match the given string | `is not` |
### Tag Attributes
| Tag Search | Description | Movie<br>Libraries | Show<br>Libraries | Music<br>Libraries |
|:--------------------|:----------------------------------------------------------------------------|:------------------:|:-----------------:|:------------------:|
| `actor` | Uses the actor tags to match | &#9989; | &#9989; | &#10060; |
| `audio_language` | Uses the audio language tags to match | &#9989; | &#9989; | &#10060; |
| `collection` | Uses the collection tags to match | &#9989; | &#9989; | &#10060; |
| `content_rating` | Uses the content rating tags to match | &#9989; | &#9989; | &#10060; |
| `country` | Uses the country tags to match | &#9989; | &#10060; | &#10060; |
| `decade` | Uses the year tag to match the decade | &#9989; | &#10060; | &#10060; |
| `director` | Uses the director tags to match | &#9989; | &#10060; | &#10060; |
| `genre` | Uses the genre tags to match | &#9989; | &#9989; | &#10060; |
| `label` | Uses the label tags to match | &#9989; | &#9989; | &#10060; |
| `network` | Uses the network tags to match<br>**Only works with the New Plex TV Agent** | &#10060; | &#9989; | &#10060; |
| `producer` | Uses the actor tags to match | &#9989; | &#10060; | &#10060; |
| `resolution` | Uses the resolution tags to match | &#9989; | &#9989; | &#10060; |
| `subtitle_language` | Uses the subtitle language tags to match | &#9989; | &#9989; | &#10060; |
| `writer` | Uses the writer tags to match | &#9989; | &#10060; | &#10060; |
| `year` | Uses the year tag to match | &#9989; | &#9989; | &#10060; |
| `episode_year` | Uses the year tag to match | &#10060; | &#9989; | &#10060; |
| `artist_genre` | Uses the Artist's Genre attribute to match | &#10060; | &#10060; | &#9989; |
| `artist_collection` | Uses the Artist's Collection attribute to match | &#10060; | &#10060; | &#9989; |
| `artist_country` | Uses the Artist's Country attribute to match | &#10060; | &#10060; | &#9989; |
| `artist_mood` | Uses the Artist's Mood attribute to match | &#10060; | &#10060; | &#9989; |
| `artist_style` | Uses the Artist's Style attribute to match | &#10060; | &#10060; | &#9989; |
| `album_genre` | Uses the Album's Genre attribute to match | &#10060; | &#10060; | &#9989; |
| `album_mood` | Uses the Album's Mood attribute to match | &#10060; | &#10060; | &#9989; |
| `album_style` | Uses the Album's Style attribute to match | &#10060; | &#10060; | &#9989; |
| `album_format` | Uses the Album's Format attribute to match | &#10060; | &#10060; | &#9989; |
| `album_type` | Uses the Album's Type attribute to match | &#10060; | &#10060; | &#9989; |
| `album_collection` | Uses the Album's Collection attribute to match | &#10060; | &#10060; | &#9989; |
| `album_source` | Uses the Album's Source attribute to match | &#10060; | &#10060; | &#9989; |
| `album_label` | Uses the Album's Label attribute to match | &#10060; | &#10060; | &#9989; |
| `track_mood` | Uses the Track's Mood attribute to match | &#10060; | &#10060; | &#9989; |
| `track_source` | Uses the Track's Style attribute to match | &#10060; | &#10060; | &#9989; |
## Date Filters
Date filters can be used with either no modifier or with `.not`, `.before`, or `.after`.
No date filter can take multiple values.
### Date Modifiers
| Date Modifier | Description | Plex Web UI Display |
|:--------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------:|
| No Modifier | Matches every item where the date attribute is in the last X days<br>**Format:** number of days<br>**Example:** `30` | `is in the last` |
| `.not` | Matches every item where the date attribute is not in the last X days<br>**Format:** number of days<br>**Example:** `30` | `is not in the last` |
| `.before` | Matches every item where the date attribute is before the given date<br>**Format:** MM/DD/YYYY or `today` for the current day<br>**Example:** `01/01/2000` | `is before` |
| `.after` | Matches every item where the date attribute is after the given date<br>**Format:** MM/DD/YYYY or `today` for the current day<br>**Example:** `01/01/2000` | `is after` |
### Date Attributes
| Date Search | Description | Movie<br>Libraries | Show<br>Libraries | Music<br>Libraries |
|:----------------------|:-----------------------------------------------------------------------------------|:------------------:|:-----------------:|:------------------:|
| `added` | Uses the date added attribute to match | &#9989; | &#9989; | &#10060; |
| `episode_added` | Uses the date added attribute of the show's episodes to match | &#10060; | &#9989; | &#10060; |
| `release` | Uses the release date attribute (originally available) to match | &#9989; | &#9989; | &#10060; |
| `episode_air_date` | Uses the air date attribute (originally available) of the show's episodes to match | &#10060; | &#9989; | &#10060; |
| `last_played` | Uses the date last played attribute to match | &#9989; | &#9989; | &#10060; |
| `episode_last_played` | Uses the date last played attribute of the show's episodes to match | &#10060; | &#9989; | &#10060; |
| `artist_added` | Uses the Artist's date added attribute to match | &#10060; | &#10060; | &#9989; |
| `artist_last_played` | Uses the Artist's last played attribute to match | &#10060; | &#10060; | &#9989; |
| `album_last_played` | Uses the Album's last played attribute to match | &#10060; | &#10060; | &#9989; |
| `album_added` | Uses the Album's date added attribute to match | &#10060; | &#10060; | &#9989; |
| `album_released` | Uses the Album's release date attribute to match | &#10060; | &#10060; | &#9989; |
| `track_last_played` | Uses the Track's date last played attribute to match | &#10060; | &#10060; | &#9989; |
| `track_last_skipped` | Uses the Track's date last skipped attribute to match | &#10060; | &#10060; | &#9989; |
| `track_last_rated` | Uses the Track's date last rated attribute to match | &#10060; | &#10060; | &#9989; |
| `track_added` | Uses the Track's date added attribute to match | &#10060; | &#10060; | &#9989; |
## Number Filters
Number filters must use `.gt`, `.gte`, `.lt`, or `.lte` as a modifier.
No number filter can take multiple values.
### Number Modifiers
| Number Modifier | Description | Plex Web UI Display |
|:----------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------:|
| `.gt` | Matches every item where the number attribute is greater then the given number<br>**Format:** number<br>**Example:** `30`, `1995`, or `7.5` | `is greater than` |
| `.gte` | Matches every item where the number attribute is greater then or equal to the given number<br>**Format:** number<br>**Example:** `30`, `1995`, or `7.5` | N/A |
| `.lt` | Matches every item where the number attribute is less then the given number<br>**Format:** number<br>**Example:** `30`, `1995`, or `7.5` | `is less than` |
| `.lte` | Matches every item where the number attribute is less then or equal to the given number<br>**Format:** number<br>**Example:** `30`, `1995`, or `7.5` | N/A |
### Number Attributes
| Number Search | Description | Movie<br>Libraries | Show<br>Libraries | Music<br>Libraries |
|:----------------------|:--------------------------------------------------------------------------------------------|:------------------:|:-----------------:|:------------------:|
| `duration` | Uses the duration attribute to match using minutes<br>**Minimum:** `1` | &#9989; | &#10060; | &#10060; |
| `plays` | Uses the plays attribute to match<br>**Minimum:** `1` | &#9989; | &#9989; | &#10060; |
| `episode_plays` | Uses the Episode's plays attribute to match<br>**Minimum:** `1` | &#10060; | &#9989; | &#10060; |
| `critic_rating` | Uses the critic rating attribute to match<br>**Range:** `0.0` - `10.0` | &#9989; | &#9989; | &#10060; |
| `audience_rating` | Uses the audience rating attribute to match<br>**Range:** `0.0` - `10.0` | &#9989; | &#9989; | &#10060; |
| `user_rating` | Uses the user rating attribute to match<br>**Range:** `0.0` - `10.0` | &#9989; | &#9989; | &#10060; |
| `episode_user_rating` | Uses the user rating attribute of the show's episodes to match<br>**Range:** `0.0` - `10.0` | &#10060; | &#9989; | &#10060; |
| `year` | Uses the year attribute to match<br>**Minimum:** `1` | &#9989; | &#9989; | &#10060; |
| `episode_year` | Uses the Episode's year attribute to match<br> **Minimum:** `1` | &#10060; | &#9989; | &#10060; |
| `album_year` | Uses the Album's year attribute to match<br>**Minimum:** `1` | &#10060; | &#10060; | &#9989; |
| `album_decade` | Uses the Album's decade attribute to match<br>**Minimum:** `1` | &#10060; | &#10060; | &#9989; |
| `album_plays` | Uses the Album's plays attribute to match<br>**Minimum:** `1` | &#10060; | &#10060; | &#9989; |
| `track_plays` | Uses the Track's plays attribute to match<br>**Minimum:** `1` | &#10060; | &#10060; | &#9989; |
| `track_skips` | Uses the Track's skips attribute to match<br>**Minimum:** `1` | &#10060; | &#10060; | &#9989; |
| `artist_user_rating` | Uses the Artist's user rating attribute to match<br>**Range:** `0.0` - `10.0` | &#10060; | &#10060; | &#9989; |
| `album_user_rating` | Uses the Album's user rating attribute to match<br>**Range:** `0.0` - `10.0` | &#10060; | &#10060; | &#9989; |
| `album_critic_rating` | Uses the Album's critic rating attribute to match<br>**Range:** `0.0` - `10.0` | &#10060; | &#10060; | &#9989; |
| `track_user_rating` | Uses the Track's user rating attribute to match<br>**Range:** `0.0` - `10.0` | &#10060; | &#10060; | &#9989; |
## Boolean Filters
Boolean Filters take no modifier and can only be either `true` or `false`.
### Boolean Attributes
| Boolean Search | Description | Movie<br>Libraries | Show<br>Libraries | Music<br>Libraries |
|:--------------------|:-----------------------|:------------------:|:-----------------:|:------------------:|
| `hdr` | Is HDR | &#9989; | &#9989; | &#10060; |
| `unmatched` | Is Unmatched | &#9989; | &#10060; | &#10060; |
| `duplicate` | Is Duplicate | &#9989; | &#10060; | &#10060; |
| `unplayed` | Is Unplayed | &#9989; | &#10060; | &#10060; |
| `progress` | Is In Progress | &#9989; | &#10060; | &#10060; |
| `trash` | Is Trashed | &#9989; | &#9989; | &#10060; |
| `unplayed_episodes` | Has Unplayed Episodes | &#10060; | &#9989; | &#10060; |
| `episode_unplayed` | Has Episodes Unplayed | &#10060; | &#9989; | &#10060; |
| `episode_duplicate` | Has Duplicate Episodes | &#10060; | &#9989; | &#10060; |
| `episode_progress` | Has Episode Progress | &#10060; | &#9989; | &#10060; |
| `episode_unmatched` | Has Episodes Unmatched | &#10060; | &#9989; | &#10060; |
| `artist_unmatched` | Is Artist's Unmatched | &#10060; | &#10060; | &#9989; |
| `album_unmatched` | Is Album's Unmatched | &#10060; | &#10060; | &#9989; |
| `track_trash` | Is Track Trashed | &#10060; | &#10060; | &#9989; |
## Smart Filter Examples
A few examples are listed below:
```yaml
collections:
Documentaries:
smart_filter:
all:
genre: Documentary
```
```yaml
collections:
Dave Chappelle Comedy:
smart_filter:
all:
actor: Dave Chappelle
genre: Comedy
```
```yaml
collections:
Top Action Movies:
smart_filter:
all:
genre: Action
sort_by: audience_rating.desc
limit: 20
```
```yaml
collections:
90s Movies:
smart_filter:
any:
year:
- 1990
- 1991
- 1992
- 1993
- 1994
- 1995
- 1996
- 1997
- 1998
- 1999
```
```yaml
collections:
90s Movies:
smart_filter:
any:
decade: 1990
```
```yaml
collections:
Best 2010+ Movies:
smart_filter:
all:
year.gte: 2010
sort_by: audience_rating.desc
limit: 20
```
If you specify TMDb Person ID's using the Detail `tmdb_person` and then tell either `actor`, `director`, `producer`, or `writer` to add `tmdb`, the script will translate the TMDb Person IDs into their names and run the filter on those names.
```yaml
collections:
Robin Williams:
smart_filter:
all:
actor: tmdb
tmdb_person: 2157
```
```yaml
collections:
Steven Spielberg:
smart_filter:
all:
director: tmdb
tmdb_person: https://www.themoviedb.org/person/488-steven-spielberg
```
```yaml
collections:
Quentin Tarantino:
smart_filter:
any:
actor: tmdb
director: tmdb
producer: tmdb
writer: tmdb
tmdb_person: 138
```

@ -0,0 +1,25 @@
# StevenLu Builders
You can find items using StevenLu's Popular Movies list on [StevenLu.com](https://movies.stevenlu.com/) (StevenLu).
No configuration is required for this builder.
| Attribute | Description | Works with Movies | Works with Shows | Works with Playlists and Custom Sort |
|:-----------------------------------------------------|:-------------------------------------------------------------------------------------|:-----------------:|:----------------:|:------------------------------------:|
| [`stevenlu_popular`](#stevenlus-popular-movies-list) | Finds every movie on [StevenLu's Popular Movies List](https://movies.stevenlu.com/). | &#9989; | &#10060; | &#9989; |
## StevenLu's Popular Movies List
Finds every movie on [StevenLu's Popular Movies List](https://movies.stevenlu.com/).
The expected input is `true`.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
StevenLu's Popular Movies:
stevenlu_popular: true
collection_order: custom
sync_mode: sync
```

@ -0,0 +1,77 @@
# Tautulli Builders
You can find items in your Plex using the features of [Tautulli](https://tautulli.com/).
[Configuring Tautulli](../../config/tautulli) in the config is required for any of these builders.
It has watch analytics that can show the most watched or most popular Movies/Shows in each Library.
| Attribute | Description | Works with Movies | Works with Shows | Works with Playlists and Custom Sort |
|:-----------------------------------------------|:------------------------------------|:-----------------:|:----------------:|:------------------------------------:|
| [`tautulli_popular`](#tautulli-popularwatched) | Gets the Tautulli Most Popular List | &#9989; | &#9989; | &#9989; |
| [`tautulli_watched`](#tautulli-popularwatched) | Gets the Tautulli Most Watched List | &#9989; | &#9989; | &#9989; |
## Tautulli Popular/Watched
Both Tautulli Popular and Tautulli Watched have the same sub-attributes detailed below.
| Attribute | Description | Required | Default |
|:---------------|:-------------------------------------------------------------------------------------|:--------:|:-------:|
| `list_days` | Number of Days to look back of the list | &#10060; | 30 |
| `list_minimum` | Minimum Number of Users Watching/Plays to add to the list | &#10060; | 30 |
| `list_size` | Number of Movies/Shows to add to this list | &#10060; | 10 |
| `list_buffer` | Number of extra Movies/Shows to grab in case you have multiple show/movie Libraries. | &#10060; | 10 |
If you have multiple movie Libraries or multiple show Libraries Tautulli combines those in the popular/watched lists so there might not be 10 movies/shows from the library to make your `list_size`.
In order to get around that, you can use the `list_buffer` attribute that defaults to 10. This will get that number more movies from Tautulli but only add to the collection until the size reaches the number in `list_size`.
So if your collection doesn't have as many movies/shows as your `list_size` attribute increase the number in the `list_buffer` attribute.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Most Popular Movies (30 Days):
sync_mode: sync
collection_order: custom
tautulli_popular:
list_days: 30
list_size: 10
```
```yaml
collections:
Most Watched Movies (30 Days):
sync_mode: sync
collection_order: custom
tautulli_watched:
list_days: 30
list_size: 10
list_buffer: 20
```
```yaml
collections:
Plex Popular:
tautulli_popular:
list_days: 30
list_size: 20
list_buffer: 20
tautulli_watched:
list_days: 30
list_size: 20
list_buffer: 20
sync_mode: sync
summary: Movies Popular on Plex
collection_order: alpha
```
```yaml
playlists:
Plex Popular:
libraries: Movies
tautulli_popular:
list_days: 30
list_size: 20
list_buffer: 20
sync_mode: sync
summary: Movies Popular on Plex
```

@ -0,0 +1,659 @@
# TMDb Builders
You can find items using the features of [TheMovieDb.org](https://www.themoviedb.org/) (TMDb).
## Standard TMDb Builders
| Attribute | Description | Works with Movies | Works with Shows | Works with Playlists and Custom Sort |
|:--------------------------------------|:---------------------------------------------------------|:-----------------:|:----------------:|:------------------------------------:|
| [`tmdb_collection`](#tmdb-collection) | Finds every item in the TMDb collection | &#9989; | &#10060; | &#10060; |
| [`tmdb_list`](#tmdb-list) | Finds every item in the TMDb List | &#9989; | &#9989; | &#9989; |
| [`tmdb_actor`](#tmdb-actor) | Finds every item in the TMDb Person's Actor Credits | &#9989; | &#9989; | &#10060; |
| [`tmdb_crew`](#tmdb-crew) | Finds every item in the TMDb Person's Crew Credits | &#9989; | &#9989; | &#10060; |
| [`tmdb_director`](#tmdb-director) | Finds every item in the TMDb Person's Director Credits | &#9989; | &#9989; | &#10060; |
| [`tmdb_producer`](#tmdb-producer) | Finds every item in the TMDb Person's Producer Credits | &#9989; | &#9989; | &#10060; |
| [`tmdb_writer`](#tmdb-writer) | Finds every item in the TMDb Person's Writer Credits | &#9989; | &#9989; | &#10060; |
| [`tmdb_movie`](#tmdb-movie) | Finds the movie specified | &#9989; | &#10060; | &#10060; |
| [`tmdb_show`](#tmdb-show) | Finds the show specified | &#10060; | &#9989; | &#10060; |
| [`tmdb_company`](#tmdb-company) | Finds every item from the TMDb company's movie/show list | &#9989; | &#9989; | &#10060; |
| [`tmdb_network`](#tmdb-network) | Finds every item from the TMDb network's show list | &#10060; | &#9989; | &#10060; |
| [`tmdb_keyword`](#tmdb-keyword) | Finds every item from the TMDb keyword's movie/show list | &#9989; | &#9989; | &#10060; |
## Standard TMDb Details Builders
| Attribute | Description | Works with Movies | Works with Shows | Works with Playlists and Custom Sort |
|:----------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------|:-----------------:|:----------------:|:------------------------------------:|
| [`tmdb_collection_details`](#tmdb-collection) | Finds every item in the TMDb collection and updates the collection with the summary, poster, and background from the TMDb collection | &#9989; | &#10060; | &#10060; |
| [`tmdb_list_details`](#tmdb-list) | Finds every item in the TMDb List and updates the collection with the description of the TMDb list | &#9989; | &#9989; | &#10060; |
| [`tmdb_actor_details`](#tmdb-actor) | Finds every item in the TMDb Person's Actor Credits with the biography and profile from the TMDb person | &#9989; | &#9989; | &#10060; |
| [`tmdb_crew_details`](#tmdb-crew) | Finds every item in the TMDb Person's Crew Credits with the biography and profile from the TMDb person | &#9989; | &#9989; | &#10060; |
| [`tmdb_director_details`](#tmdb-director) | Finds every item in the TMDb Person's Actor Credits with the biography and profile from the TMDb person | &#9989; | &#9989; | &#10060; |
| [`tmdb_producer_details`](#tmdb-producer) | Finds every item in the TMDb Person's Producer Credits with the biography and profile from the TMDb person | &#9989; | &#9989; | &#10060; |
| [`tmdb_writer_details`](#tmdb-writer) | Finds every item in the TMDb Person's Writer Credits with the biography and profile from the TMDb person | &#9989; | &#9989; | &#10060; |
| [`tmdb_movie_details`](#tmdb-movie) | Finds the movie specified and updates the collection with the summary, poster, and background from the TMDb movie | &#9989; | &#10060; | &#10060; |
| [`tmdb_show_details`](#tmdb-show) | Finds the show specified and updates the collection with the summary, poster, and background from the TMDb show | &#10060; | &#9989; | &#10060; |
## Other TMDb Builders
| Attribute | Description | Works with Movies | Works with Shows | Works with Playlists and Custom Sort |
|:------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------:|:----------------:|:------------------------------------:|
| [`tmdb_popular`](#tmdb-popular) | Finds the movies/shows in TMDb's [Popular Movies](https://www.themoviedb.org/movie)/[Popular Shows](https://www.themoviedb.org/tv) list | &#9989; | &#9989; | &#9989; |
| [`tmdb_now_playing`](#tmdb-now-playing) | Finds the movies in TMDb's [Now Playing](https://www.themoviedb.org/movie/now-playing) list | &#9989; | &#10060; | &#9989; |
| [`tmdb_top_rated`](#tmdb-top-rated) | Finds the movies/shows in TMDb's [Top Rated Movies](https://www.themoviedb.org/movie/top-rated)/[Top Rated Shows](https://www.themoviedb.org/tv/top-rated) list | &#9989; | &#9989; | &#9989; |
| [`tmdb_trending_daily`](#tmdb-trending-daily) | Finds the movies/shows in TMDb's Trending Daily list | &#9989; | &#9989; | &#9989; |
| [`tmdb_trending_weekly`](#tmdb-trending-weekly) | Finds the movies/shows in TMDb's Trending Weekly list | &#9989; | &#9989; | &#9989; |
| [`tmdb_discover`](#tmdb-discover) | Uses [TMDb's Discover Search](https://www.themoviedb.org/documentation/api/discover) to find every movie/show based on the [movie search parameters](https://developers.themoviedb.org/3/discover/movie-discover) or [show search parameters](https://developers.themoviedb.org/3/discover/tv-discover) provided | &#9989; | &#9989; | &#9989; |
## Expected Input
The builders below are expected to have the full URL to the item or the TMDb ID of the item. Multiple values are supported as either a list or a comma-separated string.
* [TMDb Collection](#tmdb-collection) and [TMDb Collection Details](#tmdb-collection)
* [TMDb List](#tmdb-list) and [TMDb List Details](#tmdb-list)
* [TMDb Actor](#tmdb-actor) and [TMDb Actor Details](#tmdb-actor)
* [TMDb Crew](#tmdb-crew) and [TMDb Crew Details](#tmdb-crew)
* [TMDb Director](#tmdb-director) and [TMDb Director Details](#tmdb-director)
* [TMDb Producer](#tmdb-producer) and [TMDb Producer Details](#tmdb-producer)
* [TMDb Writer](#tmdb-writer) and [TMDb Writer Details](#tmdb-writer)
* [TMDb Movie](#tmdb-movie) and [TMDb Movie Details](#tmdb-movie)
* [TMDb Show](#tmdb-show) and [TMDb Show Details](#tmdb-show)
* [TMDb Company](#tmdb-company)
* [TMDb Network](#tmdb-network)
The builders below are expected to have a single integer value of how many movies/shows to query.
* [TMDb Popular](#tmdb-popular)
* [TMDb Now Playing](#tmdb-now-playing)
* [TMDb Top Rated](#tmdb-top-rated)
* [TMDb Trending Daily](#tmdb-trending-daily)
* [TMDb Trending Weekly](#tmdb-trending-weekly)
[TMDb Discover](#tmdb-discover)'s attributes are detailed [below](#tmdb-discover).
## TMDb Collection
Finds every item in the TMDb collection.
```yaml
collections:
The Lord of the Rings:
tmdb_collection: https://www.themoviedb.org/collection/119
The Hobbit:
tmdb_collection: 121938
Middle Earth:
tmdb_collection:
- 119
- https://www.themoviedb.org/collection/121938
```
* You can update the collection details with the TMDb collection's summary, poster, and background by using `tmdb_collection_details`.
* You can specify multiple collections in `tmdb_collection_details` but it will only use the first one to update the collection details.
* Posters and background in the library's asset directory will be used over the collection details unless `tmdb_poster`/`tmdb_background` is also specified.
```yaml
collections:
The Lord of the Rings:
tmdb_collection_details: https://www.themoviedb.org/collection/119
The Hobbit:
tmdb_collection_details: 121938
Middle Earth:
tmdb_collection_details:
- 119
- https://www.themoviedb.org/collection/121938
```
## TMDb List
Finds every item in the TMDb List.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Top 50 Grossing Films of All Time (Worldwide):
tmdb_list: https://www.themoviedb.org/list/10
collection_order: custom
sync_mode: sync
```
```yaml
collections:
Top 50 Grossing Films of All Time (Worldwide):
tmdb_list: 10
collection_order: custom
sync_mode: sync
```
* You can update the collection details with the TMDb list's description by using `tmdb_list_details`.
* You can specify multiple lists in `tmdb_list_details` but it will only use the first one to update the collection details.
```yaml
collections:
Top 50 Grossing Films of All Time (Worldwide):
tmdb_list_details: 10
```
## TMDb Actor
Finds every item in the TMDb Person's Actor Credits.
```yaml
collections:
Robin Williams:
tmdb_actor: https://www.themoviedb.org/person/2157-robin-williams
```
```yaml
collections:
Robin Williams:
tmdb_actor: 2157
```
* You can update the collection details with the TMDb Person's biography and profile by using `tmdb_actor_details`.
* You can specify multiple people in `tmdb_actor_details` but it will only use the first one to update the collection details.
```yaml
collections:
Robin Williams:
tmdb_actor_details: 2157
```
## TMDb Crew
Finds every item in the TMDb Person's Crew Credits.
```yaml
collections:
Quentin Tarantino:
tmdb_crew: https://www.themoviedb.org/person/138-quentin-tarantino
```
```yaml
collections:
Quentin Tarantino:
tmdb_crew: 138
```
* You can update the collection details with the TMDb Person's biography and profile by using `tmdb_crew_details`.
* You can specify multiple people in `tmdb_crew_details` but it will only use the first one to update the collection details.
```yaml
collections:
Quentin Tarantino:
tmdb_crew_details: 138
```
## TMDb Director
Finds every item in the TMDb Person's Director Credits.
```yaml
collections:
Steven Spielberg:
tmdb_director: https://www.themoviedb.org/person/488-steven-spielberg
```
```yaml
collections:
Steven Spielberg:
tmdb_director: 488
```
* You can update the collection details with the TMDb Person's biography and profile by using `tmdb_director_details`.
* You can specify multiple people in `tmdb_director_details` but it will only use the first one to update the collection details.
```yaml
collections:
Steven Spielberg:
tmdb_director_details: 488
```
## TMDb Producer
Finds every item in the TMDb Person's Producer Credits.
```yaml
collections:
Adam Sandler:
tmdb_producer: https://www.themoviedb.org/person/19292-adam-sandler
```
```yaml
collections:
Adam Sandler:
tmdb_producer: 19292
```
* You can update the collection details with the TMDb Person's biography and profile by using `tmdb_producer_details`.
* You can specify multiple people in `tmdb_producer_details` but it will only use the first one to update the collection details.
```yaml
collections:
Adam Sandler:
tmdb_producer_details: 19292
```
## TMDb Writer
Finds every item in the TMDb Person's Writer Credits.
```yaml
collections:
Woody Allen:
tmdb_writer: https://www.themoviedb.org/person/1243-woody-allen
```
```yaml
collections:
Woody Allen:
tmdb_writer: 1243
```
* You can update the collection details with the TMDb Person's biography and profile by using `tmdb_writer_details`.
* You can specify multiple people in `tmdb_writer_details` but it will only use the first one to update the collection details.
```yaml
collections:
Woody Allen:
tmdb_writer_details: 1243
```
## TMDb Movie
Finds the movie specified.
```yaml
collections:
Anaconda:
tmdb_collection: https://www.themoviedb.org/collection/105995
tmdb_movie: https://www.themoviedb.org/movie/336560
```
```yaml
collections:
Anaconda:
tmdb_collection: 105995
tmdb_movie: 336560
```
* You can update the collection details with the TMDb movie's summary, poster, and background by using `tmdb_movie_details`.
* You can specify multiple movies in `tmdb_movie_details` but it will only use the first one to update the collection details.
* Posters and background in the library's asset directory will be used over the collection details unless `tmdb_poster`/`tmdb_background` is also specified.
```yaml
collections:
Anaconda:
tmdb_collection: 105995
tmdb_movie_details: 336560
```
## TMDb Show
Finds the show specified.
```yaml
collections:
Star Wars (Animated Shows):
tmdb_show:
- https://www.themoviedb.org/tv/4194-star-wars-the-clone-wars
- https://www.themoviedb.org/tv/60554-star-wars-rebels
```
```yaml
collections:
Star Wars (Animated Shows):
tmdb_show:
- 4194
- 60554
```
* You can update the collection details with the TMDb show's summary, poster, and background by using `tmdb_show_details`.
* You can specify multiple shows in `tmdb_show_details` but it will only use the first one to update the collection details.
* Posters and background in the library's asset directory will be used over the collection details unless `tmdb_poster`/`tmdb_background` is also specified.
```yaml
collections:
Star Wars (Animated Shows):
tmdb_show_details:
- 4194
- 60554
```
## TMDb Company
Finds every movie from the TMDb company's movie list.
```yaml
collections:
Studio Ghibli:
tmdb_company: 10342
```
```yaml
collections:
Studio Ghibli:
tmdb_company: https://www.themoviedb.org/company/10342
```
## TMDb Network
Finds every item from the TMDb network's movie/show list.
```yaml
collections:
CBS:
tmdb_network: 16
```
```yaml
collections:
CBS:
tmdb_network: https://www.themoviedb.org/network/16
```
## TMDb Keyword
Finds every item from the TMDb keyword's movie/show list.
```yaml
collections:
Marvel Cinematic Universe:
tmdb_keyword: 180547
```
```yaml
collections:
Marvel Cinematic Universe:
tmdb_keyword: https://www.themoviedb.org/keyword/180547
```
## TMDb Popular
Finds the movies/shows in TMDb's [Popular Movies](https://www.themoviedb.org/movie)/[Popular Shows](https://www.themoviedb.org/tv) list.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
TMDb Popular:
tmdb_popular: 30
collection_order: custom
sync_mode: sync
```
## TMDb Now Playing
Finds the movies in TMDb's [Now Playing](https://www.themoviedb.org/movie/now-playing) list.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
TMDb Now Playing:
tmdb_now_playing: 30
collection_order: custom
sync_mode: sync
```
## TMDb Top Rated
Finds the movies/shows in TMDb's [Top Rated Movies](https://www.themoviedb.org/movie/top-rated)/[Top Rated Shows](https://www.themoviedb.org/tv/top-rated) list.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
TMDb Top Rated:
tmdb_top_rated: 30
collection_order: custom
sync_mode: sync
```
## TMDb Trending Daily
Finds the movies/shows in TMDb's Trending Daily list.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
TMDb Daily Trending:
tmdb_trending_daily: 30
collection_order: custom
sync_mode: sync
```
## TMDb Trending Weekly
Finds the movies/shows in TMDb's Trending Weekly list.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
TMDb Weekly Trending:
tmdb_trending_weekly: 30
collection_order: custom
sync_mode: sync
```
## TMDb Discover
Uses [TMDb's Discover Search](https://www.themoviedb.org/documentation/api/discover) to find every movie/show based on the [movie search parameters](https://developers.themoviedb.org/3/discover/movie-discover) or [show search parameters](https://developers.themoviedb.org/3/discover/tv-discover) provided.
I've observed many attributes that begin with `with_` or `without_` being able to use `|` as an `OR` and `&` as an `AND` when specifying multiple items even though it's not listed as possible.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
| Type | Description |
|:-------------------|:--------------------------------------------------|
| String | Any number of alphanumeric characters |
| Integer | Any whole number greater than zero i.e. 2, 10, 50 |
| Number | Any number greater than zero i.e. 2.5, 7.4, 9 |
| Boolean | Must be `true` or `false` |
| Date: `MM/DD/YYYY` | Date that fits the specified format |
| Year: `YYYY` | Year must be a 4 digit integer i.e. 1990 |
### Discover Movies Parameters
| Movie Parameters | Description |
|:--------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `limit` | Specify how many movies you want returned by the query.<br>**Type:** Integer<br>**Default:** 100 |
| `region` | Specify a [ISO 3166-1 code](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) to filter release dates. Must be uppercase.<br>**Type:** `^[A-Z]{2}$` |
| `sort_by` | Choose from one of the many available sort options.<br>**Type:** Any [sort options](#sort-options) below<br>**Default:** `popularity.desc` |
| `certification_country` | Used in conjunction with the certification parameter, use this to specify a country with a valid certification.<br>**Type:** String |
| `certification` | Filter results with a valid certification from the `certification_country` parameter.<br>**Type:** String |
| `certification.lte` | Filter and only include movies that have a certification that is less than or equal to the specified value.<br>**Type:** String |
| `certification.gte` | Filter and only include movies that have a certification that is greater than or equal to the specified value.<br>**Type:** String |
| `include_adult` | A filter and include or exclude adult movies.<br>**Type:** Boolean |
| `include_video` | A filter and include or exclude videos.<br>**Type:** Boolean |
| `primary_release_year` | A filter to limit the results to a specific primary release year.<br>**Type:** Year: YYYY |
| `primary_release_date.gte` | Filter and only include movies that have a primary release date that is greater or equal to the specified value.<br>**Type:** Date: `MM/DD/YYYY` |
| `primary_release_date.lte` | Filter and only include movies that have a primary release date that is less than or equal to the specified value.<br>**Type:** Date: `MM/DD/YYYY` |
| `release_date.gte` | Filter and only include movies that have a release date (looking at all release dates) that is greater or equal to the specified value.<br>**Type:** Date: `MM/DD/YYYY` |
| `release_date.lte` | Filter and only include movies that have a release date (looking at all release dates) that is less than or equal to the specified value.<br>**Type:** Date: `MM/DD/YYYY` |
| `with_release_type` | Specify a comma (AND) or pipe (OR) separated value to filter release types by.<br>**Type:** String<br>**Values:** `1`: Premiere, `2`: Theatrical (limited), `3`: Theatrical, `4`: Digital, `5`: Physical, `6`: TV |
| `year` | A filter to limit the results to a specific year (looking at all release dates).<br>**Type:** Year: `YYYY` |
| `vote_count.gte` | Filter and only include movies that have a vote count that is greater or equal to the specified value.<br>**Type:** Integer |
| `vote_count.lte` | Filter and only include movies that have a vote count that is less than or equal to the specified value.<br>**Type:** Integer |
| `vote_average.gte` | Filter and only include movies that have a rating that is greater or equal to the specified value.<br>**Type:** Number |
| `vote_average.lte` | Filter and only include movies that have a rating that is less than or equal to the specified value.<br>**Type:** Number |
| `with_cast` | A comma-separated list of person ID's. Only include movies that have one of the ID's added as an actor.<br>**Type:** String |
| `with_crew` | A comma-separated list of person ID's. Only include movies that have one of the ID's added as a crew member.<br>**Type:** String |
| `with_people` | A comma-separated list of person ID's. Only include movies that have one of the ID's added as either an actor or a crew member.<br>**Type:** String |
| `with_companies` | A comma-separated list of production company ID's. Only include movies that have one of the ID's added as a production company.<br>**Type:** String |
| `without_companies` | Filter the results to exclude the specific production companies you specify here. AND / OR filters are supported.<br>**Type:** String |
| `with_genres` | Comma-separated value of genre ids that you want to include in the results.<br>**Type:** String |
| `without_genres` | Comma-separated value of genre ids that you want to exclude from the results.<br>**Type:** String |
| `with_keywords` | A comma-separated list of keyword ID's. Only includes movies that have one of the ID's added as a keyword.<br>**Type:** String |
| `without_keywords` | Exclude items with certain keywords. You can comma and pipe separate these values to create an 'AND' or 'OR' logic.<br>**Type:** String |
| `with_runtime.gte` | Filter and only include movies that have a runtime that is greater or equal to a value.<br>**Type:** Integer |
| `with_runtime.lte` | Filter and only include movies that have a runtime that is less than or equal to a value.<br>**Type:** Integer |
| `with_original_language` | Specify an ISO 639-1 string to filter results by their original language value.<br>**Type:** String |
| `with_title_translation` | Specify a language/country string to filter the results by if the item has a type of title translation.<br>**Type:** String<br>**Values:** `ar-AE`, `ar-SA`, `bg-BG`, `bn-BD`, `ca-ES`, `ch-GU`, `cs-CZ`, `da-DK`, `de-DE`, `el-GR`, `en-US`, `eo-EO`, `es-ES`, `es-MX`, `eu-ES`, `fa-IR`, `fi-FI`, `fr-CA`, `fr-FR`, `he-IL`, `hi-IN`, `hu-HU`, `id-ID`, `it-IT`, `ja-JP`, `ka-GE`, `kn-IN`, `ko-KR`, `lt-LT`, `ml-IN`, `nb-NO`, `nl-NL`, `no-NO`, `pl-PL`, `pt-BR`, `pt-PT`, `ro-RO`, `ru-RU`, `sk-SK`, `sl-SI`, `sr-RS`, `sv-SE`, `ta-IN`, `te-IN`, `th-TH`, `tr-TR`, `uk-UA`, `vi-VN`, `zh-CN`, `zh-TW` |
| `with_overview_translation` | Specify a language/country string to filter the results by if the item has a type of overview translation.<br>**Type:** String<br>**Values:** `ar-AE`, `ar-SA`, `bg-BG`, `bn-BD`, `ca-ES`, `ch-GU`, `cs-CZ`, `da-DK`, `de-DE`, `el-GR`, `en-US`, `eo-EO`, `es-ES`, `es-MX`, `eu-ES`, `fa-IR`, `fi-FI`, `fr-CA`, `fr-FR`, `he-IL`, `hi-IN`, `hu-HU`, `id-ID`, `it-IT`, `ja-JP`, `ka-GE`, `kn-IN`, `ko-KR`, `lt-LT`, `ml-IN`, `nb-NO`, `nl-NL`, `no-NO`, `pl-PL`, `pt-BR`, `pt-PT`, `ro-RO`, `ru-RU`, `sk-SK`, `sl-SI`, `sr-RS`, `sv-SE`, `ta-IN`, `te-IN`, `th-TH`, `tr-TR`, `uk-UA`, `vi-VN`, `zh-CN`, `zh-TW` |
| `with_watch_providers` | A comma or pipe separated list of watch provider ID's. Combine this filter with `watch_region` in order to filter your results by a specific watch provider in a specific region.<br>**Type:** String |
| `watch_region` | An [ISO 3166-1 code](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes). Combine this filter with `with_watch_providers` in order to filter your results by a specific watch provider in a specific region.<br>**Type:** String<br>**Values:** [ISO 3166-1 code](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) |
| `with_watch_monetization_types` | In combination with `watch_region`, you can filter by monetization type.<br>**Type:** String<br>**Values:** `flatrate`, `free`, `ads`, `rent`, `buy` |
### Discover Shows Parameters
| Show Parameters | Description |
|:--------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `limit` | Specify how many movies you want to be returned by the query.<br>**Type:** Integer<br>**Default:** 100 |
| `sort_by` | Choose from one of the many available sort options.<br>**Type:** Any [sort options](#sort-options) below<br>**Default:** `popularity.desc` |
| `air_date.gte` | Filter and only include TV shows that have an air date (by looking at all episodes) that is greater or equal to the specified value.<br>**Type:** Date: `MM/DD/YYYY` |
| `air_date.lte` | Filter and only include TV shows that have an air date (by looking at all episodes) that is less than or equal to the specified value.<br>**Type:** Date: `MM/DD/YYYY` |
| `first_air_date.gte` | Filter and only include TV shows that have a original air date that is greater or equal to the specified value. Can be used in conjunction with the `include_null_first_air_dates` filter if you want to include items with no air date.<br>**Type:** Date: `MM/DD/YYYY` |
| `first_air_date.lte` | Filter and only include TV shows that have a original air date that is less than or equal to the specified value. Can be used in conjunction with the `include_null_first_air_dates` filter if you want to include items with no air date.<br>**Type:** Date: `MM/DD/YYYY` |
| `first_air_date_year` | Filter and only include TV shows that have an original air date year that equal to the specified value. Can be used in conjunction with the `include_null_first_air_dates` filter if you want to include items with no air date.<br>**Type:** Year: `YYYY` |
| `include_null_first_air_dates` | Use this filter to include TV shows that don't have an air date while using any of the `first_air_date` filters.<br>**Type:** Boolean |
| `timezone` | Used in conjunction with the `air_date.gte/lte` filter to calculate the proper UTC offset.<br>**Type:** String<br>**Default:** `America/New_York` |
| `vote_count.gte` | Filter and only include TV that have a vote count that is greater or equal to the specified value.<br>**Type:** Integer |
| `vote_count.lte` | Filter and only include TV that have a vote count that is less than or equal to the specified value.<br>**Type:** Integer |
| `vote_average.gte` | Filter and only include TV that have a rating that is greater or equal to the specified value.<br>**Type:** Number |
| `vote_average.lte` | Filter and only include TV that have a rating that is less than or equal to the specified value.<br>**Type:** Number |
| `with_networks` | Comma-separated value of network ids that you want to include in the results.<br>**Type:** String |
| `with_companies` | A comma-separated list of production company ID's. Only include movies that have one of the ID's added as a production company.<br>**Type:** String |
| `without_companies` | Filter the results to exclude the specific production companies you specify here. AND / OR filters are supported.<br>**Type:** String |
| `with_genres` | Comma-separated value of genre ids that you want to include in the results.<br>**Type:** String |
| `without_genres` | Comma-separated value of genre ids that you want to exclude from the results.<br>**Type:** String |
| `with_keywords` | A comma-separated list of keyword ID's. Only includes TV shows that have one of the ID's added as a keyword.<br>**Type:** String |
| `without_keywords` | Exclude items with certain keywords. You can comma and pipe separate these values to create an 'AND' or 'OR' logic.<br>**Type:** String |
| `with_runtime.gte` | Filter and only include TV shows with an episode runtime that is greater than or equal to a value.<br>**Type:** Integer |
| `with_runtime.lte` | Filter and only include TV shows with an episode runtime that is less than or equal to a value.<br>**Type:** Integer |
| `with_original_language` | Specify an ISO 639-1 string to filter results by their original language value.<br>**Type:** String |
| `with_name_translation` | Specify a language/country string to filter the results by if the item has a type of name translation.<br>**Type:** String<br>**Values:** `ar-AE`, `ar-SA`, `bg-BG`, `bn-BD`, `ca-ES`, `ch-GU`, `cs-CZ`, `da-DK`, `de-DE`, `el-GR`, `en-US`, `eo-EO`, `es-ES`, `es-MX`, `eu-ES`, `fa-IR`, `fi-FI`, `fr-CA`, `fr-FR`, `he-IL`, `hi-IN`, `hu-HU`, `id-ID`, `it-IT`, `ja-JP`, `ka-GE`, `kn-IN`, `ko-KR`, `lt-LT`, `ml-IN`, `nb-NO`, `nl-NL`, `no-NO`, `pl-PL`, `pt-BR`, `pt-PT`, `ro-RO`, `ru-RU`, `sk-SK`, `sl-SI`, `sr-RS`, `sv-SE`, `ta-IN`, `te-IN`, `th-TH`, `tr-TR`, `uk-UA`, `vi-VN`, `zh-CN`, `zh-TW` |
| `screened_theatrically` | Filter results to include items that have been screened theatrically.<br>**Type:** Boolean |
| `with_watch_providers` | A comma or pipe separated list of watch provider ID's. Combine this filter with `watch_region` in order to filter your results by a specific watch provider in a specific region.<br>**Type:** String |
| `watch_region` | An [ISO 3166-1 code](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes). Combine this filter with `with_watch_providers` in order to filter your results by a specific watch provider in a specific region.<br>**Type:** String |
| `with_watch_monetization_types` | In combination with `watch_region`, you can filter by monetization type.<br>**Type:** String<br>**Values:** `flatrate`, `free`, `ads`, `rent`, `buy` |
| `with_status` | Filter TV shows by their status.<br>**Type:** String<br>**Values:** `0`: Returning Series, `1`: Planned, `2`: In Production, `3`: Ended, `4`: Cancelled, `5`: Pilot |
| `with_type` | Filter TV shows by their type.<br>**Type:** String<br>**Values:** `0`: Documentary, `1`: News, `2`: Miniseries, `3`: Reality, `4`: Scripted, `5`: Show, `6`: Video |
### Sort Options
| Sort Option | Movie Sort | Show Sort |
|:----------------------------|:----------:|:---------:|
| `popularity.asc` | &#9989; | &#9989; |
| `popularity.desc` | &#9989; | &#9989; |
| `original_title.asc` | &#9989; | &#10060; |
| `original_title.desc` | &#9989; | &#10060; |
| `revenue.asc` | &#9989; | &#10060; |
| `revenue.desc` | &#9989; | &#10060; |
| `release_date.asc` | &#9989; | &#10060; |
| `release_date.desc` | &#9989; | &#10060; |
| `primary_release_date.asc` | &#9989; | &#10060; |
| `primary_release_date.desc` | &#9989; | &#10060; |
| `first_air_date.asc` | &#10060; | &#9989; |
| `first_air_date.desc` | &#10060; | &#9989; |
| `vote_average.asc` | &#9989; | &#9989; |
| `vote_average.desc` | &#9989; | &#9989; |
| `vote_count.asc` | &#9989; | &#10060; |
| `vote_count.desc` | &#9989; | &#10060; |
```yaml
collections:
Movies Released in October 2020:
tmdb_discover:
primary_release_date.gte: 10/01/2020
primary_release_date.lte: 10/31/2020
```
```yaml
collections:
Popular Movies:
collection_order: custom
sync_mode: sync
tmdb_discover:
sort_by: popularity.desc
```
```yaml
collections:
Highest Rated R Movies:
collection_order: custom
sync_mode: sync
tmdb_discover:
certification_country: US
certification: R
sort_by: vote_average.desc
```
```yaml
collections:
Most Popular Kids Movies:
collection_order: custom
sync_mode: sync
tmdb_discover:
certification_country: US
certification.lte: G
sort_by: popularity.desc
```
```yaml
collections:
Highest Rated Movies From 2010:
collection_order: custom
sync_mode: sync
tmdb_discover:
primary_release_year: 2010
sort_by: vote_average.desc
```
```yaml
collections:
Best Dramas From 2014:
collection_order: custom
sync_mode: sync
tmdb_discover:
with_genres: 18
primary_release_year: 2014
sort_by: vote_average.desc
```
```yaml
collections:
Highest Rated Science Fiction Movies with Tom Cruise:
collection_order: custom
sync_mode: sync
tmdb_discover:
with_genres: 878
with_cast: 500
sort_by: vote_average.desc
```
```yaml
collections:
Highest Grossing Comedy Movies with Will Ferrell:
collection_order: custom
sync_mode: sync
tmdb_discover:
with_genres: 35
with_cast: 23659
sort_by: revenue.desc
```
```yaml
collections:
Top Rated Movies with Brad Pitt and Edward Norton:
collection_order: custom
sync_mode: sync
tmdb_discover:
with_people: 287,819
sort_by: vote_average.desc
```
```yaml
collections:
Popular Movies with David Fincher and Rooney Mara:
collection_order: custom
sync_mode: sync
tmdb_discover:
with_people: 108916,7467
sort_by: popularity.desc
```
```yaml
collections:
Top Rated Dramas:
collection_order: custom
sync_mode: sync
tmdb_discover:
with_genres: 18
sort_by: vote_average.desc
vote_count.gte: 10
```
```yaml
collections:
Highest Grossing R Movies with Liam Neeson:
collection_order: custom
sync_mode: sync
tmdb_discover:
certification_country: US
certification: R
sort_by: revenue.desc
with_cast: 3896
```

@ -0,0 +1,220 @@
# Trakt Builders
You can find items using the features of [Trakt.tv](https://trakt.tv/) (Trakt).
[Configuring Trakt](../../config/trakt) in the config is required for any of these builders.
| Attribute | Description | Works with Movies | Works with Shows | Works with Playlists and Custom Sort |
|:---------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------:|:----------------:|:------------------------------------:|
| [`trakt_list`](#trakt-list) | Finds every item in the Trakt List | &#9989; | &#9989; | &#9989; |
| [`trakt_list_details`](#trakt-list) | Finds every item in the Trakt List and updates the collection summary with the list description | &#9989; | &#9989; | &#9989; |
| [`trakt_watchlist`](#trakt-user-watchlist) | Finds every item in a Users Watchlist | &#9989; | &#9989; | &#9989; |
| [`trakt_collection`](#trakt-user-collection) | Finds every item in a Users Collection | &#9989; | &#9989; | &#9989; |
| [`trakt_trending`](#trakt-trending) | Finds the movies/shows in Trakt's Trending [Movies](https://trakt.tv/movies/trending)/[Shows](https://trakt.tv/shows/trending) list | &#9989; | &#9989; | &#9989; |
| [`trakt_popular`](#trakt-popular) | Finds the movies/shows in Trakt's Popular [Movies](https://trakt.tv/movies/popular)/[Shows](https://trakt.tv/shows/popular) list | &#9989; | &#9989; | &#9989; |
| [`trakt_recommended_personal`](#trakt-recommended) | Finds the movies/shows in Trakt's Personal Recommendations for your User [Movies](https://trakt.docs.apiary.io/#reference/recommendations/movies/get-movie-recommendations)/[Shows](https://trakt.docs.apiary.io/#reference/recommendations/shows/get-show-recommendations) | &#9989; | &#9989; | &#9989; |
| [`trakt_recommended_daily`](#trakt-recommended) | Finds the movies/shows in Trakt's Daily Recommended [Movies](https://trakt.tv/movies/recommended/daily)/[Shows](https://trakt.tv/shows/recommended/daily) list | &#9989; | &#9989; | &#9989; |
| [`trakt_recommended_weekly`](#trakt-recommended) | Finds the movies/shows in Trakt's Weekly Recommended [Movies](https://trakt.tv/movies/recommended/weekly)/[Shows](https://trakt.tv/shows/recommended/weekly) list | &#9989; | &#9989; | &#9989; |
| [`trakt_recommended_monthly`](#trakt-recommended) | Finds the movies/shows in Trakt's Monthly Recommended [Movies](https://trakt.tv/movies/recommended/monthly)/[Shows](https://trakt.tv/shows/recommended/monthly) list | &#9989; | &#9989; | &#9989; |
| [`trakt_recommended_yearly`](#trakt-recommended) | Finds the movies/shows in Trakt's Yearly Recommended [Movies](https://trakt.tv/movies/recommended/yearly)/[Shows](https://trakt.tv/shows/recommended/yearly) list | &#9989; | &#9989; | &#9989; |
| [`trakt_recommended_all`](#trakt-recommended) | Finds the movies/shows in Trakt's All-Time Recommended [Movies](https://trakt.tv/movies/recommended/all)/[Shows](https://trakt.tv/shows/recommended/all) list | &#9989; | &#9989; | &#9989; |
| [`trakt_watched_daily`](#trakt-watched) | Finds the movies/shows in Trakt's Daily Watched [Movies](https://trakt.tv/movies/watched/daily)/[Shows](https://trakt.tv/shows/watched/daily) list | &#9989; | &#9989; | &#9989; |
| [`trakt_watched_weekly`](#trakt-watched) | Finds the movies/shows in Trakt's Weekly Watched [Movies](https://trakt.tv/movies/watched/weekly)/[Shows](https://trakt.tv/shows/watched/weekly) list | &#9989; | &#9989; | &#9989; |
| [`trakt_watched_monthly`](#trakt-watched) | Finds the movies/shows in Trakt's Monthly Watched [Movies](https://trakt.tv/movies/watched/monthly)/[Shows](https://trakt.tv/shows/watched/monthly) list | &#9989; | &#9989; | &#9989; |
| [`trakt_watched_yearly`](#trakt-watched) | Finds the movies/shows in Trakt's Yearly Watched [Movies](https://trakt.tv/movies/watched/yearly)/[Shows](https://trakt.tv/shows/watched/yearly) list | &#9989; | &#9989; | &#9989; |
| [`trakt_watched_all`](#trakt-watched) | Finds the movies/shows in Trakt's All-Time Watched [Movies](https://trakt.tv/movies/watched/all)/[Shows](https://trakt.tv/shows/watched/all) list | &#9989; | &#9989; | &#9989; |
| [`trakt_collected_daily`](#trakt-collected) | Finds the movies/shows in Trakt's Daily Collected [Movies](https://trakt.tv/movies/collected/daily)/[Shows](https://trakt.tv/shows/collected/daily) list | &#9989; | &#9989; | &#9989; |
| [`trakt_collected_weekly`](#trakt-collected) | Finds the movies/shows in Trakt's Weekly Collected [Movies](https://trakt.tv/movies/collected/weekly)/[Shows](https://trakt.tv/shows/collected/weekly) list | &#9989; | &#9989; | &#9989; |
| [`trakt_collected_monthly`](#trakt-collected) | Finds the movies/shows in Trakt's Monthly Collected [Movies](https://trakt.tv/movies/collected/monthly)/[Shows](https://trakt.tv/shows/collected/monthly) list | &#9989; | &#9989; | &#9989; |
| [`trakt_collected_yearly`](#trakt-collected) | Finds the movies/shows in Trakt's Yearly Collected [Movies](https://trakt.tv/movies/collected/yearly)/[Shows](https://trakt.tv/shows/collected/yearly) list | &#9989; | &#9989; | &#9989; |
| [`trakt_collected_all`](#trakt-collected) | Finds the movies/shows in Trakt's All-Time Collected [Movies](https://trakt.tv/movies/collected/all)/[Shows](https://trakt.tv/shows/collected/all) list | &#9989; | &#9989; | &#9989; |
| [`trakt_boxoffice`](#trakt-box-office) | Finds the 10 movies in Trakt's Top Box Office [Movies](https://trakt.tv/movies/boxoffice) list | &#9989; | &#10060; | &#9989; |
## Trakt List
Finds every item in the Trakt List.
The expected input is a Trakt List URL. Multiple values are supported as either a list or a comma-separated string.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Christmas:
trakt_list:
- https://trakt.tv/users/movistapp/lists/christmas-movies
- https://trakt.tv/users/2borno2b/lists/christmas-movies-extravanganza
sync_mode: sync
```
```yaml
collections:
Reddit Top 250:
trakt_list: https://trakt.tv/users/jay-greene/lists/reddit-top-250-2019-edition
collection_order: custom
sync_mode: sync
```
* You can update the collection details with the Trakt List's description by using `trakt_list_details`.
* You can specify multiple collections in `trakt_list_details` but it will only use the first one to update the collection summary.
```yaml
collections:
Reddit Top 250:
trakt_list_details: https://trakt.tv/users/jay-greene/lists/reddit-top-250-2019-edition
collection_order: custom
sync_mode: sync
```
## Trakt User Watchlist
Finds every item in a Users Watchlist.
The expected input is a user's Trakt Username or `me`. Multiple values are supported as either a list or a comma-separated string.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Trakt Watchlist:
trakt_watchlist: me
collection_order: custom
sync_mode: sync
```
## Trakt User Collection
Finds every item in a Users Collection.
The expected input is a user's Trakt Username or `me`. Multiple values are supported as either a list or a comma-separated string.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Trakt Collection:
trakt_collection:
- me
- traktbuddy
sync_mode: sync
```
## Trakt Trending
Finds the movies/shows in Trakt's Trending [Movies](https://trakt.tv/movies/trending)/[Shows](https://trakt.tv/shows/trending) list.
The expected input is a single integer value of how many movies/shows to query.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Trakt Trending:
trakt_trending: 30
collection_order: custom
sync_mode: sync
```
## Trakt Popular
Finds the movies/shows in Trakt's Popular [Movies](https://trakt.tv/movies/popular)/[Shows](https://trakt.tv/shows/popular) list.
The expected input is a single integer value of how many movies/shows to query.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Trakt Popular:
trakt_popular: 30
collection_order: custom
sync_mode: sync
```
## Trakt Recommended
Finds the movies/shows in Trakt's Recommended lists.
| Builder | Period | Movie List | Show List |
|:-----------------------------|:--------:|:--------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------:|
| `trakt_recommended_personal` | Custom | [Movies](https://trakt.docs.apiary.io/#reference/recommendations/movies/get-movie-recommendations) | [Shows](https://trakt.docs.apiary.io/#reference/recommendations/shows/get-show-recommendations) |
| `trakt_recommended_daily` | Daily | [Daily Movies](https://trakt.tv/movies/recommended/daily) | [Daily Shows](https://trakt.tv/shows/recommended/daily) |
| `trakt_recommended_weekly` | Weekly | [Weekly Movies](https://trakt.tv/movies/recommended/weekly) | [Weekly Shows](https://trakt.tv/shows/recommended/weekly) |
| `trakt_recommended_monthly` | Monthly | [Monthly Movies](https://trakt.tv/movies/recommended/monthly) | [Monthly Shows](https://trakt.tv/shows/recommended/monthly) |
| `trakt_recommended_yearly` | Yearly | [Yearly Movies](https://trakt.tv/movies/recommended/yearly) | [Yearly Shows](https://trakt.tv/shows/recommended/yearly) |
| `trakt_recommended_all` | All-Time | [All-Time Movies](https://trakt.tv/movies/recommended/all) | [All-Time Shows](https://trakt.tv/shows/recommended/all) |
The expected input is a single integer value of how many movies/shows to query.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Trakt Recommended:
trakt_recommended_weekly: 30
collection_order: custom
sync_mode: sync
```
## Trakt Watched
Finds the movies/shows in Trakt's Watched lists.
| Builder | Period | Movie List | Show List |
|:------------------------|:--------:|:---------------------------------------------------------:|:-------------------------------------------------------:|
| `trakt_watched_daily` | Daily | [Daily Movies](https://trakt.tv/movies/watched/daily) | [Daily Shows](https://trakt.tv/shows/watched/daily) |
| `trakt_watched_weekly` | Weekly | [Weekly Movies](https://trakt.tv/movies/watched/weekly) | [Weekly Shows](https://trakt.tv/shows/watched/weekly) |
| `trakt_watched_monthly` | Monthly | [Monthly Movies](https://trakt.tv/movies/watched/monthly) | [Monthly Shows](https://trakt.tv/shows/watched/monthly) |
| `trakt_watched_yearly` | Yearly | [Yearly Movies](https://trakt.tv/movies/watched/yearly) | [Yearly Shows](https://trakt.tv/shows/watched/yearly) |
| `trakt_watched_all` | All-Time | [All-Time Movies](https://trakt.tv/movies/watched/all) | [All-Time Shows](https://trakt.tv/shows/watched/all) |
The expected input is a single integer value of how many movies/shows to query.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Trakt Watched:
trakt_watched_weekly: 30
collection_order: custom
sync_mode: sync
```
## Trakt Collected
Finds the movies/shows in Trakt's Collected [Movies](https://trakt.tv/movies/collected/weekly)/[Shows](https://trakt.tv/shows/collected/weekly) list.
| Builder | Period | Movie List | Show List |
|:--------------------------|:--------:|:-----------------------------------------------------------:|:---------------------------------------------------------:|
| `trakt_collected_daily` | Daily | [Daily Movies](https://trakt.tv/movies/collected/daily) | [Daily Shows](https://trakt.tv/shows/collected/daily) |
| `trakt_collected_weekly` | Weekly | [Weekly Movies](https://trakt.tv/movies/collected/weekly) | [Weekly Shows](https://trakt.tv/shows/collected/weekly) |
| `trakt_collected_monthly` | Monthly | [Monthly Movies](https://trakt.tv/movies/collected/monthly) | [Monthly Shows](https://trakt.tv/shows/collected/monthly) |
| `trakt_collected_yearly` | Yearly | [Yearly Movies](https://trakt.tv/movies/collected/yearly) | [Yearly Shows](https://trakt.tv/shows/collected/yearly) |
| `trakt_collected_all` | All-Time | [All-Time Movies](https://trakt.tv/movies/collected/all) | [All-Time Shows](https://trakt.tv/shows/collected/all) |
The expected input is a single integer value of how many movies/shows to query.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Trakt Collected:
trakt_collected_weekly: 30
collection_order: custom
sync_mode: sync
```
## Trakt Box Office
Finds the 10 movies in Trakt's Top Box Office [Movies](https://trakt.tv/movies/boxoffice) list.
The expected input is true.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Trakt Collected:
trakt_boxoffice: true
collection_order: custom
sync_mode: sync
```

@ -0,0 +1,110 @@
# TVDb Builders
You can find items using the features of [TheTVDb.com](https://www.thetvdb.com/) (TVDb).
No configuration is required for these builders.
| Attribute | Description | Works with Movies | Works with Shows | Works with Playlists and Custom Sort |
|:------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------:|:----------------:|:------------------------------------:|
| [`tvdb_list`](#tvdb-list) | Finds every item in a [TVDb List](https://www.thetvdb.com/lists) or [TVDb Userlist](https://www.thetvdb.com/lists/custom) | &#9989; | &#9989; | &#9989; |
| [`tvdb_list_details`](#tvdb-list) | Finds every item in a [TVDb List](https://www.thetvdb.com/lists) or [TVDb Userlist](https://www.thetvdb.com/lists/custom) and updates the collection summary with the TVDb list description | &#9989; | &#9989; | &#9989; |
| [`tvdb_show`](#tvdb-show) | Finds the series specified | &#10060; | &#9989; | &#10060; |
| [`tvdb_show_details`](#tvdb-show) | Finds the series specified and updates the collection with the summary, poster, and background from the TVDb series | &#10060; | &#9989; | &#10060; |
| [`tvdb_movie`](#tvdb-movie) | Finds the movie specified | &#9989; | &#10060; | &#10060; |
| [`tvdb_movie_details`](#tvdb-movie) | Finds the movie specified and updates the collection with the summary, poster, and background from the TVDb movie | &#9989; | &#10060; | &#10060; |
## TVDb List
Finds every item in a [TVDb List](https://www.thetvdb.com/lists) or [TVDb Userlist](https://www.thetvdb.com/lists/custom)
The expected input is a TVDb List URL or TVDb Userlist URL. Multiple values are supported as either a list or a comma-separated string.
The `sync_mode: sync` and `collection_order: custom` Details are recommended since the lists are continuously updated and in a specific order.
```yaml
collections:
Arrowverse:
tvdb_list: https://www.thetvdb.com/lists/arrowverse
collection_order: custom
sync_mode: sync
```
```yaml
collections:
Saved by the Bell:
tvdb_list: https://www.thetvdb.com/lists/6957
collection_order: custom
sync_mode: sync
```
* You can update the collection details with the TVDb list's description by using `tvdb_list_details`.
* You can specify multiple lists in `tvdb_list_details` but it will only use the first one to update the collection details.
```yaml
collections:
Arrowverse:
tvdb_list_details: https://www.thetvdb.com/lists/arrowverse
collection_order: custom
sync_mode: sync
```
## TVDb Show
Finds the show specified
The expected input is a TVDb Series ID or TVDb Series URL. Multiple values are supported as either a list or a comma-separated string.
```yaml
collections:
Star Wars (Animated Shows):
tvdb_show: 83268, 283468
```
```yaml
collections:
Star Wars (Animated Shows):
tvdb_show:
- https://www.thetvdb.com/series/star-wars-the-clone-wars
- https://www.thetvdb.com/series/star-wars-rebels
```
* You can update the collection details with the TVDb show's summary, poster, and background by using `tvdb_show_details`.
* You can specify multiple shows in `tvdb_show_details` but it will only use the first one to update the collection details.
* Posters and background in the library's asset directory will be used over the collection details unless `tvdb_poster`/`tvdb_background` is also specified.
```yaml
collections:
Star Wars (Animated Shows):
tvdb_show_details: 83268, 283468
```
## TVDb Movie
Finds the movie specified
The expected input is a TVDb Movie ID or TVDb Movie URL. Multiple values are supported as either a list or a comma-separated string.
```yaml
collections:
The Lord of the Rings:
tvdb_movie: 107, 157, 74
```
```yaml
collections:
The Lord of the Rings:
tvdb_movie:
- https://www.thetvdb.com/movies/the-lord-of-the-rings-the-fellowship-of-the-ring
- https://www.thetvdb.com/movies/the-lord-of-the-rings-the-two-towers
- https://www.thetvdb.com/movies/the-lord-of-the-rings-the-return-of-the-king
```
* You can update the collection details with the TVDb movie's summary, poster, and background by using `tvdb_movie_details`.
* You can specify multiple movies in `tvdb_movie_details` but it will only use the first one to update the collection details.
* Posters and background in the library's asset directory will be used over the collection details unless `tvdb_poster`/`tvdb_background` is also specified.
```yaml
collections:
The Lord of the Rings:
tvdb_movie_details:
- https://www.thetvdb.com/movies/the-lord-of-the-rings-the-fellowship-of-the-ring
- https://www.thetvdb.com/movies/the-lord-of-the-rings-the-two-towers
- https://www.thetvdb.com/movies/the-lord-of-the-rings-the-return-of-the-king
```

@ -0,0 +1,71 @@
# Radarr/Sonarr Details
## Radarr Details
All the following attributes can override the global/library [Radarr](../../config/radarr) attributes which are the default unless otherwise specified.
| Attribute | Description & Values |
|:-------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `radarr_add_missing` | **Description:** Override Radarr `add` attribute<hr>**Values:** `true` or `false` |
| `radarr_add_existing` | **Description:** Override Radarr `add_existing` attribute<hr>**Values:** `true` or `false` |
| `radarr_folder` | **Description:** Override Radarr `root_folder_path` attribute<hr>**Values:** Folder Path |
| `radarr_monitor` | **Description:** Override Radarr `monitor` attribute<hr>**Values:** `true` or `false` |
| `radarr_availability` | **Description:** Override Radarr `availability` attribute<hr>**Values:** `announced`, `cinemas`, `released`, `db` |
| `radarr_quality` | **Description:** Override Radarr `quality_profile` attribute<hr>**Values:** Radarr Quality Profile |
| `radarr_tag` | **Description:** Override Radarr `tag` attribute<hr>**Values:** List or comma-separated string of tags |
| `radarr_search` | **Description:** Override Radarr `search` attribute<hr>**Values:** `true` or `false` |
| `item_radarr_tag` | **Description:** Used to append a tag in Radarr for every movie found by the builders that's in Radarr<hr>**Values:** List or comma-separated string of tags |
| `item_radarr_tag.remove` | **Description:** Used to remove existing tags in Radarr for every movie found by the builders that's in Radarr<hr>**Values:** List or comma-separated string of tags |
| `item_radarr_tag.sync` | **Description:** Matches the tags in Radarr for every movie found by the builders that's in Radarr with the provided tags<hr>**Values:** List or comma-separated string of tags |
## Sonarr Details
All the following attributes can override the global/library [Sonarr](../../config/sonarr) attributes which are the default unless otherwise specified.
| Attribute | Description & Values |
|:-------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `sonarr_add_missing` | **Description:** Override Sonarr `add` attribute<hr>**Values:** `true` or `false` |
| `sonarr_add_existing` | **Description:** Override Sonarr `add_existing` attribute<hr>**Values:** `true` or `false` |
| `sonarr_folder` | **Description:** Override Sonarr `root_folder_path` attribute<hr>**Values:** Folder Path |
| `sonarr_monitor` | **Description:** Override Sonarr `monitor` attribute<hr>**Values:** `all`, `future`, `missing`, `existing`, `pilot`, `first`, `latest`, `none` |
| `sonarr_quality` | **Description:** Override Sonarr `quality_profile` attribute<hr>**Values:** Sonarr Quality Profile |
| `sonarr_language` | **Description:** Override Sonarr `language_profile` attribute<hr>**Values:** Sonarr Language Profile |
| `sonarr_series` | **Description:** Override Sonarr `series_type` attribute<hr>**Values:** `standard`, `daily`, `anime` |
| `sonarr_season` | **Description:** Override Sonarr `season_folder` attribute<hr>**Values:** `true` or `false` |
| `sonarr_tag` | **Description:** Override Sonarr `tag` attribute<hr>**Values:** List or comma-separated string of tags |
| `sonarr_search` | **Description:** Override Sonarr `search` attribute<hr>**Values:** `true` or `false` |
| `sonarr_cutoff_search` | **Description:** Override Sonarr `cutoff_search` attribute<hr>**Values:** `true` or `false` |
| `item_sonarr_tag` | **Description:** Used to append a tag in Sonarr for every series found by the builders that's in Sonarr<hr>**Values:** List or comma-separated string of tags |
| `item_sonarr_tag.remove` | **Description:** Used to remove existing tags in Sonarr for every series found by the builders that's in Sonarr<hr>**Values:** List or comma-separated string of tags |
| `item_sonarr_tag.sync` | **Description:** Matches the tags in Sonarr for every series found by the builders that's in Sonarr with the provided tags<hr>**Values:** List or comma-separated string of tags |
## Adding to Arr
You can add items to Radarr/Sonarr in two different ways.
1. Items found by PMM that are missing from your collections/playlists.
2. Items found by PMM that already exist in Plex but are not in Radarr/Sonarr.
### Arr Add Missing
When `radarr_add_missing`/`sonarr_add_missing` are true the items missing from the collection/playlist will be added to Radarr/Sonarr.
### Arr Add Existing
When `radarr_add_existing`/`sonarr_add_existing` are true the items that exist in the collection/playlist will be added to Radarr/Sonarr.
If your Radarr/Sonarr has different file system mappings from your plex use `radarr_path`/`sonarr_path` along with `plex_path` from your [Radarr](../../config/radarr)/[Sonarr](../../config/sonarr) global config settings.
### Radarr Add Details
When adding a movie in Radarr you get the screen below to set these options use `radarr_folder`, `radarr_monitor`, `radarr_availability`, `radarr_quality`, `radarr_tag`, and `radarr_search`.
![Radarr Details](radarr.png)
### Sonarr Add Details
When adding a movie in Sonarr you get the screen below to set these options use `sonarr_folder`, `sonarr_monitor`, `sonarr_quality`, `sonarr_language`, `sonarr_series`, `sonarr_season`, `sonarr_tag`, `sonarr_search`, and `sonarr_cutoff_search`.
![Sonarr Details](sonarr.png)
## Arr Edit Details
When editing the details of items that exist in the collection/playlist and in Radarr/Sonarr use `item_radarr_tag` and `item_sonarr_tag`

@ -0,0 +1,111 @@
# Metadata Details
## Collection/Playlist Details
All the following attributes update various details of the collection/playlist's Metadata.
Only `tmdb_person` works with Playlists.
| Attribute | Description & Values |
|:-------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `tmdb_person` | **Description:** Changes summary and poster to a TMDb Person's biography and profile as well as allow the people specified to be used in [Plex Searches](../builders/plex.md#plex-search).<br>**Values:** TMDb Person ID (List or Comma-separated string) |
| `sort_title` | **Description:** Changes the sort title.<br>You can "promote" certain collections to the top of a library by creating a sort title starting with a `+` or "demote" certain collections to the bottom of a library by creating a sort title starting with a `~`.<br>**Values:** Text to change Sort Title |
| `content_rating` | **Description:** Changes the content rating.<br>**Values:** Text to change Content Rating |
| `label` | **Description:** Appends new labels.<br>**Values:** Comma-separated string of labels to append |
| `label.remove` | **Description:** Removes existing labels from the collection.<br>**Values:** Comma-separated string of labels to remove |
| `label.sync` | **Description:** Matches the labels of the collection to the labels provided (Leave blank to remove all labels)<br>**Values:** Comma-separated string of labels to sync |
| `collection_mode` | **Description:** Changes the Collection Mode<br>**Values:**<table class="clearTable"><tr><td>`default`</td><td>Library default</td></tr><tr><td>`hide`</td><td>Hide Collection</td></tr><tr><td>`hide_items`</td><td>Hide Items in this Collection</td></tr><tr><td>`show_items`</td><td>Show this Collection and its Items</td></tr></table> |
| `collection_order` | **Description:** Changes the Collection Order<br>When using `custom` you can only have a single builder in the collection.<br>**Values:**<table class="clearTable"><tr><td>`release`</td><td>Order Collection by Release Dates</td></tr><tr><td>`alpha`</td><td>Order Collection Alphabetically</td></tr><tr><td>`custom`</td><td>Order Collection Via the Builder Order</td></tr><tr><td>[Any `plex_search` Sort Option](../builders/plex.md#sort-options)</td><td>Order Collection by any `plex_search` Sort Option</td></tr></table> |
| `collection_level` | **Description:** Make season, episode, album or track collections from `plex_all`, `plex_search`, `trakt_list`, or `imdb_list` Builders and Filters<br>**Values:**<table class="clearTable"><tr><td>`season`</td><td>Collection contains seasons</td></tr><tr><td>`episode`</td><td>Collection contains episodes</td></tr><tr><td>`album`</td><td>Collection contains albums</td></tr><tr><td>`track`</td><td>Collection contains tracks</td></tr></table> |
| `visible_library` | **Description:** Changes collection visible on Library (Only works with Plex Pass)<br>**Values:**<table class="clearTable"><tr><td>`true`</td><td>Visible</td></tr><tr><td>`false`</td><td>Not Visible</td></tr><tr><td>[Any `schedule` Option](schedule)</td><td>Visible When Scheduled</td></tr></table> |
| `visible_home` | **Description:** Changes collection visible on Home (Only works with Plex Pass)<br>**Values:**<table class="clearTable"><tr><td>`true`</td><td>Visible</td></tr><tr><td>`false`</td><td>Not Visible</td></tr><tr><td>[Any `schedule` Option](schedule)</td><td>Visible When Scheduled</td></tr></table> |
| `visible_shared` | **Description:** Changes collection visible on Shared Users' Home (Only works with Plex Pass)<br>**Values:**<table class="clearTable"><tr><td>`true`</td><td>Visible</td></tr><tr><td>`false`</td><td>Not Visible</td></tr><tr><td>[Any `schedule` Option](schedule)</td><td>Visible When Scheduled</td></tr></table> |
| `url_theme` | **Description:** Changes the Collection Theme to the URL provided.<br>**Values:** URL to mp3 file |
| `file_theme` | **Description:** Changes the Collection Theme to the file location provided.<br>**Values:** Path to mp3 file |
* Here's an example of how the collections can look on the Home Page.
### Pinned Collections Example
![Display](display.png)
## Item Metadata Details
All the following attributes update various details of the metadata for every item in the collection.
None of these details work with Playlists.
| Attribute | Description & Values |
|:--------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `item_label` | **Description:** Appends new labels to every movie/show in the collection<br>**Values:** Comma-separated string of labels to append |
| `item_label.remove` | **Description:** Removes existing labels from every movie/show in the collection<br>**Values:** Comma-separated string of labels to remove |
| `item_label.sync` | **Description:** Matches the labels of every movie/show in the collection to the labels provided (Leave blank to remove all labels)<br>**Values:** Comma-separated string of labels to sync |
| `non_item_remove_label` | **Description:** Matches every movie/show that has the given label and is not in the collection and removes the label<br>**Values:** Comma-separated string of labels to remove |
| `item_lock_poster` | **Description:** Locks/Unlocks the poster of every movie/show in the collection<br>**Default:** `None`<br>**Values:**<table class="clearTable"><tr><td>`true`</td><td>Lock</td></tr><tr><td>`false`</td><td>Unlock</td></tr></table> |
| `item_lock_background` | **Description:** Locks/Unlocks the background of every movie/show in the collection<br>**Default:** `None`<br>**Values:**<table class="clearTable"><tr><td>`true`</td><td>Lock</td></tr><tr><td>`false`</td><td>Unlock</td></tr></table> |
| `item_lock_title` | **Description:** Locks/Unlocks the title of every movie/show in the collection<br>**Default:** `None`<br>**Values:**<table class="clearTable"><tr><td>`true`</td><td>Lock</td></tr><tr><td>`false`</td><td>Unlock</td></tr></table> |
| `item_overlay` | **Description:** Adds and overlay image to the poster of every movie/show in the collection see [Overlay Details](overlay) for more information.<br>**Values:** Name of overlay to be applied |
| `item_assets` | **Description:** Checks your assets folders for assets of every movie/show in the collection<br>**Default:** `false`<br>**Values:** `true` or `false` |
| `item_refresh` | **Description:** Refreshes the metadata of every movie/show in the collection<br>**Default:** `false`<br>**Values:** `true` or `false` |
| `item_refresh_delay` | **Description:** Amount of time to wait between each `item_refresh` of every movie/show in the collection<br>**Default:** `0`<br>**Values:** Number greater then `0` |
| `item_tmdb_season_titles` | **Description:** Changes the season titles of every show in the collection to match TMDb<br>**Default:** `false`<br>**Values:** `true` or `false` |
| `item_episode_sorting`<sup>1</sup> | **Description:** Changes the episode sorting of every show in the collection<br>**Values:**<table class="clearTable"><tr><td>`default`</td><td>Library default</td></tr><tr><td>`oldest`</td><td>Oldest first</td></tr><tr><td>`newest`</td><td>Newest first</td></tr></table> |
| `item_keep_episodes`<sup>1</sup> | **Description:** Changes the keep episodes of every show in the collection<br>**Values:**<table class="clearTable"><tr><td>`all`</td><td>All episodes</td></tr><tr><td>`5_latest`</td><td>5 latest episodes</td></tr><tr><td>`3_latest`</td><td>3 latest episodes</td></tr><tr><td>`latest`</td><td>Latest episodes</td></tr><tr><td>`past_3`</td><td>Episodes added in the past 3 days</td></tr><tr><td>`past_7`</td><td>Episodes added in the past 7 days</td></tr><tr><td>`past_30`</td><td>Episodes added in the past 30 days</td></tr></table> |
| `item_delete_episodes`<sup>1</sup> | **Description:** Changes the delete episodes of every show in the collection<br>**Values:**<table class="clearTable"><tr><td>`never`</td><td>Never</td></tr><tr><td>`day`</td><td>After a day</td></tr><tr><td>`week`</td><td>After a week</td></tr><tr><td>`refresh`</td><td>On next refresh</td></tr></table> |
| `item_season_display`<sup>1</sup> | **Description:** Changes the season display of every show in the collection<br>**Values:**<table class="clearTable"><tr><td>`default`</td><td>Library default</td></tr><tr><td>`show`</td><td>Show</td></tr><tr><td>`hide`</td><td>Hide</td></tr></table> |
| `item_episode_ordering`<sup>1</sup> | **Description:** Changes the episode ordering of every show in the collection<br>**Values:**<table class="clearTable"><tr><td>`default`</td><td>Library default</td></tr><tr><td>`tmdb_aired`</td><td>The Movie Database (Aired)</td></tr><tr><td>`tvdb_aired`</td><td>TheTVDb (Aired)</td></tr><tr><td>`tvdb_dvd`</td><td>TheTVDb (DVD)</td></tr><tr><td>`tvdb_absolute`</td><td>TheTVDb (Absolute)</td></tr></table> |
| `item_metadata_language`<sup>2</sup> | **Description:** Changes the metadata language of every movie/show in the collection<br>**Values:** `default`, `ar-SA`, `ca-ES`, `cs-CZ`, `da-DK`, `de-DE`, `el-GR`, `en-AU`, `en-CA`, `en-GB`, `en-US`, `es-ES`, `es-MX`, `et-EE`, `fa-IR`, `fi-FI`, `fr-CA`, `fr-FR`, `he-IL`, `hi-IN`, `hu-HU`, `id-ID`, `it-IT`, `ja-JP`, `ko-KR`, `lt-LT`, `lv-LV`, `nb-NO`, `nl-NL`, `pl-PL`, `pt-BR`, `pt-PT`, `ro-RO`, `ru-RU`, `sk-SK`, `sv-SE`, `th-TH`, `tr-TR`, `uk-UA`, `vi-VN`, `zh-CN`, `zh-HK`, `zh-TW` |
| `item_use_original_title`<sup>2</sup> | **Description:** Changes the use original title of every movie/show in the collection<br>**Values:**<table class="clearTable"><tr><td>`default`</td><td>Library default</td></tr><tr><td>`no`</td><td>No</td></tr><tr><td>`yes`</td><td>Yes</td></tr></table> |
<sup>1</sup> Only works with TV Show Libraries
<sup>2</sup> Must be using the **New Plex Movie Agent** or the **New Plex TV Agent**
## Summary Details
All the following attributes update the summary of the collection/playlist from various sources.
All of these details work with Playlists.
| Attribute | Description & Values |
|:-------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `summary` | **Description:** Changes summary to the Text Provided<br>**Values:** Text to change Summary |
| `tmdb_summary` | **Description:** Changes summary to the TMDb Movie/Collection summary for a movie library or the TMDb Show summary for a show library<br>**Values:** TMDb Movie/Show/Collection ID |
| `tmdb_description` | **Description:** Changes summary to the TMDb List Description<br>**Values:** TMDb List ID |
| `tmdb_biography` | **Description:** Changes summary to the TMDb Person's biography<br>**Values:** TMDb Person ID |
| `tvdb_summary` | **Description:** Changes summary to the TVDb Movie summary for a movie library or the TVDb Show summary for a show library<br>**Values:** TVDb Movie/Show ID or URL |
| `tvdb_description` | **Description:** Changes summary to the TVDb List Description<br>**Values:** TVDb List URL |
| `trakt_description` | **Description:** Changes summary to the Trakt List Description<br>**Values:** Trakt List URL |
| `letterboxd_description` | **Description:** Changes summary to the Letterboxd List Description<br>**Values:** Letterboxd List URL |
## Poster Details
All the following attributes update the poster of the collection/playlist from various sources.
All of these details work with Playlists.
If no poster is specified the script will look in the library's [Image Asset Directories](../../home/guides/assets) for a folder named either the collection/playlist name or the `name_mapping` if specified and look for a `poster.ext` file in that folder (replacing .ext with the image extension).
| Attribute | Description & Values |
|:-------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `url_poster` | **Description:** Changes poster to the URL<br>**Values:** URL of image publicly available on the internet |
| `tmdb_poster` | **Description:** Changes poster to the TMDb Movie/Collection poster for a movie library or the TMDb Show poster for a show library<br>**Values:** TMDb Movie/Show/Collection ID |
| `tmdb_list_poster` | **Description:** Changes poster to the TMDb List poster<br>**Values:** TMDb List ID |
| `tmdb_profile` | **Description:** Changes poster to the TMDb Person's profile<br>**Values:** TMDb Person ID |
| `tvdb_poster` | **Description:** Changes poster to the TVDb Movie poster for a movie library or the TVDb Show poster for a show library<br>**Values:** TVDb Movie/Show ID or URL |
| `file_poster` | **Description:** Changes poster to the image in the file system<br>**Values:** Path to image in the file system |
## Background Details
All the following attributes update the background of the collection/playlist from various sources.
All of these details work with Playlists.
If no background is specified the script will look in the library's [Image Asset Directories](../../home/guides/assets) for a folder named either the collection/playlist name or the `name_mapping` if specified and look for a `background.ext` file in that folder (replacing .ext with the image extension).
| Attribute | Description & Values |
|:------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `url_background` | **Description:** Changes background to the URL<br>**Values:** URL of image publicly available on the internet |
| `tmdb_background` | **Description:** Changes background to the TMDb Movie/Collection background for a movie library or the TMDb Show background for a show library<br>**Values:** TMDb Movie/Show/Collection ID |
| `tvdb_background` | **Description:** Changes background to the TVDb Movie background for a movie library or the TVDb Show background for a show library<br>**Values:** TVDb Movie/Show ID or URL |
| `file_background` | **Description:** Changes background to the image in the file system<br>**Values:** Path to image in the file system |

@ -0,0 +1,175 @@
# Image Overlay Detail
In order to add an overlay to a set of items you must add `item_overlay: OVERLAY_NAME` to the collection config, where `OVERLAY_NAME` matches the exact name of a folder in your `overlays` directory.
Your `overlays` directory must be inside your config folder structured like below:
```
config
├── overlays
│ ├── OVERLAY_NAME
│ ├── overlay.png
```
* `OVERLAY_NAME` is the folder contacting your `overlay.png` and its name is what you give `item_overlay` to refer to this specific overlay.
* `overlay.png` is the overlay file with the banner. You can create you're own with this [PSD](https://github.com/meisnate12/Plex-Meta-Manager/blob/master/overlays.psd). The font can be found [here](https://www.dafontfree.net/freefonts-eurostile-extended-f123859.htm).
* An item can only be in one overlay search so make sure you exclude other searches when using multiple overlays.
* Posters will be backed up in the overlay director and if an item is removed from the search the original poster should be added back.
* `revert_overlay` can be added to an overlay collection configuration to revert all movies changed by that overlay back to their original posters.
## Examples
### Example Folder Structure
This is an example of the default set found [here](https://github.com/meisnate12/Plex-Meta-Manager/tree/master/config/overlays) which would have 5 overlay options `4K`, `4K-Dolby`, `4K-HDR`, `Dolby`, and `HDR` and have a directory structured like below:
```
config
├── config.yml
├── Movies.yml
├── TV Shows.yml
├── overlays
│ ├── 4K
│ ├── overlay.png
│ ├── 4K-Dolby
│ ├── overlay.png
│ ├── 4K-HDR
│ ├── overlay.png
│ ├── Dolby
│ ├── overlay.png
│ ├── HDR
│ ├── overlay.png
```
### Alternative URL Images
The alternative way to specify your overlay image is do use the `name` and either `url` or `git` attributes like so.
```yaml
collections:
4K Overlay:
plex_search:
all:
resolution: 4K
item_overlay:
name: 4K
url: https://raw.githubusercontent.com/wiki/meisnate12/Plex-Meta-Manager/overlay.png
build_collection: false
```
```yaml
collections:
4K Overlay:
plex_search:
all:
resolution: 4K
item_overlay:
name: 4K
git: yozora/Overlays/4K/overlay
build_collection: false
```
### Examples Collection Configs
#### 4K Overlay Only
![4K Overlay](overlay-4k.png)
Add a 4K overlay to all 4K Movies
```yaml
collections:
4K Overlay:
plex_search:
all:
resolution: 4K
item_overlay: 4K
build_collection: false
```
#### 4K and HDR Overlays
Here's an example of how you could add `4K`, `4K-HDR`, and `HDR` overlays
```yaml
collections:
4K Overlay:
plex_search:
all:
resolution: 4K
hdr: false
item_overlay: 4K
build_collection: false
4K-HDR Overlay:
plex_search:
all:
resolution: 4K
hdr: true
item_overlay: 4K-HDR
build_collection: false
HDR Overlay:
plex_search:
all:
hdr: true
filters:
resolution.not: 4K
item_overlay: HDR
build_collection: false
```
#### 4K, HDR, Dolby Overlays
Here's an example of how you could add `4K`, `4K-HDR`, `4K-Dolby`, `Dolby`, and `HDR` overlays
**Note: This only works is your filenames have a tag in them for Dolby files as Plex cannot detect dolby yet**
```yaml
collections:
4K:
plex_search:
all:
resolution: 4K
hdr: false
filters:
filepath.not: DoVi
item_overlay: 4K
build_collection: false
4K-HDR:
plex_search:
all:
resolution: 4K
hdr: true
filters:
filepath.not: DoVi
item_overlay: 4K-HDR
build_collection: false
4K-Dolby:
plex_search:
all:
resolution: 4K
filters:
filepath: DoVi
item_overlay: 4K-Dolby
build_collection: false
HDR:
plex_search:
all:
hdr: true
filters:
filepath.not: DoVi
resolution.not: 4K
item_overlay: HDR
build_collection: false
Dolby:
plex_all: true
filters:
filepath: DoVi
resolution.not: 4K
item_overlay: Dolby
build_collection: false
```
## User Generated Overlays
![Language Overlay](overlay-language.png)

@ -0,0 +1,57 @@
# Schedule Detail
The script is designed to run continuously and certain attributes can be scheduled using these attributes.
Below is an example of a scheduled library:
```yaml
libraries:
Movies:
schedule: weekly(sunday)
metadata_path:
- file: config/Movies.yml
- git: meisnate12/MovieCharts
- git: meisnate12/Studios
- git: meisnate12/IMDBGenres
- git: meisnate12/People
operations:
mass_critic_rating_update: tmdb
```
Below is an example of a scheduled collection:
```yaml
collections:
TMDb Trending Weekly:
tmdb_trending_weekly: 30
sync_mode: sync
schedule: weekly(sunday)
TMDb Top Rated:
tmdb_top_rated: 30
sync_mode: sync
schedule: monthly(1), monthly(15)
```
Below is an example of a scheduled pinning collection:
```yaml
collections:
Christmas Movies:
imdb_list: https://www.imdb.com/list/ls000096828/
sync_mode: sync
visible_home: range(12/01-12-31)
```
The scheduling options are:
| Name | Description | Format | Example |
|:--------|:------------------------------------------------|:----------------------|:---------------------|
| Hourly | Update only when the script is run in that hour | hourly(Hour of Day) | `hourly(17)` |
| Daily | Update once a day | daily | `daily` |
| Weekly | Update once a week on the specified day | weekly(Day of Week) | `weekly(sunday)` |
| Monthly | Update once a month on the specified day | monthly(Day of Month) | `monthly(1)` |
| Yearly | Update once a year on the specified day | yearly(MM/DD) | `yearly(01/30)` |
| Range | Updates whenever the date is within the range | range(MM/DD-MM/DD) | `range(12/01-12/31)` |
| Never | Never updates | never | `never` |
* `daily` is the default when `schedule` isn't specified.
* You can run the script multiple times per day but using the `--time` command line argument detailed on the [Run Commands & Environmental Variables Page](../../home/environmental.md#time-to-run).
* You can have multiple scheduling options just make them a list or comma-separated values.
* You can use the `delete_not_scheduled` setting to delete Collections that are skipped due to not being scheduled.

@ -0,0 +1,30 @@
# Setting Details
All the following attributes serve various functions as how the collection/playlist functions inside of Plex Meta Manager.
| Attribute | Description & Values |
|:------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `name` | **Description:** Used to specify the name off the collection/playlist in Plex as different then the mapping name.<br>**Values:** Any String |
| `limit` | **Description:** Used to specify the max number of items for the collection/playlist<br>**Values:** Number greater then 0 |
| `template` | **Description:** Used to specify a template and template variables to use for this collection/playlist. See the [Templates Page](../templates) for more information.<br>**Values:** Dictionary |
| `run_again` | **Description:** Used to try and add all the missing items to the collection/playlist again after the daily run.<br>**Default:** `false`<br>**Values:** `true` or `false` |
| `sync_mode` | **Description:** Used to change how builders sync with this collection/playlist.<br>**Default:** `sync_mode` [settings value](../../config/settings) in the Configuration File<br>**Values:**<table class="clearTable"><tr><td>`append`</td><td>Only Add Items to the Collection</td></tr><tr><td>`sync`</td><td>Add & Remove Items from the Collection</td></tr></table> |
| `minimum_items` | **Description:** Minimum items that must be found to add to a collection/playlist.<br>**Default:** `minimum_items` [settings value](../../config/settings) in the Configuration File<br>**Values:** number greater then 0 |
| `delete_below_minimum` | **Description:** Deletes the collection/playlist if below the minimum.<br>**Default:** `delete_below_minimum` [settings value](../../config/settings) in the Configuration File<br>**Values:** `true` or `false` |
| `delete_not_scheduled` | **Description:** Deletes the collection/playlist if its skipped because its not scheduled.<br>**Default:** `delete_not_scheduled` [settings value](../../config/settings) in the Configuration File<br>**Values:** `true` or `false` |
| `validate_builders` | **Description:** When set to false the collection/playlist will not fail if one builder fails.<br>**Default:** `true`<br>**Values:** `true` or `false` |
| `cache_builders` | **Description:** Caches the items found by the builders for a number of days. This is useful if you run the same configuration on multiple libraries/servers in one run just set the value to `1`.<br>**Default:** `0` <br>**Values:** number 0 or greater |
| `blank_collection` | **Description:** When set to true the collection will be created with no builders and no items added.<br>**Default:** `false`<br>**Values:** `true` or `false` |
| `build_collection` | **Description:** When set to false the collection won't be created but items can still be added to Radarr/Sonarr. Does not work for playlists.<br>**Default:** `true`<br>**Values:** `true` or `false` |
| `server_preroll` | **Description:** Used to set the `Movie pre-roll video` Text box in Plex under Settings -> Extras.<br>You can run this with a [schedule](schedule) to change the pre-rolls automatically.<br>**Values:** Any String |
| `missing_only_released` | **Description:** Collection/Playlist Level `missing_only_released` toggle.<br>**Default:** `missing_only_released` [settings value](../../config/settings) in the Configuration File<br>**Values:** `true` or `false` |
| `only_filter_missing` | **Description:** Collection/Playlist Level `only_filter_missing` toggle.<br>**Default:** `only_filter_missing` [settings value](../../config/settings) in the Configuration File<br>**Values:** `true` or `false` |
| `show_filtered` | **Description:** Collection/Playlist level `show_filtered` toggle.<br>**Default:** `show_filtered` [settings value](../../config/settings) in the Configuration File<br>**Values:** `true` or `false` |
| `show_missing` | **Description:** Collection/Playlist level `show_missing` toggle.<br>**Default:** `show_missing` [settings value](../../config/settings) in the Configuration File<br>**Values:** `true` or `false` |
| `save_missing` | **Description:** Collection/Playlist level `save_missing` toggle.<br>**Default:** `save_missing` [settings value](../../config/settings) in the Configuration File<br>**Values:** `true` or `false` |
| `ignore_ids` | **Description:** Collection/Playlist level `ignore_ids` which is combined with the library and global `ignore_ids`.<br>**Default:** `ignore_ids` [settings value](../../config/settings) in the Configuration File<br>**Values:** List or comma-separated String of TMDb/TVDb IDs |
| `ignore_imdb_ids` | **Description:** Collection/Playlist level `ignore_imdb_ids` which is combined with the library and global `ignore_imdb_ids`.<br>**Default:** `ignore_imdb_ids` [settings value](../../config/settings) in the Configuration File<br>**Values:** List or comma-separated String of IMDb IDs |
| `name_mapping` | **Description:** Used to specify the folder name in the [Image Assets Directory](../../home/guides/assets) i.e. if your collection/playlist name contains characters that are not allowed in file paths (i.e. for windows `<`, `>`, `:`, `"`, `/`, `\`, `?`, `*` cannot be in the file path), but you want them in your name you can this to specify the name in the file system.<br>**Values:** Any String |
| `test` | **Description:** When running in Test Mode (`--run-tests` [option](../../home/environmental)) only collections/playlists with `test: true` will be run.<br>**Default:** `false`<br>**Values:** `true` or `false` |
| `changes_webhooks` | **Description:** Used to specify a collection/playlist changes webhook for just this collection/playlist.<br>**Values:** List of webhooks |

File diff suppressed because it is too large Load Diff

@ -0,0 +1,228 @@
# Filters
Filters allow for you to filter every item added to the collection/playlist from every builder using the `filters` attribute.
You can have multiple filters but an item must match at least one value from **each** filter to be added to a collection/playlist. The values for each must match what Plex has including special characters in order to match.
All filter options are listed below. To display items filtered out add `show_filtered: true` to the collection.
You can use the `plex_all: true` builder to filter from your entire library.
**Filters can be very slow. Try to build or narrow your items using [Plex Search](builders/plex.md#plex-search) if possible.**
## String Filters
String filters can be used with either no modifier or with `.not`, `.is`, `.isnot`, `.begins`, `.ends`, or `.regex`.
String filters can take multiple values **only as a list**.
### Modifier
| String Modifier | Description |
|:----------------|:-------------------------------------------------------------------------------|
| No Modifier | Matches every item where the attribute contains the given string |
| `.not` | Matches every item where the attribute does not contain the given string |
| `.is` | Matches every item where the attribute exactly matches the given string |
| `.isnot` | Matches every item where the attribute does not exactly match the given string |
| `.begins` | Matches every item where the attribute begins with the given string |
| `.ends` | Matches every item where the attribute ends with the given string |
| `.regex` | Matches every item where the attribute matches the regex given |
### Attribute
| String Filter | Description | Movies | Shows | Seasons | Episodes | Artists | Albums | Track |
|:--------------------|:-----------------------------------------|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|
| `title` | Uses the title attribute to match | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; |
| `summary` | Uses the summary attribute to match | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; |
| `studio` | Uses the studio attribute to match | &#9989; | &#9989; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; |
| `record_label` | Uses the record label attribute to match | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; | &#9989; | &#10060; |
| `filepath` | Uses the item's filepath to match | &#9989; | &#9989; | &#10060; | &#9989; | &#9989; | &#10060; | &#9989; |
| `audio_track_title` | Uses the audio track titles to match | &#9989; | &#10060; | &#10060; | &#9989; | &#10060; | &#10060; | &#9989; |
## Tag Filters
Tag filters can be used with either no modifier or with `.not`.
Tag filters can take multiple values as a **list or a comma-separated string**.
The `original_language` and `tmdb_genre` filters will also filter out movies/shows from being added to Radarr/Sonarr.
### Modifier
| Tag Modifier | Description |
|:-------------|:------------------------------------------------------------------------------------------|
| No Modifier | Matches every item where the attribute matches the given string |
| `.not` | Matches every item where the attribute does not match the given string |
| `.count_gt` | Matches every item where the attribute count is greater then the given number |
| `.count_gte` | Matches every item where the attribute count is greater then or equal to the given number |
| `.count_lt` | Matches every item where the attribute count is less then the given number |
| `.count_lte` | Matches every item where the attribute count is less then the given number |
### Attribute
| Tag Filters | Description | Movies | Shows | Seasons | Episodes | Artists | Albums | Track |
|:--------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|
| `actor` | Uses the actor tags to match | &#9989; | &#9989; | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; |
| `collection` | Uses the collection tags to match | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; |
| `content_rating` | Uses the content rating tags to match | &#9989; | &#9989; | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; |
| `network` | Uses the network tags to match | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; |
| `country` | Uses the country tags to match | &#9989; | &#10060; | &#10060; | &#10060; | &#9989; | &#10060; | &#10060; |
| `director` | Uses the director tags to match | &#9989; | &#10060; | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; |
| `genre` | Uses the genre tags to match | &#9989; | &#9989; | &#10060; | &#10060; | &#9989; | &#9989; | &#10060; |
| `tmdb_genre` | Uses the genre from TMDb to match | &#9989; | &#9989; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; |
| `label` | Uses the label tags to match | &#9989; | &#9989; | &#10060; | &#10060; | &#10060; | &#9989; | &#10060; |
| `producer` | Uses the actor tags to match | &#9989; | &#10060; | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; |
| `year` | Uses the year tag to match | &#9989; | &#9989; | &#9989; | &#9989; | &#10060; | &#9989; | &#9989; |
| `writer` | Uses the writer tags to match | &#9989; | &#10060; | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; |
| `resolution` | Uses the resolution tag to match | &#9989; | &#10060; | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; |
| `audio_language` | Uses the audio language tags to match | &#9989; | &#10060; | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; |
| `subtitle_language` | Uses the subtitle language tags to match | &#9989; | &#10060; | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; |
| `original_language` | Uses TMDb original language [ISO 639-1 codes](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) to match<br>Example: `original_language: en, ko` | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; |
| `tmdb_status` | Uses TMDb Status to match<br>**Values:** `returning`, `planned`, `production`, `ended`, `canceled`, `pilot` | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; |
| `tmdb_type` | Uses TMDb Type to match<br>**Values:** `documentary`, `news`, `production`, `miniseries`, `reality`, `scripted`, `talk_show`, `video` | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; |
## Boolean Filters
Boolean Filters have no modifiers.
### Attribute
| Boolean Filters | Description | Movies | Shows | Seasons | Episodes | Artists | Albums | Track |
|:-----------------|:----------------------------------------------------------|:-------:|:-------:|:--------:|:--------:|:--------:|:--------:|:--------:|
| `has_collection` | Matches every item that has or does not have a collection | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; |
| `has_overlay` | Matches every item that has or does not have an overlay | &#9989; | &#9989; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; |
## Date Filters
Date filters can be used with either no modifier or with `.not`, `.before`, `.after`, or `.regex`.
Date filters can **NOT** take multiple values.
The `first_episode_aired` and `last_episode_aired` filters will also filter out movies/shows from being added to Radarr/Sonarr.
### Modifier
| Date Modifier | Description | Format |
|:--------------|:----------------------------------------------------------------------|:--------------------------------------------------------------------------:|
| No Modifier | Matches every item where the date attribute is in the last X days | **Format:** number of days<br>e.g. `30` |
| `.not` | Matches every item where the date attribute is not in the last X days | **Format:** number of days<br>e.g. `30` |
| `.before` | Matches every item where the date attribute is before the given date | **Format:** MM/DD/YYYY or `today` for the current day<br>e.g. `01/01/2000` |
| `.after` | Matches every item where the date attribute is after the given date | **Format:** MM/DD/YYYY or `today` for the current day<br>e.g. `01/01/2000` |
| `.regex` | Matches every item where the attribute matches the regex given | N/A |
### Attribute
| Date Filters | Description | Movies | Shows | Seasons | Episodes | Artists | Albums | Track |
|:----------------------|:----------------------------------------------------------------|:--------:|:-------:|:--------:|:--------:|:--------:|:--------:|:--------:|
| `release` | Uses the release date attribute (originally available) to match | &#9989; | &#9989; | &#10060; | &#9989; | &#10060; | &#9989; | &#10060; |
| `added` | Uses the date added attribute to match | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; |
| `last_played` | Uses the date last played attribute to match | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; |
| `first_episode_aired` | Uses the first episode aired date to match | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; |
| `last_episode_aired` | Uses the last episode aired date to match | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; |
## Number Filters
Number filters must use `.gt`, `.gte`, `.lt`, or `.lte` as a modifier.
Number filters can **NOT** take multiple values.
The `tmdb_vote_count` and `tmdb_year` filters will also filter out movies/shows from being added to Radarr/Sonarr.
### Modifier
| Number Modifier | Description | Format |
|:----------------|:-------------------------------------------------------------------------------------------|:-------------------------------------------------:|
| `.gt` | Matches every item where the number attribute is greater then the given number | **Format:** number<br>e.g. `30`, `1995`, or `7.5` |
| `.gte` | Matches every item where the number attribute is greater then or equal to the given number | **Format:** number<br>e.g. `30`, `1995`, or `7.5` |
| `.lt` | Matches every item where the number attribute is less then the given number | **Format:** number<br>e.g. `30`, `1995`, or `7.5` |
| `.lte` | Matches every item where the number attribute is less then or equal to the given number | **Format:** number<br>e.g. `30`, `1995`, or `7.5` |
### Attribute
| Number Filters | Description | Movies | Shows | Seasons | Episodes | Artists | Albums | Track |
|:------------------|:---------------------------------------------------------------------|:-------:|:-------:|:--------:|:--------:|:--------:|:--------:|:--------:|
| `year` | Uses the year attribute to match<br>minimum: `1` | &#9989; | &#9989; | &#9989; | &#9989; | &#10060; | &#9989; | &#9989; |
| `tmdb_year` | Uses the year on TMDb to match<br>minimum: `1` | &#9989; | &#9989; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; |
| `critic_rating` | Uses the critic rating attribute to match<br>`0.0` - `10.0` | &#9989; | &#9989; | &#10060; | &#9989; | &#10060; | &#9989; | &#10060; |
| `audience_rating` | Uses the audience rating attribute to match<br> `0.0` - `10.0` | &#9989; | &#9989; | &#10060; | &#9989; | &#10060; | &#10060; | &#10060; |
| `user_rating` | Uses the user rating attribute to match<br>`0.0` - `10.0` | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; |
| `tmdb_vote_count` | Uses the tmdb vote count to match<br>minimum: `1` | &#9989; | &#9989; | &#10060; | &#10060; | &#10060; | &#10060; | &#10060; |
| `plays` | Uses the plays attribute to match<br>minimum: `1` | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; | &#9989; |
| `duration` | Uses the duration attribute to match using minutes<br>minimum: `0.0` | &#9989; | &#9989; | &#10060; | &#9989; | &#10060; | &#10060; | &#9989; |
## Special Filters
Special Filters each have their own set of rules for how they're used.
### Attribute
| Special Filters | Description | Movies | Shows | Seasons | Episodes | Artists | Albums | Track |
|:----------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------:|:-------:|:--------:|:--------:|:--------:|:-------:|:--------:|
| `history` | Uses the release date attribute (originally available) to match dates throughout history<br>`day`: Match the Day and Month to Today's Date<br>`month`: Match the Month to Today's Date<br>`1-30`: Match the Day and Month to Today's Date or `1-30` days before Today's Date | &#9989; | &#9989; | &#10060; | &#9989; | &#10060; | &#9989; | &#10060; |
## Collection Filter Examples
A few examples are listed below:
```yaml
collections:
1080p Documentaries:
genre: Documentary
summary: A collection of 1080p Documentaries
filters:
resolution: 1080
```
```yaml
collections:
Daniel Craig only James Bonds:
imdb_list: https://www.imdb.com/list/ls006405458/
filters:
actor: Daniel Craig
```
```yaml
collections:
French Romance:
genre: Romance
filters:
audio_language: Français
```
```yaml
collections:
Romantic Comedies:
genre: Romance
filters:
genre: Comedy
```
```yaml
collections:
9.0 Movies:
plex_all: true
filters:
rating.gte: 9
```
```yaml
collections:
Summer 2020 Movies:
plex_all: true
filters:
release.after: 5/1/2020
release.before: 8/31/2020
```
```yaml
collections:
Movies Released in the Last 180 Days:
plex_all: true
filters:
release: 180
```
```yaml
collections:
Good Adam Sandler Romantic Comedies:
plex_search:
genre: Romance
actor: Adam Sandler
filters:
genre: Comedy
rating.gte: 7
```
```yaml
collections:
Movies with Commentary:
plex: all
filters:
audio_track_title: Commentary
```

@ -0,0 +1,120 @@
# Metadata and Playlist Files
Metadata and Playlist files are used to create and maintain collections within the Plex libraries and playlists on the server.
If utilized to their fullest, these files can be used to maintain the entire server's collections and playlists, and can be used as a backup for these in the event of a restore requirement.
## Metadata Files
Collections, templates, metadata, and dynamic collections are defined within one or more Metadata files, which are linked to libraries in the [Libraries Attribute](../config/libraries) within the [Configuration File](../config/configuration.md).
These are the attributes which can be used within the Metadata File:
| Attribute | Description |
|:-----------------------------------------------------|:-------------------------------------------------------------------------------------------------------------|
| `metadata` | contains definitions of metadata changes to make to library items [movie titles, episode descriptions, etc.] |
| [`templates`](templates) | contains definitions of templates that can be leveraged by multiple collections |
| [`collections`](#collections-and-playlists-mappings) | contains definitions of collections you wish to add to one or more libraries |
| [`dynamic_collections`](dynamic) | contains definitions of dynamic collections you wish to create in one or more libraries |
* One of `metadata`, `collections` or `dynamic_collections` must be present for the Metadata File to execute.
* Example Metadata Files can be found in the [Plex Meta Manager Configs Repository](https://github.com/meisnate12/Plex-Meta-Manager-Configs)
## Playlist Files
Playlists are defined in one or more Playlist files that are mapped in the [Playlist Files Attribute](../config/playlist) within the Configuration File.
There are two attributes which can be utilized within the Playlist File:
| Attribute | Description |
|:-----------------------------------------------|:------------------------------------------------------------------------------|
| [`templates`](templates) | contains definitions of templates that can be leveraged by multiple playlists |
| [`playlists`](#additional-playlist-attributes) | contains definitions of playlists you wish to add to the server |
* `playlists` is required in order to run the Playlist File.
* You can find example Playlist Files in the [Plex Meta Manager Configs Repository](https://github.com/meisnate12/Plex-Meta-Manager-Configs)
* Plex does not support the "Continue Watching" feature for playlists, you can [vote for the feature here](https://forums.plex.tv/t/playlists-remember-position-for-subsequent-resume/84866/39)
## Collections and Playlists Mappings
Plex Meta Manager can run a number of different operations within `collections:` and `playlists:` such as:
* Automatically build and update collections and playlists
* Sync the collection with the source list if one is used
* Send missing media to Sonarr/Radarr (Lidarr not supported at this time)
* Show and Hide collections and playlists at set intervals (i.e. show Christmas collections in December only)
## Dynamic Collection Mappings
Plex Meta Manager can automatically create dynamic collections based on different criteria, such as
* Collections for the top `X` popular people on TMDb (Bruce Willis, Tom Hanks etc.)
* Collections for each decade represented in the library (Best of 1990s, Best of 2000s etc.)
* Collections for each of the moods/styles within a Music library (A Cappella, Pop Rock etc.)
Below is an example dynamic collection which will create a collection for each of the decades represented within the library:
```yaml
dynamic_collections:
Decades:
type: decade
```
## Collection and Playlist Attributes
There are three types of attributes that can be utilized within a collection/playlist:
### Builders
Builders use third-party services to source items to be added to the collection/playlist. Multiple builders can be used in the same collection/playlist from a variety of sources listed below.
* [Plex Builders](builders/plex)
* [Smart Builders](builders/smart)
* [TMDb Builders](builders/tmdb)
* [TVDb Builders](builders/tvdb)
* [IMDb Builders](builders/imdb)
* [Trakt Builders](builders/trakt)
* [Tautulli Builders](builders/tautulli)
* [Letterboxd Builders](builders/letterboxd)
* [ICheckMovies Builders](builders/icheckmovies)
* [FlixPatrol Builders](builders/flixpatrol)
* [StevenLu Builders](builders/stevenlu)
* [AniDB Builders](builders/anidb)
* [AniList Builders](builders/anilist)
* [MyAnimeList Builders](builders/myanimelist)
## Details
These can alter any aspect of the collection/playlist or the media items within them.
* [Setting Details](details/setting)
* [Schedule Detail](details/schedule)
* [Image Overlay Detail](details/overlay)
* [Metadata Details](details/metadata)
* [Arr Details](details/arr)
## Filters
These filter media items added to the collection by any of the Builders.
* [Filters](filters)
## Additional Playlist Attributes
Playlist operations requires the `libraries` attribute, which instructs the operation to look in the specified libraries. This allows media to be combined from multiple libraries into one playlist. The mappings that you define in the `libraries` attribute must match the library names in your [Configuration File](../config/configuration).
The playlist can also use the `sync_to_users` attributes to control who has visibility of the playlist. This will override the global [`playlist_sync_to_users` Setting](../config/settings.md#playlist-sync-to-users). `sync_to_users` can be set to `all` to sync to all users who have access to the Plex Media Server, or a list/comma-separated string of users. The Plex Media Server owner will always have visibility of the Playlists, so does not need to be defined within the attribute. Leaving `sync_to_users` empty will make the playlist visible to the Plex Media Server owner only.
In the following example, media is pulled from the `Movies` and `TV Shows` libraries into the one Playlist, and the playlist is shared with a specific set of users:
```yaml
playlists:
Marvel Cinematic Universe:
sync_mode: sync
libraries: Movies, TV Shows
sync_to_users: User1, someone@somewhere.com, User3
trakt_list: https://trakt.tv/users/donxy/lists/marvel-cinematic-universe?sort=rank,asc
summary: Marvel Cinematic Universe In Chronological Order
```
* Unlike collections, playlists can only be built using one Builder as their ordering is inherited from the builder; it is not possible to combine builders.

@ -0,0 +1,166 @@
# Movie Library Metadata
You can have the script edit the metadata of Movies by adding them to the `metadata` mapping of a Metadata File.
An example of multiple metadata edits in a movie library is below:
```yaml
metadata:
Godzilla (1954):
title: Godzilla
year: 1954
content_rating: R
Godzilla (1998):
title: Godzilla
year: 1998
sort_title: Godzilla 03
content_rating: PG-13
Shin Godzilla:
sort_title: Godzilla 06
content_rating: R
Godzilla 1985:
content_rating: PG
"Godzilla 2000: Millennium":
originally_available: 1999-08-18
Godzilla Against MechaGodzilla:
originally_available: 2002-03-23
Godzilla Raids Again:
content_rating: G
originally_available: 1955-05-21
Godzilla vs. Biollante:
content_rating: PG
Godzilla vs. Destoroyah:
content_rating: PG
originally_available: 1995-01-19
Godzilla vs. Gigan:
content_rating: G
originally_available: 1972-09-14
Godzilla vs. Hedorah:
content_rating: G
originally_available: 1971-04-01
Godzilla vs. King Ghidorah:
content_rating: PG
originally_available: 1991-04-28
Godzilla vs. Mechagodzilla:
content_rating: G
originally_available: 1974-03-24
Godzilla vs. Mechagodzilla II:
content_rating: PG
Godzilla vs. Megaguirus:
content_rating: PG
originally_available: 2000-08-31
Godzilla vs. Megalon:
content_rating: G
originally_available: 1973-03-17
Godzilla vs. Mothra:
content_rating: PG
originally_available: 1992-04-28
Godzilla vs. SpaceGodzilla:
content_rating: PG
originally_available: 1994-01-19
Godzilla, King of the Monsters!:
content_rating: G
"Godzilla, Mothra and King Ghidorah: Giant Monsters All-Out Attack":
content_rating: PG
originally_available: 2001-08-31
"Godzilla: Final Wars":
content_rating: PG
originally_available: 2004-12-13
"Godzilla: Tokyo S.O.S.":
originally_available: 2003-12-14
Halloween (Rob Zombie):
alt_title: Halloween
year: 2007
"Halo 4: Forward Unto Dawn":
alt_title: Halo 4 Forward Unto Dawn
tmdb_show: 56295
content_rating: R
```
## Movies
Each movie is defined by the mapping name which must be the same as the movie name in the library unless an `alt_title` is specified.
## Metadata Edits
The available attributes for editing movies are as follows
### Special Attributes
| Attribute | Allowed Values |
|:-------------|:--------------------------------------------------------------------------------------------------|
| `title` | Title if different from the mapping value useful when you have multiple movies with the same name |
| `alt_title` | Alternative title to look for |
| `year` | Year of movie for better identification |
| `tmdb_show` | TMDb Show ID to use for metadata useful for miniseries that have been compiled into a movie |
| `tmdb_movie` | TMDb Movie ID to use for metadata useful for movies that have been split into segments |
* YAML files cannot have two items with the same mapping name so if you have two movies with the same name you would change the mapping values to whatever you want. Then use the `title` attribute to specify the real title and use the `year` attribute to specify which of the multiple movies to choose.
```yaml
metadata:
Godzilla1:
title: Godzilla
year: 1954
content_rating: R
Godzilla2:
title: Godzilla
year: 1998
content_rating: PG-13
```
* If you know of another Title your movie might exist under, but you want it titled differently you can use `alt_title` to specify another title to look under and then be changed to the mapping name. For Example TMDb uses the name `The Legend of Korra`, but I want it as `Avatar: The Legend of Korra` (Which must be surrounded by quotes since it uses the character `:`):
```yaml
metadata:
"Avatar: The Legend of Korra":
alt_title: The Legend of Korra
```
This would change the name of the TMDb default `The Legend of Korra` to `Avatar: The Legend of Korra` and would not mess up any subsequent runs.
### General Attributes
| Attribute | Allowed Values |
|:-----------------------|:--------------------------------------------------------------|
| `sort_title` | Text to change Sort Title |
| `original_title` | Text to change Original Title |
| `originally_available` | Date to change Originally Available<br>**Format:** YYYY-MM-DD |
| `content_rating` | Text to change Content Rating |
| `user_rating` | Number to change User Rating |
| `audience_rating` | Number to change Audience Rating |
| `critic_rating` | Number to change Critic Rating |
| `studio` | Text to change Studio |
| `tagline` | Text to change Tagline |
| `summary` | Text to change Summary |
### Tag Attributes
You can add `.remove` to any tag attribute to only remove those tags i.e. `genre.remove`.
You can add `.sync` to any tag attribute to sync all tags vs just appending the new ones i.e. `genre.sync`.
| Attribute | Allowed Values |
|:-------------|:----------------------------------------------------|
| `director` | List or comma-separated text of each Director Tag |
| `country` | List or comma-separated text of each Country Tag |
| `genre` | List or comma-separated text of each Genre Tag |
| `writer` | List or comma-separated text of each Writer Tag |
| `producer` | List or comma-separated text of each Producer Tag |
| `collection` | List or comma-separated text of each Collection Tag |
| `label` | List or comma-separated text of each Label Tag |
### Advanced Attributes
| Attribute | Allowed Values |
|:---------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `metadata_language` | `default`, `ar-SA`, `ca-ES`, `cs-CZ`, `da-DK`, `de-DE`, `el-GR`, `en-AU`, `en-CA`, `en-GB`, `en-US`, `es-ES`, `es-MX`, `et-EE`, `fa-IR`, `fi-FI`, `fr-CA`, `fr-FR`, `he-IL`, `hi-IN`, `hu-HU`, `id-ID`, `it-IT`, `ja-JP`, `ko-KR`, `lt-LT`, `lv-LV`, `nb-NO`, `nl-NL`, `pl-PL`, `pt-BR`, `pt-PT`, `ro-RO`, `ru-RU`, `sk-SK`, `sv-SE`, `th-TH`, `tr-TR`, `uk-UA`, `vi-VN`, `zh-CN`, `zh-HK`, `zh-TW` |
| `use_original_title` | `default`: Library default<br>`no`: No<br>`yes`: Yes |
\* Must be using the **New Plex Movie Agent*
### Image Attributes
| Attribute | Description | Allowed Values |
|:------------------|:----------------------------------------------------------------------|:------------------------------------------------|
| `url_poster` | Used to change the movie's poster to the URL | URL of image publicly available on the internet |
| `file_poster` | Used to change the movie's poster to the image in the file system | Path to image in the file system |
| `url_background` | Use to change the movie's background to the URL | URL of image publicly available on the internet |
| `file_background` | Used to change the movie's background to the image in the file system | Path to image in the file system |

@ -0,0 +1,115 @@
# Music Library Metadata
You can have the script edit the metadata of Artists, Albums, and Tracks by adding them to the `metadata` mapping of a Metadata File.
An example of multiple metadata edits in a music library is below:
```yaml
metadata:
"Linkin Park":
country: "United States of America"
album_sorting: newest
albums:
"Hybrid Theory":
originally_available: "2000-10-24"
tracks:
1:
user_rating: 5
"One Step Closer":
user_rating: 5
"Meteora":
originally_available: "2003-03-25"
album_sorting: newest
tracks:
9:
user_rating: 5
"Numb":
user_rating: 5
"Minutes To Midnight":
originally_available: "2007-05-14"
```
## Artist
Each artist is defined by the mapping name which must be the same as the artist name in the library unless an `alt_title` is specified.
### Albums
To edit the metadata of a particular Album for an Artist use the `albums` attribute on its artist.
The mapping name is the album name.
### Tracks
To edit the metadata of a particular Track on an Album use the `tracks` attribute on its album.
The mapping name is the track number on that Album, or the title of the Track.
## Metadata Edits
The available attributes for editing artists, albums, and tracks are as follows
### Special Attributes
| Attribute | Values | Artists | Album | Tracks |
|:------------|:------------------------------|:--------:|:--------:|:--------:|
| `alt_title` | Alternative title to look for | &#9989; | &#9989; | &#9989; |
| `albums` | Mapping to define Albums | &#9989; | &#10060; | &#10060; |
| `tracks` | Mapping to define Tracks | &#10060; | &#9989; | &#10060; |
* If you know of another Title your item might exist under, but you want it titled differently you can use `alt_title` to specify another title to look under and then be changed to the mapping name. For Example the Artist `Kesha` used to be stylized as `Ke$ha`, and might still be found that way in Metadata results.
```yaml
metadata:
"Kesha":
alt_title: "Ke$ha"
```
This would change the name of the default `Ke$ha` to `Kesha` and would not mess up any subsequent runs.
``
### General Attributes
| Attribute | Values | Artists | Album | Tracks |
|:-----------------------|:--------------------------------------------------------------|:--------:|:--------:|:--------:|
| `title` | Text to change Title | &#10060; | &#10060; | &#9989; |
| `sort_title` | Text to change Sort Title | &#9989; | &#9989; | &#9989; |
| `user_rating` | Number to change User Rating | &#9989; | &#9989; | &#9989; |
| `critic_rating` | Number to change Critic Rating | &#10060; | &#9989; | &#10060; |
| `originally_available` | Date to change Originally Available<hr>**Format:** YYYY-MM-DD | &#10060; | &#9989; | &#10060; |
| `record_label` | Text to change Record Label | &#10060; | &#9989; | &#10060; |
| `summary` | Text to change Summary | &#9989; | &#9989; | &#9989; |
| `track` | Text to change Track | &#10060; | &#10060; | &#9989; |
| `disc` | Text to change Disc | &#10060; | &#10060; | &#9989; |
| `original_artist` | Text to change Original Artist | &#10060; | &#10060; | &#9989; |
### Tag Attributes
You can add `.remove` to any tag attribute to only remove those tags i.e. `genre.remove`.
You can add `.sync` to any tag attribute to sync all tags vs just appending the new ones i.e. `genre.sync`.
| Attribute | Values | Artists | Album | Tracks |
|:-----------------|:--------------------------------------------------------|:--------:|:--------:|:--------:|
| `genre` | List or comma-separated text of each Genre Tag | &#9989; | &#9989; | &#10060; |
| `collection` | List or comma-separated text of each Collection Tag | &#9989; | &#9989; | &#9989; |
| `label` | List or comma-separated text of each Label Tag | &#10060; | &#9989; | &#10060; |
| `style` | List or comma-separated text of each Style Tag | &#9989; | &#9989; | &#10060; |
| `mood` | List or comma-separated text of each Mood Tag | &#9989; | &#9989; | &#9989; |
| `country` | List or comma-separated text of each Country Tag | &#9989; | &#10060; | &#10060; |
| `similar_artist` | List or comma-separated text of each Similar Artist Tag | &#9989; | &#10060; | &#10060; |
### Image Attributes
| Attribute | Values | Artists | Album | Tracks |
|:------------------|:------------------------------------------------|:-------:|:-------:|:--------:|
| `url_poster` | URL of image publicly available on the internet | &#9989; | &#9989; | &#10060; |
| `file_poster` | Path to image in the file system | &#9989; | &#9989; | &#10060; |
| `url_background` | URL of image publicly available on the internet | &#9989; | &#9989; | &#10060; |
| `file_background` | Path to image in the file system | &#9989; | &#9989; | &#10060; |
### Advanced Attributes
All these attributes only work with Artists.
| Attribute | Values |
|:----------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `album_sorting` | <table class="clearTable"><tbody><tr><td>`default`</td><td>Library default</td></tr><tr><td>`oldest`</td><td>Oldest first</td></tr><tr><td>`newest`</td><td>Newest first</td></tr><tr><td>`name`</td><td>Alphabetical</td></tr></tbody></table> |

@ -0,0 +1,166 @@
# TV Show Library Metadata
You can have the script edit the metadata of Shows, Seasons, and Episodes by adding them to the `metadata` mapping of a Metadata File.
An example of multiple metadata edits in a show library is below:
```yaml
metadata:
"Avatar: The Last Airbender":
sort_title: Avatar 01
seasons:
1:
title: "Book One: Water"
summary: >-
After a lapse of 100 years, the Avatar-spiritual master of the elements-has returned. And just in
the nick of time. The Four Nations (Water, Earth, Fire, and Air) have become unbalanced. The Fire
Nation wants to rule the world, and its first conquest will be the Northern Water Tribe. It's up to
a 12-year-old Airbender named Aang to find a way to stop it. Join Aang, Katara, Sokka, Momo, and
Appa as they head north on the adventure of a lifetime.
episodes:
1:
user_rating: 9.1
2:
title: "Book Two: Earth"
summary: >-
Avatar Aang continues his quest to master the four elements before the end of summer. Together with
Katara, Sokka, Momo, and Appa, he journeys across the Earth Kingdom in search of an Earthbending
mentor. Along the way, he confronts Princess Azula, treacherous daughter of Firelord Ozai and
sister to Prince Zuko. More powerful than her brother, Azula will stop nothing to defeat the Avatar.
But Aang and the gang find plenty of Earth Kingdom allies to help them along the way. From the swamps
of the South to the Earth King's palace, Avatar: Book 2 is an adventure like no other.
3:
title: "Book Three: Fire"
summary: >-
Having survived the terrible battle with Azula, Aang faces new challenges as he and his brave
friends secretly enter the Fire Nation. Their quest is to find and defeat Firelord Ozai. Along
the way, they discover that Ozai has plans of his own. The leader of the Fire Nation intends to
use the massive power of Sozin's comet to spread his dominion permanently across the four nations.
Short on time, Aang has a lot of bending to learn and no master to help him learn it. However, his
friends are there to help, and he finds unexpected allies deep in the heart of the Fire Nation. In
the spectacular four-part conclusion, Aang must fulfill his destiny and become a fully realized
Avatar, or watch the world go up in smoke.
episodes:
21:
summary: The Epic Series Final of Avatar The Last Airbender
"Avatar: The Legend of Korra":
sort_title: Avatar 02
alt_title: The Legend of Korra
original_title: The Legend of Korra
seasons:
1:
title: "Book One: Air"
2:
title: "Book Two: Spirits"
3:
title: "Book Three: Change"
4:
title: "Book Four: Balance"
```
## Shows
Each show is defined by the mapping name which must be the same as the show name in the library unless an `alt_title` is specified.
### Seasons
To edit the metadata of a particular Season in a Show use the `seasons` attribute on its show.
The mapping name is the season number (use 0 for specials) or the season name.
### Episodes
To edit the metadata of a particular Episode in a Season use the `episodes` attribute on its season.
The mapping name is the episode number in that season or the title of the episode.
## Metadata Edits
The available attributes for editing shows, seasons, and episodes are as follows
### Special Attributes
| Attribute | Values | Shows | Seasons | Episodes |
|:-------------|:-------------------------------------------------------------------------------------------------|:--------:|:--------:|:--------:|
| `title` | Title if different from the mapping value useful when you have multiple shows with the same name | &#9989; | &#9989; | &#9989; |
| `alt_title` | Alternative title to look for | &#9989; | &#10060; | &#10060; |
| `year` | Year of show for better identification | &#9989; | &#10060; | &#10060; |
| `tmdb_show` | TMDb Show ID to use for metadata useful for miniseries that have been compiled into a movie | &#9989; | &#10060; | &#10060; |
| `tmdb_movie` | TMDb Movie ID to use for metadata useful for movies that have been split into segments | &#9989; | &#10060; | &#10060; |
| `seasons` | Mapping to define Seasons | &#9989; | &#10060; | &#10060; |
| `episodes` | Mapping to define Episodes | &#10060; | &#9989; | &#10060; |
* YAML files cannot have two items with the same mapping name so if you have two shows with the same name you would change the mapping values to whatever you want. Then use the `title` attribute to specify the real title and use the `year` attribute to specify which of the multiple shows to choose.
```yaml
metadata:
Godzilla1:
title: Godzilla
year: 1954
content_rating: R
Godzilla2:
title: Godzilla
year: 1998
content_rating: PG-13
```
* If you know of another Title your show might exist under, but you want it titled differently you can use `alt_title` to specify another title to look under and then be changed to the mapping name. For Example TMDb uses the name `The Legend of Korra`, but I want it as `Avatar: The Legend of Korra` (Which must be surrounded by quotes since it uses the character `:`):
```yaml
metadata:
"Avatar: The Legend of Korra":
alt_title: The Legend of Korra
```
This would change the name of the TMDb default `The Legend of Korra` to `Avatar: The Legend of Korra` and would not mess up any subsequent runs.
### General Attributes
| Attribute | Values | Shows | Seasons | Episodes |
|:-----------------------|:--------------------------------------------------------------|:--------:|:--------:|:--------:|
| `title` | Text to change Title | &#10060; | &#9989; | &#9989; |
| `sort_title` | Text to change Sort Title | &#9989; | &#10060; | &#9989; |
| `original_title` | Text to change Original Title | &#9989; | &#10060; | &#9989; |
| `originally_available` | Date to change Originally Available<br>**Format:** YYYY-MM-DD | &#9989; | &#10060; | &#9989; |
| `content_rating` | Text to change Content Rating | &#9989; | &#10060; | &#10060; |
| `user_rating` | Number to change User Rating | &#9989; | &#9989; | &#9989; |
| `audience_rating` | Number to change Audience Rating | &#9989; | &#10060; | &#9989; |
| `critic_rating` | Number to change Critic Rating | &#9989; | &#10060; | &#9989; |
| `studio` | Text to change Studio | &#9989; | &#10060; | &#10060; |
| `tagline` | Text to change Tagline | &#9989; | &#10060; | &#10060; |
| `summary` | Text to change Summary | &#9989; | &#9989; | &#9989; |
### Tag Attributes
You can add `.remove` to any tag attribute to only remove those tags i.e. `genre.remove`.
You can add `.sync` to any tag attribute to sync all tags vs just appending the new ones i.e. `genre.sync`.
| Attribute | Values | Shows | Seasons | Episodes |
|:-------------|:----------------------------------------------------|:--------:|:--------:|:--------:|
| `director` | List or comma-separated text of each Director Tag | &#10060; | &#10060; | &#9989; |
| `genre` | List or comma-separated text of each Genre Tag | &#9989; | &#10060; | &#10060; |
| `writer` | List or comma-separated text of each Writer Tag | &#10060; | &#10060; | &#9989; |
| `collection` | List or comma-separated text of each Collection Tag | &#9989; | &#10060; | &#10060; |
| `label` | List or comma-separated text of each Label Tag | &#9989; | &#10060; | &#10060; |
### Image Attributes
| Attribute | Values | Shows | Seasons | Episodes |
|:------------------|:------------------------------------------------|:-------:|:-------:|:--------:|
| `url_poster` | URL of image publicly available on the internet | &#9989; | &#9989; | &#9989; |
| `file_poster` | Path to image in the file system | &#9989; | &#9989; | &#9989; |
| `url_background` | URL of image publicly available on the internet | &#9989; | &#9989; | &#10060; |
| `file_background` | Path to image in the file system | &#9989; | &#9989; | &#10060; |
### Advanced Attributes
All these attributes only work with Shows.
| Attribute | Values |
|:---------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `episode_sorting` | <table class="clearTable"><tbody><tr><td>`default`</td><td>Library default</td></tr><tr><td>`oldest`</td><td>Oldest first</td></tr><tr><td>`newest`</td><td>Newest first</td></tr></tbody></table> |
| `keep_episodes` | <table class="clearTable"><tbody><tr><td>`all`</td><td>All episodes</td></tr><tr><td>`5_latest`</td><td>5 latest episodes</td></tr><tr><td>`3_latest`</td><td>3 latest episodes</td></tr><tr><td>`latest`</td><td>Latest episodes</td></tr><tr><td>`past_3`</td><td>Episodes added in the past 3 days</td></tr><tr><td>`past_7`</td><td>Episodes added in the past 7 days</td></tr><tr><td>`past_30`</td><td>Episodes added in the past 30 days</td></tr></tbody></table> |
| `delete_episodes` | <table class="clearTable"><tbody><tr><td>`never`</td><td>Never</td></tr><tr><td>`day`</td><td>After a day</td></tr><tr><td>`week`</td><td>After a week</td></tr><tr><td>`refresh`</td><td>On next refresh</td></tr></tbody></table> |
| `season_display` | <table class="clearTable"><tbody><tr><td>`default`</td><td>Library default</td></tr><tr><td>`show`</td><td>Show</td></tr><tr><td>`hide`</td><td>Hide</td></tr></tbody></table> |
| `episode_ordering` | <table class="clearTable"><tbody><tr><td>`default`</td><td>Library default</td></tr><tr><td>`tmdb_aired`</td><td>The Movie Database (Aired)</td></tr><tr><td>`tvdb_aired`</td><td>TheTVDb (Aired)</td></tr><tr><td>`tvdb_dvd`</td><td>TheTVDb (DVD)</td></tr><tr><td>`tvdb_absolute`</td><td>TheTVDb (Absolute)</td></tr></tbody></table> |
| `metadata_language`<sup>1</sup> | `default`, `ar-SA`, `ca-ES`, `cs-CZ`, `da-DK`, `de-DE`, `el-GR`, `en-AU`, `en-CA`, `en-GB`, `en-US`, `es-ES`, `es-MX`, `et-EE`, `fa-IR`, `fi-FI`, `fr-CA`, `fr-FR`, `he-IL`, `hi-IN`, `hu-HU`, `id-ID`, `it-IT`, `ja-JP`, `ko-KR`, `lt-LT`, `lv-LV`, `nb-NO`, `nl-NL`, `pl-PL`, `pt-BR`, `pt-PT`, `ro-RO`, `ru-RU`, `sk-SK`, `sv-SE`, `th-TH`, `tr-TR`, `uk-UA`, `vi-VN`, `zh-CN`, `zh-HK`, `zh-TW` |
| `use_original_title`<sup>1</sup> | <table class="clearTable"><tbody><tr><td>`default`</td><td>Library default</td></tr><tr><td>`no`</td><td>No</td></tr><tr><td>`yes`</td><td>Yes</td></tr></tbody></table> |
<sup>1</sup> Must be using the **New Plex TV Agent**

@ -0,0 +1,140 @@
# Templates
Collections often share a lot of common [or generalizable] configuration details. Templates allow you to define these details so they can be used across multiple collections.
For example, an actor collection might look like this:
```yaml
collections:
Bruce Lee:
actor: tmdb
tmdb_person: 19429
sort_title: +_Bruce Lee
sync_mode: sync
collection_order: release
```
Then you add another:
```
collections:
Bruce Lee:
actor: tmdb
tmdb_person: 19429
sort_title: +_Bruce Lee
sync_mode: sync
collection_order: release
Chris Pratt:
actor: tmdb
tmdb_person: 73457
sort_title: +_Chris Pratt
sync_mode: sync
collection_order: release
```
You could keep going in this way, but there's a lot of repetition there. Both of these collections have the same `sync_mode`, `collection_order`, and `actor` settings; the other two details, `tmdb_person` and `sort_title`, depend on a value defined in the collection.
Those repetitive aspects can be moved into template and leveraged by multiple collections.
For example, a template for those two collections might look like this:
```yaml
templates:
Actor:
actor: tmdb
tmdb_person: <<person>>
sort_title: +_<<collection_name>>
sync_mode: sync
collection_order: release
```
The only things that change are the ID that is used with `tmdb_person` and the name of the collection that is used in `sort_title`.
Those two things surrounded by `<< >>` are "template variables" that you can define for any collection using this template, like this:
```yaml
collections:
Bruce Lee:
template: {name: Actor, person: 19429}
```
or as a list:
```yaml
collections:
Chris Pratt:
template:
name: Actor
person: 73457
```
Note that we provide the template name ["Actor"] and the value to insert in the place of `<<person>>`. The `<<collection_name>>` is a required property of a collection, so it is always available and doesn't have to be called out like `<<person>>`.
Inside a template, you can use all the Builders, Details, and [Filters](filters) attributes that you can give collections/playlists [except `template`; templates cannot be nested].
The names of template variables that you define are arbitrary. In the example above, `<<person>>` could have been `<<tvdb_person_id>>` or `<<bing>>` or anything else. The only thing that matters is that in the template definition you surround them with `<< >>` and in the collection definition you spell it correctly.
To use a template with a collection definition you use the `template` attribute. The only required attribute under `template` is `name` which must correspond exactly to the template mapping name. Any other attributes under `template` are considered template variables whose names correspond exactly with the template variable name surrounded by `<<` and `>>` in the templates. These template variables will replace any part of any value that contains the template variable name surrounded by `<<` and `>>` in the template with the specified template variable's value.
Here's the full example Actor template and two different ways to use it, as it would appear in a metadata file.
```yaml
templates:
Actor:
actor: tmdb
tmdb_person: <<person>>
sort_title: +_<<collection_name>>
sync_mode: sync
collection_order: release
collections:
Bruce Lee:
template: {name: Actor, person: 19429}
Chris Pratt:
template:
name: Actor
person: 73457
```
There are three attributes unique to `templates`, `default`, `optional`, and `move_prefix`.
* `default` can set default values for template variables to be used if they're not specified in the call.
* `optional` can specify variables that if not specified on the template call will cause any attribute using one of those variables to be ignored in the template. You can make any template variable optional per collection by setting it to `null`.
* `move_prefix` can be given a list or comma-separated string of prefixes to move to the end of the collection/playlist name for sorting.
i.e. If you have `move_prefix: The` and a collection is called `The Avengers` then `<<collection_name>>` is replaced with `Avengers, The` instead of `The Avengers` for that collection.
Here's an example IMDb Genre template and two different ways to call it.
```yaml
templates:
IMDb Genre:
default:
title: feature
limit: 100
optional:
- poster_id
imdb_list:
- url: https://www.imdb.com/search/title/?title_type=<<title>>&release_date=1990-01-01,&user_rating=5.0,10.0&num_votes=100000,&genres=<<genre>>
limit: <<limit>>
- url: https://www.imdb.com/search/title/?title_type=<<title>>&release_date=1990-01-01,&user_rating=5.0,10.0&num_votes=100000,&genres=<<genre>>&sort=user_rating,desc
limit: <<limit>>
sort_title: ++_<<collection_name>>
url_poster: https://theposterdb.com/api/assets/<<poster_id>>
sync_mode: sync
collection_order: alpha
collections:
Action:
template:
name: IMDb Genre
genre: action
summary: Action film is a genre wherein physical action takes precedence in the storytelling. The film will often have continuous motion and action including physical stunts, chases, fights, battles, and races. The story usually revolves around a hero that has a goal, but is facing incredible odds to obtain it.
Comedy:
template: {name: IMDb Genre, genre: comedy, poster_id: 69200}
summary: Comedy is a genre of film that uses humor as a driving force. The aim of a comedy film is to illicit laughter from the audience through entertaining stories and characters. Although the comedy film may take on some serious material, most have a happy ending. Comedy film has the tendency to become a hybrid sub-genre because humor can be incorporated into many other genres. Comedies are more likely than other films to fall back on the success and popularity of an individual star.
Romantic Comedy:
template: {name: IMDb Genre, genre: "romance,comedy", limit: 200}
summary: Romantic Comedy is a genre that attempts to catch the viewers heart with the combination of love and humor. This sub-genre is light-hearted and usually places the two protagonists in humorus situation. Romantic-Comedy film revolves around a romantic ideal, such as true love. In the end, the ideal triumphs over the situation or obstacle, thus creating a happy ending.
filters:
genre: Comedy
```
Check out the example files in the [Plex Meta Manager Configs Repository](https://github.com/meisnate12/Plex-Meta-Manager-Configs/tree/master/meisnate12) for more uses and examples.

Binary file not shown.

@ -0,0 +1,3 @@
myst-parser
sphinx_bootstrap_theme
sphinx_inline_tabs

Binary file not shown.
Loading…
Cancel
Save