Merge pull request #14 from meisnate12/develop

v1.0.1
pull/16/head v1.0.1
meisnate12 4 years ago committed by GitHub
commit a7c420dd1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,4 +1,5 @@
# Plex Meta Manager # Plex Meta Manager
#### Version 1.0.1
The original concept for Plex Meta Manager is [Plex Auto Collections](https://github.com/mza921/Plex-Auto-Collections), but this is rewritten from the ground up to be able to include a scheduler, metadata edits, multiple libraries, and logging. Plex Meta Manager is a Python 3 script that can be continuously run using YAML configuration files to update on a schedule the metadata of the movies, shows, and collections in your libraries as well as automatically build collections based on various methods all detailed in the wiki. Some collection examples that the script can automatically build and update daily include Plex Based Searches like actor, genre, or studio collections or Collections based on TMDb, IMDb, Trakt, TVDb, AniDB, or MyAnimeList lists and various other services. The original concept for Plex Meta Manager is [Plex Auto Collections](https://github.com/mza921/Plex-Auto-Collections), but this is rewritten from the ground up to be able to include a scheduler, metadata edits, multiple libraries, and logging. Plex Meta Manager is a Python 3 script that can be continuously run using YAML configuration files to update on a schedule the metadata of the movies, shows, and collections in your libraries as well as automatically build collections based on various methods all detailed in the wiki. Some collection examples that the script can automatically build and update daily include Plex Based Searches like actor, genre, or studio collections or Collections based on TMDb, IMDb, Trakt, TVDb, AniDB, or MyAnimeList lists and various other services.

@ -13,6 +13,7 @@ plex: # Can be individually specified pe
token: #################### token: ####################
sync_mode: append sync_mode: append
asset_directory: config/assets asset_directory: config/assets
show_unmanaged_collections: true
radarr: # Can be individually specified per library as well radarr: # Can be individually specified per library as well
url: http://192.168.1.12:7878 url: http://192.168.1.12:7878
token: ################################ token: ################################

@ -142,6 +142,7 @@ class Config:
self.general["plex"]["token"] = check_for_attribute(self.data, "token", parent="plex", default_is_none=True) if "plex" in self.data else None self.general["plex"]["token"] = check_for_attribute(self.data, "token", parent="plex", default_is_none=True) if "plex" in self.data else None
self.general["plex"]["asset_directory"] = check_for_attribute(self.data, "asset_directory", parent="plex", var_type="path", default=os.path.join(default_dir, "assets")) if "plex" in self.data else os.path.join(default_dir, "assets") self.general["plex"]["asset_directory"] = check_for_attribute(self.data, "asset_directory", parent="plex", var_type="path", default=os.path.join(default_dir, "assets")) if "plex" in self.data else os.path.join(default_dir, "assets")
self.general["plex"]["sync_mode"] = check_for_attribute(self.data, "sync_mode", parent="plex", default="append", test_list=["append", "sync"], options="| \tappend (Only Add Items to the Collection)\n| \tsync (Add & Remove Items from the Collection)") if "plex" in self.data else "append" self.general["plex"]["sync_mode"] = check_for_attribute(self.data, "sync_mode", parent="plex", default="append", test_list=["append", "sync"], options="| \tappend (Only Add Items to the Collection)\n| \tsync (Add & Remove Items from the Collection)") if "plex" in self.data else "append"
self.general["plex"]["show_unmanaged_collections"] = check_for_attribute(self.data, "show_unmanaged_collections", parent="plex", var_type="bool", default=True) if "plex" in self.data else True
self.general["radarr"] = {} self.general["radarr"] = {}
self.general["radarr"]["url"] = check_for_attribute(self.data, "url", parent="radarr", default_is_none=True) if "radarr" in self.data else None self.general["radarr"]["url"] = check_for_attribute(self.data, "url", parent="radarr", default_is_none=True) if "radarr" in self.data else None
@ -239,6 +240,16 @@ class Config:
else: else:
logger.warning("Config Warning: sync_mode attribute is blank using general value: {}".format(self.general["plex"]["sync_mode"])) logger.warning("Config Warning: sync_mode attribute is blank using general value: {}".format(self.general["plex"]["sync_mode"]))
params["show_unmanaged_collections"] = self.general["plex"]["show_unmanaged_collections"]
if "plex" in libs[lib] and "show_unmanaged_collections" in libs[lib]["plex"]:
if libs[lib]["plex"]["show_unmanaged_collections"]:
if isinstance(libs[lib]["plex"]["show_unmanaged_collections"], bool):
params["plex"]["show_unmanaged_collections"] = libs[lib]["plex"]["show_unmanaged_collections"]
else:
logger.warning("Config Warning: plex sub-attribute show_unmanaged_collections must be either true or false using general value: {}".format(self.general["plex"]["show_unmanaged_collections"]))
else:
logger.warning("Config Warning: radarr sub-attribute add is blank using general value: {}".format(self.general["radarr"]["add"]))
params["tmdb"] = self.TMDb params["tmdb"] = self.TMDb
params["tvdb"] = self.TVDb params["tvdb"] = self.TVDb
@ -533,6 +544,8 @@ class Config:
logger.info("Collection Error: {} skipped. MyAnimeList must be configured".format(m)) logger.info("Collection Error: {} skipped. MyAnimeList must be configured".format(m))
map = {} map = {}
elif collections[c][m] is not None: elif collections[c][m] is not None:
logger.debug("Method: {}".format(m))
logger.debug("Value: {}".format(collections[c][m]))
if m in util.method_alias: if m in util.method_alias:
method_name = util.method_alias[m] method_name = util.method_alias[m]
logger.warning("Collection Warning: {} attribute will run as {}".format(m, method_name)) logger.warning("Collection Warning: {} attribute will run as {}".format(m, method_name))
@ -843,8 +856,11 @@ class Config:
library.clear_collection_missing(collection_name) library.clear_collection_missing(collection_name)
for method, values in methods: for method, values in methods:
logger.debug("Method: {}".format(method))
logger.debug("Values: {}".format(values))
pretty = util.pretty_names[method] if method in util.pretty_names else method pretty = util.pretty_names[method] if method in util.pretty_names else method
for value in values: for value in values:
logger.debug("Value: {}".format(value))
items = [] items = []
missing_movies = [] missing_movies = []
missing_shows = [] missing_shows = []
@ -986,10 +1002,10 @@ class Config:
edits["summary.value"] = details["summary"] edits["summary.value"] = details["summary"]
edits["summary.locked"] = 1 edits["summary.locked"] = 1
if len(edits) > 0: if len(edits) > 0:
logger.debug(edits)
plex_collection.edit(**edits) plex_collection.edit(**edits)
plex_collection.reload() plex_collection.reload()
logger.info("Details: have been updated") logger.info("Details: have been updated")
logger.debug(edits)
if "collection_mode" in details: if "collection_mode" in details:
plex_collection.modeUpdate(mode=details["collection_mode"]) plex_collection.modeUpdate(mode=details["collection_mode"])
if "collection_order" in details: if "collection_order" in details:
@ -1027,7 +1043,7 @@ class Config:
except Exception as e: except Exception as e:
util.print_stacktrace() util.print_stacktrace()
logger.error("Unknown Error: {}".format(e)) logger.error("Unknown Error: {}".format(e))
if library.show_unmanaged_collections is True:
logger.info("") logger.info("")
util.seperator("Unmanaged Collections in {} Library".format(library.name)) util.seperator("Unmanaged Collections in {} Library".format(library.name))
logger.info("") logger.info("")

@ -74,6 +74,7 @@ class PlexAPI:
self.metadata_path = params["metadata_path"] self.metadata_path = params["metadata_path"]
self.asset_directory = params["asset_directory"] self.asset_directory = params["asset_directory"]
self.sync_mode = params["sync_mode"] self.sync_mode = params["sync_mode"]
self.show_unmanaged_collections = params["show_unmanaged_collections"]
self.plex = params["plex"] self.plex = params["plex"]
self.radarr = params["radarr"] self.radarr = params["radarr"]
self.sonarr = params["sonarr"] self.sonarr = params["sonarr"]
@ -293,7 +294,10 @@ class PlexAPI:
add_edit("originally_available", str(item.originallyAvailableAt)[:-9], self.metadata[m], key="originallyAvailableAt", value=originally_available) add_edit("originally_available", str(item.originallyAvailableAt)[:-9], self.metadata[m], key="originallyAvailableAt", value=originally_available)
add_edit("rating", item.rating, self.metadata[m], value=rating) add_edit("rating", item.rating, self.metadata[m], value=rating)
add_edit("content_rating", item.contentRating, self.metadata[m], key="contentRating") add_edit("content_rating", item.contentRating, self.metadata[m], key="contentRating")
if self.is_movie:
add_edit("original_title", item.originalTitle, self.metadata[m], key="originalTitle", value=original_title) add_edit("original_title", item.originalTitle, self.metadata[m], key="originalTitle", value=original_title)
elif "original_title" in self.metadata[m]:
logger.error("Metadata Error: original_title does not work with shows")
add_edit("studio", item.studio, self.metadata[m], value=studio) add_edit("studio", item.studio, self.metadata[m], value=studio)
add_edit("tagline", item.tagline, self.metadata[m], value=tagline) add_edit("tagline", item.tagline, self.metadata[m], value=tagline)
add_edit("summary", item.summary, self.metadata[m], value=summary) add_edit("summary", item.summary, self.metadata[m], value=summary)

@ -67,7 +67,7 @@ class RadarrAPI:
"title": movie.title, "title": movie.title,
"{}".format("qualityProfileId" if self.version == "v3" else "profileId"): self.quality_profile_id, "{}".format("qualityProfileId" if self.version == "v3" else "profileId"): self.quality_profile_id,
"year": int(year), "year": int(year),
"tmdbid": str(tmdb_id), "tmdbid": int(tmdb_id),
"titleslug": titleslug, "titleslug": titleslug,
"monitored": True, "monitored": True,
"rootFolderPath": self.root_folder_path, "rootFolderPath": self.root_folder_path,
@ -79,7 +79,11 @@ class RadarrAPI:
logger.info("Added to Radarr | {:<6} | {}".format(tmdb_id, movie.title)) logger.info("Added to Radarr | {:<6} | {}".format(tmdb_id, movie.title))
add_count += 1 add_count += 1
else: else:
try:
logger.error("Radarr Error: ({}) {}: ({}) {}".format(tmdb_id, movie.title, response.status_code, response.json()[0]["errorMessage"])) logger.error("Radarr Error: ({}) {}: ({}) {}".format(tmdb_id, movie.title, response.status_code, response.json()[0]["errorMessage"]))
except KeyError as e:
logger.debug(url_json)
logger.error("Radarr Error: {}".format(response.json()))
logger.info("{} Movie{} added to Radarr".format(add_count, "s" if add_count > 1 else "")) logger.info("{} Movie{} added to Radarr".format(add_count, "s" if add_count > 1 else ""))
@retry(stop_max_attempt_number=6, wait_fixed=10000) @retry(stop_max_attempt_number=6, wait_fixed=10000)

@ -70,7 +70,11 @@ class SonarrAPI:
logger.info("Added to Sonarr | {:<6} | {}".format(tvdb_id, show.title)) logger.info("Added to Sonarr | {:<6} | {}".format(tvdb_id, show.title))
add_count += 1 add_count += 1
else: else:
try:
logger.error("Sonarr Error: ({}) {}: ({}) {}".format(tvdb_id, show.title, response.status_code, response.json()[0]["errorMessage"])) logger.error("Sonarr Error: ({}) {}: ({}) {}".format(tvdb_id, show.title, response.status_code, response.json()[0]["errorMessage"]))
except KeyError as e:
logger.debug(url_json)
logger.error("Sonarr Error: {}".format(response.json()))
logger.info("{} Show{} added to Sonarr".format(add_count, "s" if add_count > 1 else "")) logger.info("{} Show{} added to Sonarr".format(add_count, "s" if add_count > 1 else ""))
@retry(stop_max_attempt_number=6, wait_fixed=10000) @retry(stop_max_attempt_number=6, wait_fixed=10000)

@ -1,4 +1,4 @@
import logging, re, signal, sys, time, traceback import datetime, logging, re, signal, sys, time, traceback
try: try:
import msvcrt import msvcrt

@ -56,7 +56,7 @@ logger.info(util.get_centered_text("| |_) | |/ _ \ \/ / | |\/| |/ _ \ __/ _` | |
logger.info(util.get_centered_text("| __/| | __/> < | | | | __/ || (_| | | | | | (_| | | | | (_| | (_| | __/ | ")) logger.info(util.get_centered_text("| __/| | __/> < | | | | __/ || (_| | | | | | (_| | | | | (_| | (_| | __/ | "))
logger.info(util.get_centered_text("|_| |_|\___/_/\_\ |_| |_|\___|\__\__,_| |_| |_|\__,_|_| |_|\__,_|\__, |\___|_| ")) logger.info(util.get_centered_text("|_| |_|\___/_/\_\ |_| |_|\___|\__\__,_| |_| |_|\__,_|_| |_|\__,_|\__, |\___|_| "))
logger.info(util.get_centered_text(" |___/ ")) logger.info(util.get_centered_text(" |___/ "))
logger.info(util.get_centered_text(" Version: 1.0.0 ")) logger.info(util.get_centered_text(" Version: 1.0.1 "))
util.seperator() util.seperator()
if args.test: if args.test:

Loading…
Cancel
Save