mirror of
https://github.com/meisnate12/Plex-Meta-Manager
synced 2024-11-10 06:54:21 +00:00
fixed detect image changes
This commit is contained in:
parent
c6c0429fb3
commit
7e55107d36
5 changed files with 118 additions and 74 deletions
|
@ -1,7 +1,7 @@
|
|||
import logging, os, re
|
||||
from datetime import datetime, timedelta
|
||||
from modules import anidb, anilist, imdb, letterboxd, mal, plex, radarr, sonarr, tautulli, tmdb, trakttv, tvdb, util
|
||||
from modules.util import Failed
|
||||
from modules.util import Failed, Image
|
||||
from plexapi.exceptions import BadRequest, NotFound
|
||||
from plexapi.video import Movie, Show
|
||||
from urllib.parse import quote
|
||||
|
@ -1742,42 +1742,47 @@ class CollectionBuilder:
|
|||
for p in self.posters:
|
||||
logger.info(f"Method: {p} Poster: {self.posters[p]}")
|
||||
|
||||
if "url_poster" in self.posters: self.library.upload_image("url_poster", self.obj, self.posters["url_poster"])
|
||||
elif "file_poster" in self.posters: self.library.upload_image("file_poster", self.obj, self.posters["file_poster"], url=False)
|
||||
elif "tmdb_poster" in self.posters: self.library.upload_image("tmdb_poster", self.obj, self.posters["tmdb_poster"])
|
||||
elif "tmdb_profile" in self.posters: self.library.upload_image("tmdb_poster", self.obj, self.posters["tmdb_profile"])
|
||||
elif "tvdb_poster" in self.posters: self.library.upload_image("tvdb_poster", self.obj, self.posters["tvdb_poster"])
|
||||
elif "asset_directory" in self.posters: self.library.upload_image("asset_directory", self.obj, self.posters["asset_directory"], url=False)
|
||||
elif "tmdb_person" in self.posters: self.library.upload_image("tmdb_person", self.obj, self.posters["tmdb_person"])
|
||||
elif "tmdb_collection_details" in self.posters: self.library.upload_image("tmdb_collection_details", self.obj, self.posters["tmdb_collection_details"])
|
||||
elif "tmdb_actor_details" in self.posters: self.library.upload_image("tmdb_actor_details", self.obj, self.posters["tmdb_actor_details"])
|
||||
elif "tmdb_crew_details" in self.posters: self.library.upload_image("tmdb_crew_details", self.obj, self.posters["tmdb_crew_details"])
|
||||
elif "tmdb_director_details" in self.posters: self.library.upload_image("tmdb_director_details", self.obj, self.posters["tmdb_director_details"])
|
||||
elif "tmdb_producer_details" in self.posters: self.library.upload_image("tmdb_producer_details", self.obj, self.posters["tmdb_producer_details"])
|
||||
elif "tmdb_writer_details" in self.posters: self.library.upload_image("tmdb_writer_details", self.obj, self.posters["tmdb_writer_details"])
|
||||
elif "tmdb_movie_details" in self.posters: self.library.upload_image("tmdb_movie_details", self.obj, self.posters["tmdb_movie_details"])
|
||||
elif "tvdb_movie_details" in self.posters: self.library.upload_image("tvdb_movie_details", self.obj, self.posters["tvdb_movie_details"])
|
||||
elif "tvdb_show_details" in self.posters: self.library.upload_image("tvdb_show_details", self.obj, self.posters["tvdb_show_details"])
|
||||
elif "tmdb_show_details" in self.posters: self.library.upload_image("tmdb_show_details", self.obj, self.posters["tmdb_show_details"])
|
||||
else: logger.info("No poster to update")
|
||||
|
||||
if len(self.backgrounds) > 1:
|
||||
logger.info(f"{len(self.backgrounds)} backgrounds found:")
|
||||
for b in self.backgrounds:
|
||||
logger.info(f"Method: {b} Background: {self.backgrounds[b]}")
|
||||
|
||||
if "url_background" in self.backgrounds: self.library.upload_image("url_background", self.obj, self.backgrounds["url_background"], poster=False)
|
||||
elif "file_background" in self.backgrounds: self.library.upload_image("file_background", self.obj, self.backgrounds["file_background"], poster=False, url=False)
|
||||
elif "tmdb_background" in self.backgrounds: self.library.upload_image("tmdb_background", self.obj, self.backgrounds["tmdb_background"], poster=False)
|
||||
elif "tvdb_background" in self.backgrounds: self.library.upload_image("tvdb_background", self.obj, self.backgrounds["tvdb_background"], poster=False)
|
||||
elif "asset_directory" in self.backgrounds: self.library.upload_image("asset_directory", self.obj, self.backgrounds["asset_directory"], poster=False, url=False)
|
||||
elif "tmdb_collection_details" in self.backgrounds: self.library.upload_image("tmdb_collection_details", self.obj, self.backgrounds["tmdb_collection_details"], poster=False)
|
||||
elif "tmdb_movie_details" in self.backgrounds: self.library.upload_image("tmdb_movie_details", self.obj, self.backgrounds["tmdb_movie_details"], poster=False)
|
||||
elif "tvdb_movie_details" in self.backgrounds: self.library.upload_image("tvdb_movie_details", self.obj, self.backgrounds["tvdb_movie_details"], poster=False)
|
||||
elif "tvdb_show_details" in self.backgrounds: self.library.upload_image("tvdb_show_details", self.obj, self.backgrounds["tvdb_show_details"], poster=False)
|
||||
elif "tmdb_show_details" in self.backgrounds: self.library.upload_image("tmdb_show_details", self.obj, self.backgrounds["tmdb_show_details"], poster=False)
|
||||
poster = None
|
||||
if "url_poster" in self.posters: poster = Image("url_poster", self.posters["url_poster"])
|
||||
elif "file_poster" in self.posters: poster = Image("file_poster", self.posters["file_poster"], is_url=False)
|
||||
elif "tmdb_poster" in self.posters: poster = Image("tmdb_poster", self.posters["tmdb_poster"])
|
||||
elif "tmdb_profile" in self.posters: poster = Image("tmdb_poster", self.posters["tmdb_profile"])
|
||||
elif "tvdb_poster" in self.posters: poster = Image("tvdb_poster", self.posters["tvdb_poster"])
|
||||
elif "asset_directory" in self.posters: poster = Image("asset_directory", self.posters["asset_directory"], is_url=False)
|
||||
elif "tmdb_person" in self.posters: poster = Image("tmdb_person", self.posters["tmdb_person"])
|
||||
elif "tmdb_collection_details" in self.posters: poster = Image("tmdb_collection_details", self.posters["tmdb_collection_details"])
|
||||
elif "tmdb_actor_details" in self.posters: poster = Image("tmdb_actor_details", self.posters["tmdb_actor_details"])
|
||||
elif "tmdb_crew_details" in self.posters: poster = Image("tmdb_crew_details", self.posters["tmdb_crew_details"])
|
||||
elif "tmdb_director_details" in self.posters: poster = Image("tmdb_director_details", self.posters["tmdb_director_details"])
|
||||
elif "tmdb_producer_details" in self.posters: poster = Image("tmdb_producer_details", self.posters["tmdb_producer_details"])
|
||||
elif "tmdb_writer_details" in self.posters: poster = Image("tmdb_writer_details", self.posters["tmdb_writer_details"])
|
||||
elif "tmdb_movie_details" in self.posters: poster = Image("tmdb_movie_details", self.posters["tmdb_movie_details"])
|
||||
elif "tvdb_movie_details" in self.posters: poster = Image("tvdb_movie_details", self.posters["tvdb_movie_details"])
|
||||
elif "tvdb_show_details" in self.posters: poster = Image("tvdb_show_details", self.posters["tvdb_show_details"])
|
||||
elif "tmdb_show_details" in self.posters: poster = Image("tmdb_show_details", self.posters["tmdb_show_details"])
|
||||
else: logger.info("No poster to update")
|
||||
|
||||
background = None
|
||||
if "url_background" in self.backgrounds: background = Image("url_background", self.backgrounds["url_background"], is_poster=False)
|
||||
elif "file_background" in self.backgrounds: background = Image("file_background", self.backgrounds["file_background"], is_poster=False, is_url=False)
|
||||
elif "tmdb_background" in self.backgrounds: background = Image("tmdb_background", self.backgrounds["tmdb_background"], is_poster=False)
|
||||
elif "tvdb_background" in self.backgrounds: background = Image("tvdb_background", self.backgrounds["tvdb_background"], is_poster=False)
|
||||
elif "asset_directory" in self.backgrounds: background = Image("asset_directory", self.backgrounds["asset_directory"], is_poster=False, is_url=False)
|
||||
elif "tmdb_collection_details" in self.backgrounds: background = Image("tmdb_collection_details", self.backgrounds["tmdb_collection_details"], is_poster=False)
|
||||
elif "tmdb_movie_details" in self.backgrounds: background = Image("tmdb_movie_details", self.backgrounds["tmdb_movie_details"], is_poster=False)
|
||||
elif "tvdb_movie_details" in self.backgrounds: background = Image("tvdb_movie_details", self.backgrounds["tvdb_movie_details"], is_poster=False)
|
||||
elif "tvdb_show_details" in self.backgrounds: background = Image("tvdb_show_details", self.backgrounds["tvdb_show_details"], is_poster=False)
|
||||
elif "tmdb_show_details" in self.backgrounds: background = Image("tmdb_show_details", self.backgrounds["tmdb_show_details"], is_poster=False)
|
||||
else: logger.info("No background to update")
|
||||
|
||||
if poster or background:
|
||||
self.library.upload_images(self.obj, poster=poster, background=background)
|
||||
|
||||
def run_collections_again(self):
|
||||
self.obj = self.library.get_collection(self.name)
|
||||
name, collection_items = self.library.get_collection_name_and_items(self.obj, self.smart_label_collection)
|
||||
|
|
|
@ -246,5 +246,5 @@ class Cache:
|
|||
with sqlite3.connect(self.cache_path) as connection:
|
||||
connection.row_factory = sqlite3.Row
|
||||
with closing(connection.cursor()) as cursor:
|
||||
cursor.execute("INSERT OR IGNORE INTO image_map(rating_key, library) VALUES(?, ?)", (rating_key, library))
|
||||
cursor.execute("INSERT OR IGNORE INTO image_map(rating_key, library, type) VALUES(?, ?, ?)", (rating_key, library, image_type))
|
||||
cursor.execute("UPDATE image_map SET location = ?, compare = ? WHERE rating_key = ? AND library = ? AND type = ?", (location, compare, rating_key, library, image_type))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import logging, os, re, requests
|
||||
from datetime import datetime
|
||||
from modules import plex, util
|
||||
from modules.util import Failed
|
||||
from modules.util import Failed, Image
|
||||
from plexapi.exceptions import NotFound
|
||||
from ruamel import yaml
|
||||
|
||||
|
@ -141,21 +141,26 @@ class Metadata:
|
|||
return self.library.edit_tags(attr, obj, add_tags=add_tags, remove_tags=remove_tags, sync_tags=sync_tags)
|
||||
return False
|
||||
|
||||
def set_image(attr, obj, group, alias, poster=True, url=True):
|
||||
def set_image(attr, group, alias, is_poster=True, is_url=True):
|
||||
if group[alias[attr]]:
|
||||
self.library.upload_image(attr, obj, group[alias[attr]], poster=poster, url=url)
|
||||
return Image(attr, group[alias[attr]], is_poster=is_poster, is_url=is_url)
|
||||
else:
|
||||
logger.error(f"Metadata Error: {attr} attribute is blank")
|
||||
|
||||
def set_images(obj, group, alias):
|
||||
poster = None
|
||||
background = None
|
||||
if "url_poster" in alias:
|
||||
set_image("url_poster", obj, group, alias)
|
||||
poster = set_image("url_poster", group, alias)
|
||||
elif "file_poster" in alias:
|
||||
set_image("file_poster", obj, group, alias, url=False)
|
||||
poster = set_image("file_poster", group, alias, is_url=False)
|
||||
if "url_background" in alias:
|
||||
set_image("url_background", obj, group, alias, poster=False)
|
||||
background = set_image("url_background", group, alias, is_poster=False)
|
||||
elif "file_background" in alias:
|
||||
set_image("file_background", obj, group, alias, poster=False, url=False)
|
||||
background = set_image("file_background", group, alias, is_poster=False, is_url=False)
|
||||
|
||||
if poster or background:
|
||||
self.library.upload_images(obj, poster=poster, background=background)
|
||||
|
||||
logger.info("")
|
||||
util.separator()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import glob, logging, os, requests
|
||||
from modules import builder, util
|
||||
from modules.meta import Metadata
|
||||
from modules.util import Failed
|
||||
from modules.util import Failed, Image
|
||||
import plexapi
|
||||
from plexapi import utils
|
||||
from plexapi.exceptions import BadRequest, NotFound, Unauthorized
|
||||
|
@ -426,39 +426,59 @@ class PlexAPI:
|
|||
self.reload(item)
|
||||
|
||||
@retry(stop_max_attempt_number=6, wait_fixed=10000, retry_on_exception=util.retry_if_not_plex)
|
||||
def _upload_image(self, item, location, poster=True, url=True):
|
||||
if poster and url:
|
||||
item.uploadPoster(url=location)
|
||||
elif poster:
|
||||
item.uploadPoster(filepath=location)
|
||||
elif url:
|
||||
item.uploadArt(url=location)
|
||||
def _upload_image(self, item, image):
|
||||
if image.is_poster and image.is_url:
|
||||
item.uploadPoster(url=image.location)
|
||||
elif image.is_poster:
|
||||
item.uploadPoster(filepath=image.location)
|
||||
elif image.is_url:
|
||||
item.uploadArt(url=image.location)
|
||||
else:
|
||||
item.uploadArt(filepath=location)
|
||||
item.uploadArt(filepath=image.location)
|
||||
self.reload(item)
|
||||
|
||||
def upload_image(self, attr, item, location, name="", poster=True, url=True):
|
||||
image_type = "poster" if poster else "background"
|
||||
message = f"{name}{image_type} to [{'URL' if url else 'File'}] {location}"
|
||||
def upload_images(self, item, poster=None, background=None):
|
||||
poster_uploaded = False
|
||||
if poster is not None:
|
||||
try:
|
||||
image = None
|
||||
if self.config.Cache:
|
||||
image, image_compare = self.config.Cache.query_image_map(item.ratingKey, self.original_mapping_name, image_type)
|
||||
compare = location if url else os.stat(location).st_size
|
||||
if compare != image_compare:
|
||||
image, image_compare = self.config.Cache.query_image_map(item.ratingKey, self.original_mapping_name, "poster")
|
||||
if str(poster.compare) != str(image_compare):
|
||||
image = None
|
||||
if image is None \
|
||||
or (image_type == "poster" and image != item.thumb) \
|
||||
or (image_type == "background" and image != item.art):
|
||||
self._upload_image(item, location, poster=poster, url=url)
|
||||
if self.config.Cache:
|
||||
self.reload(item)
|
||||
self.config.Cache.update_image_map(item.ratingKey, self.original_mapping_name, image_type, item.thumb if image_type == "poster" else item.art, compare)
|
||||
logger.info(f"Detail: {attr} updated {message}")
|
||||
if image is None or image != item.thumb:
|
||||
self._upload_image(item, poster)
|
||||
poster_uploaded = True
|
||||
logger.info(f"Detail: {poster.attribute} updated {poster.message}")
|
||||
else:
|
||||
logger.info(f"Detail: {name}{image_type} update not needed")
|
||||
logger.info(f"Detail: {poster.prefix}poster update not needed")
|
||||
except BadRequest:
|
||||
util.print_stacktrace()
|
||||
logger.error(f"Detail: {attr} failed to update {message}")
|
||||
logger.error(f"Detail: {poster.attribute} failed to update {poster.message}")
|
||||
|
||||
background_uploaded = False
|
||||
if background is not None:
|
||||
try:
|
||||
image = None
|
||||
if self.config.Cache:
|
||||
image, image_compare = self.config.Cache.query_image_map(item.ratingKey, self.original_mapping_name, "background")
|
||||
if str(background.compare) != str(image_compare):
|
||||
image = None
|
||||
if image is None or image != item.art:
|
||||
self._upload_image(item, background)
|
||||
background_uploaded = True
|
||||
logger.info(f"Detail: {background.attribute} updated {background.message}")
|
||||
else:
|
||||
logger.info(f"Detail: {background.prefix}background update not needed")
|
||||
except BadRequest:
|
||||
util.print_stacktrace()
|
||||
logger.error(f"Detail: {background.attribute} failed to update {background.message}")
|
||||
|
||||
if self.config.Cache:
|
||||
if poster_uploaded:
|
||||
self.config.Cache.update_image_map(item.ratingKey, self.original_mapping_name, "poster", item.thumb, poster.compare)
|
||||
if background_uploaded:
|
||||
self.config.Cache.update_image_map(item.ratingKey, self.original_mapping_name, "background", item.art, background.compare)
|
||||
|
||||
@retry(stop_max_attempt_number=6, wait_fixed=10000, retry_on_exception=util.retry_if_not_failed)
|
||||
def get_search_choices(self, search_name, title=True):
|
||||
|
@ -736,6 +756,8 @@ class PlexAPI:
|
|||
elif not name:
|
||||
name = os.path.basename(os.path.dirname(item.locations[0]) if self.is_movie else item.locations[0])
|
||||
for ad in dirs:
|
||||
poster = None
|
||||
background = None
|
||||
poster_image = None
|
||||
background_image = None
|
||||
if self.asset_folders:
|
||||
|
@ -750,12 +772,14 @@ class PlexAPI:
|
|||
if len(matches) > 0:
|
||||
poster_image = os.path.abspath(matches[0])
|
||||
if upload:
|
||||
self.upload_image("asset_directory", item, poster_image, name=f"{item.title}'s ", url=False)
|
||||
poster = Image("asset_directory", poster_image, prefix=f"{item.title}'s ", is_url=False)
|
||||
matches = glob.glob(background_filter)
|
||||
if len(matches) > 0:
|
||||
background_image = os.path.abspath(matches[0])
|
||||
if upload:
|
||||
self.upload_image("asset_directory", item, background_image, name=f"{item.title}'s ", poster=False, url=False)
|
||||
background = Image("asset_directory", background_image, prefix=f"{item.title}'s ", is_poster=False, is_url=False)
|
||||
if poster or background:
|
||||
self.upload_images(item, poster=poster, background=background)
|
||||
if collection_mode:
|
||||
for ite in self.query(item.items):
|
||||
self.update_item_from_assets(ite, dirs=[os.path.join(ad, name)])
|
||||
|
@ -770,7 +794,7 @@ class PlexAPI:
|
|||
matches = glob.glob(season_filter)
|
||||
if len(matches) > 0:
|
||||
season_path = os.path.abspath(matches[0])
|
||||
self.upload_image("asset_directory", season, season_path, name=f"{item.title} Season {season.seasonNumber}'s ", url=False)
|
||||
self.upload_images(season, poster=Image("asset_directory", season_path, prefix=f"{item.title} Season {season.seasonNumber}'s ", is_url=False))
|
||||
for episode in self.query(season.episodes):
|
||||
if self.asset_folders:
|
||||
episode_filter = os.path.join(ad, name, f"{episode.seasonEpisode.upper()}.*")
|
||||
|
@ -779,5 +803,5 @@ class PlexAPI:
|
|||
matches = glob.glob(episode_filter)
|
||||
if len(matches) > 0:
|
||||
episode_path = os.path.abspath(matches[0])
|
||||
self.upload_image("asset_directory", episode, episode_path, name=f"{item.title} {episode.seasonEpisode.upper()}'s ", url=False)
|
||||
self.upload_images(episode, poster=Image("asset_directory", episode_path, prefix=f"{item.title} {episode.seasonEpisode.upper()}'s ", is_url=False))
|
||||
return None, None
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import logging, re, signal, sys, time, traceback
|
||||
import logging, os, re, signal, sys, time, traceback
|
||||
from datetime import datetime
|
||||
from pathvalidate import is_valid_filename, sanitize_filename
|
||||
from plexapi.exceptions import BadRequest, NotFound, Unauthorized
|
||||
|
@ -18,6 +18,16 @@ class TimeoutExpired(Exception):
|
|||
class Failed(Exception):
|
||||
pass
|
||||
|
||||
class Image:
|
||||
def __init__(self, attribute, location, prefix="", is_poster=True, is_url=True):
|
||||
self.attribute = attribute
|
||||
self.location = location
|
||||
self.prefix = prefix
|
||||
self.is_poster = is_poster
|
||||
self.is_url = is_url
|
||||
self.compare = location if is_url else os.stat(location).st_size
|
||||
self.message = f"{prefix}{'poster' if is_poster else 'background'} to [{'URL' if is_url else 'File'}] {location}"
|
||||
|
||||
def retry_if_not_failed(exception):
|
||||
return not isinstance(exception, Failed)
|
||||
|
||||
|
|
Loading…
Reference in a new issue