|
|
@ -1,5 +1,8 @@
|
|
|
|
import os, plexapi, requests
|
|
|
|
import os, plexapi, requests
|
|
|
|
from datetime import datetime
|
|
|
|
from datetime import datetime
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
from plexapi.base import PlexObject
|
|
|
|
|
|
|
|
|
|
|
|
from modules import builder, util
|
|
|
|
from modules import builder, util
|
|
|
|
from modules.library import Library
|
|
|
|
from modules.library import Library
|
|
|
|
from modules.util import Failed, ImageData
|
|
|
|
from modules.util import Failed, ImageData
|
|
|
@ -809,118 +812,101 @@ class Plex(Library):
|
|
|
|
logger.info(final)
|
|
|
|
logger.info(final)
|
|
|
|
return final
|
|
|
|
return final
|
|
|
|
|
|
|
|
|
|
|
|
def update_asset(self, item, folders=None, create=None, asset_directory=None):
|
|
|
|
def find_item_assets(self, item, item_asset_directory=None, asset_directory=None):
|
|
|
|
if isinstance(item, (Movie, Artist, Show)):
|
|
|
|
poster = None
|
|
|
|
starting = item.show() if isinstance(item, (Episode, Season)) else item
|
|
|
|
background = None
|
|
|
|
path_test = str(starting.locations[0])
|
|
|
|
item_dir = None
|
|
|
|
if not os.path.dirname(path_test):
|
|
|
|
folder_name = None
|
|
|
|
path_test = path_test.replace("\\", "/")
|
|
|
|
|
|
|
|
name = os.path.basename(os.path.dirname(path_test) if isinstance(starting, Movie) else path_test)
|
|
|
|
|
|
|
|
elif isinstance(item, (Collection, Playlist)):
|
|
|
|
|
|
|
|
name, _ = util.validate_filename(item.title)
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
return None, None, None
|
|
|
|
|
|
|
|
if folders is None:
|
|
|
|
|
|
|
|
folders = self.asset_folders
|
|
|
|
|
|
|
|
if create is None:
|
|
|
|
|
|
|
|
create = self.create_asset_folders
|
|
|
|
|
|
|
|
if asset_directory is None:
|
|
|
|
if asset_directory is None:
|
|
|
|
asset_directory = self.asset_directory
|
|
|
|
asset_directory = self.asset_directory
|
|
|
|
|
|
|
|
|
|
|
|
poster, background, item_dir = self.find_assets(
|
|
|
|
is_top_level = isinstance(item, (Movie, Artist, Show, Collection, Playlist))
|
|
|
|
name="poster" if folders else name,
|
|
|
|
if isinstance(item, Album):
|
|
|
|
folder_name=name if folders else None,
|
|
|
|
prefix = f"{item.title} Album {item.title}'s "
|
|
|
|
prefix=f"{item.title}'s "
|
|
|
|
file_name = item.title
|
|
|
|
)
|
|
|
|
elif isinstance(item, Season):
|
|
|
|
if item_dir and self.dimensional_asset_rename and (not poster or not background):
|
|
|
|
prefix = f"{item.title} Season {item.seasonNumber}'s "
|
|
|
|
for file in util.glob_filter(os.path.join(item_dir, "*.*")):
|
|
|
|
file_name = f"Season{'0' if item.seasonNumber < 10 else ''}{item.seasonNumber}"
|
|
|
|
if file.lower().endswith((".jpg", ".png", ".jpeg")):
|
|
|
|
elif isinstance(item, Episode):
|
|
|
|
image = Image.open(file)
|
|
|
|
prefix = f"{item.title} {item.seasonEpisode.upper()}'s "
|
|
|
|
_w, _h = image.size
|
|
|
|
file_name = item.seasonEpisode.upper()
|
|
|
|
image.close()
|
|
|
|
else:
|
|
|
|
if not poster and _h >= _w:
|
|
|
|
prefix = f"{item.title if is_top_level else item}'s "
|
|
|
|
new_path = os.path.join(os.path.dirname(file), f"poster{os.path.splitext(file)[1].lower()}")
|
|
|
|
file_name = "poster"
|
|
|
|
os.rename(file, new_path)
|
|
|
|
|
|
|
|
poster = ImageData("asset_directory", os.path.abspath(new_path), prefix=f"{item.title}'s ", is_url=False)
|
|
|
|
if not item_asset_directory:
|
|
|
|
elif not background and _w > _h:
|
|
|
|
if isinstance(item, (Movie, Artist, Album, Show, Episode, Season)):
|
|
|
|
new_path = os.path.join(os.path.dirname(file), f"background{os.path.splitext(file)[1].lower()}")
|
|
|
|
starting = item.show() if isinstance(item, (Episode, Season)) else item
|
|
|
|
os.rename(file, new_path)
|
|
|
|
path_test = str(starting.locations[0])
|
|
|
|
background = ImageData("asset_directory", os.path.abspath(new_path), prefix=f"{item.title}'s ", is_poster=False, is_url=False)
|
|
|
|
if not os.path.dirname(path_test):
|
|
|
|
if poster and background:
|
|
|
|
path_test = path_test.replace("\\", "/")
|
|
|
|
break
|
|
|
|
folder_name = os.path.basename(os.path.dirname(path_test) if isinstance(starting, Movie) else path_test)
|
|
|
|
|
|
|
|
elif isinstance(item, (Collection, Playlist)):
|
|
|
|
|
|
|
|
folder_name, _ = util.validate_filename(item.title)
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
folder_name, _ = util.validate_filename(item)
|
|
|
|
|
|
|
|
|
|
|
|
if poster or background:
|
|
|
|
if not self.asset_folders:
|
|
|
|
self.upload_images(item, poster=poster, background=background)
|
|
|
|
file_name = folder_name if file_name == "poster" else f"{folder_name}_{file_name}"
|
|
|
|
|
|
|
|
|
|
|
|
if isinstance(item, Show):
|
|
|
|
for ad in asset_directory:
|
|
|
|
missing_seasons = ""
|
|
|
|
if self.asset_folders:
|
|
|
|
missing_episodes = ""
|
|
|
|
if os.path.isdir(os.path.join(ad, folder_name)):
|
|
|
|
found_season = False
|
|
|
|
item_asset_directory = os.path.join(ad, folder_name)
|
|
|
|
found_episode = False
|
|
|
|
else:
|
|
|
|
for season in self.query(item.seasons):
|
|
|
|
for n in range(1, self.asset_depth + 1):
|
|
|
|
season_name = f"Season{'0' if season.seasonNumber < 10 else ''}{season.seasonNumber}"
|
|
|
|
new_path = ad
|
|
|
|
season_poster, season_background, _ = self.find_assets(
|
|
|
|
for i in range(1, n + 1):
|
|
|
|
name=season_name,
|
|
|
|
new_path = os.path.join(new_path, "*")
|
|
|
|
folder_name=name,
|
|
|
|
matches = util.glob_filter(os.path.join(new_path, folder_name))
|
|
|
|
item_directory=item_dir,
|
|
|
|
if len(matches) > 0:
|
|
|
|
prefix=f"{item.title} Season {season.seasonNumber}'s "
|
|
|
|
item_asset_directory = os.path.abspath(matches[0])
|
|
|
|
)
|
|
|
|
|
|
|
|
if season_poster:
|
|
|
|
|
|
|
|
found_season = True
|
|
|
|
|
|
|
|
elif self.show_missing_season_assets and season.seasonNumber > 0:
|
|
|
|
|
|
|
|
missing_seasons += f"\nMissing Season {season.seasonNumber} Poster"
|
|
|
|
|
|
|
|
if season_poster or season_background:
|
|
|
|
|
|
|
|
self.upload_images(season, poster=season_poster, background=season_background)
|
|
|
|
|
|
|
|
for episode in self.query(season.episodes):
|
|
|
|
|
|
|
|
if episode.seasonEpisode:
|
|
|
|
|
|
|
|
episode_poster, episode_background, _ = self.find_assets(
|
|
|
|
|
|
|
|
name=episode.seasonEpisode.upper(),
|
|
|
|
|
|
|
|
folder_name=name,
|
|
|
|
|
|
|
|
item_directory=item_dir,
|
|
|
|
|
|
|
|
prefix=f"{item.title} {episode.seasonEpisode.upper()}'s "
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
if episode_poster or episode_background:
|
|
|
|
|
|
|
|
found_episode = True
|
|
|
|
|
|
|
|
self.upload_images(episode, poster=episode_poster, background=episode_background)
|
|
|
|
|
|
|
|
elif self.show_missing_episode_assets:
|
|
|
|
|
|
|
|
missing_episodes += f"\nMissing {episode.seasonEpisode.upper()} Title Card"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (found_season and missing_seasons) or (found_episode and missing_episodes):
|
|
|
|
|
|
|
|
output = f"Missing Posters for {item.title}"
|
|
|
|
|
|
|
|
if found_season:
|
|
|
|
|
|
|
|
output += missing_seasons
|
|
|
|
|
|
|
|
if found_episode:
|
|
|
|
|
|
|
|
output += missing_episodes
|
|
|
|
|
|
|
|
logger.info(output)
|
|
|
|
|
|
|
|
if isinstance(item, Artist):
|
|
|
|
|
|
|
|
missing_assets = ""
|
|
|
|
|
|
|
|
found_album = False
|
|
|
|
|
|
|
|
for album in self.query(item.albums):
|
|
|
|
|
|
|
|
album_poster, album_background, _ = self.find_assets(
|
|
|
|
|
|
|
|
name=album.title,
|
|
|
|
|
|
|
|
folder_name=name,
|
|
|
|
|
|
|
|
item_directory=item_dir,
|
|
|
|
|
|
|
|
prefix=f"{item.title} Album {album.title}'s "
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
if album_poster:
|
|
|
|
|
|
|
|
found_album = True
|
|
|
|
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
missing_assets += f"\nMissing Album {album.title} Poster"
|
|
|
|
matches = util.glob_filter(os.path.join(ad, f"{file_name}.*"))
|
|
|
|
if album_poster or album_background:
|
|
|
|
if len(matches) > 0:
|
|
|
|
self.upload_images(album, poster=album_poster, background=album_background)
|
|
|
|
item_asset_directory = ad
|
|
|
|
if self.show_missing_season_assets and found_album and missing_assets:
|
|
|
|
if item_asset_directory:
|
|
|
|
logger.info(f"Missing Album Posters for {item.title}{missing_assets}")
|
|
|
|
break
|
|
|
|
|
|
|
|
if not item_asset_directory:
|
|
|
|
if create and folders and item_dir is None:
|
|
|
|
if self.create_asset_folders and self.asset_folders:
|
|
|
|
filename, _ = util.validate_filename(name)
|
|
|
|
item_asset_directory = os.path.join(asset_directory[0], folder_name)
|
|
|
|
item_dir = os.path.join(asset_directory[0], filename)
|
|
|
|
os.makedirs(item_asset_directory, exist_ok=True)
|
|
|
|
os.makedirs(item_dir, exist_ok=True)
|
|
|
|
logger.info(f"Asset Directory Created: {item_asset_directory}")
|
|
|
|
logger.info(f"Asset Directory Created: {item_dir}")
|
|
|
|
raise Failed(f"Asset Error: Unable to find asset {'folder' if self.asset_folders else 'file'}: {folder_name if self.asset_folders else file_name}")
|
|
|
|
elif folders and item_dir is None:
|
|
|
|
|
|
|
|
logger.warning(f"Asset Warning: No asset folder found called '{name}'")
|
|
|
|
poster_filter = os.path.join(item_asset_directory, f"{file_name}.*")
|
|
|
|
elif not poster and not background and self.show_missing_assets:
|
|
|
|
background_filter = os.path.join(item_asset_directory, "background.*" if file_name == "poster" else f"{file_name}_background.*")
|
|
|
|
logger.warning(f"Asset Warning: No poster or background found in an assets folder for '{name}'")
|
|
|
|
|
|
|
|
return poster, background, item_dir
|
|
|
|
poster_matches = util.glob_filter(poster_filter)
|
|
|
|
|
|
|
|
if len(poster_matches) > 0:
|
|
|
|
|
|
|
|
poster = ImageData("asset_directory", os.path.abspath(poster_matches[0]), prefix=prefix, is_url=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
background_matches = util.glob_filter(background_filter)
|
|
|
|
|
|
|
|
if len(background_matches) > 0:
|
|
|
|
|
|
|
|
background = ImageData("asset_directory", os.path.abspath(background_matches[0]), prefix=prefix, is_poster=False, is_url=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if is_top_level and self.asset_folders and self.dimensional_asset_rename and (not poster or not background):
|
|
|
|
|
|
|
|
for file in util.glob_filter(os.path.join(item_asset_directory, "*.*")):
|
|
|
|
|
|
|
|
if file.lower().endswith((".jpg", ".png", ".jpeg")):
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
image = Image.open(file)
|
|
|
|
|
|
|
|
_w, _h = image.size
|
|
|
|
|
|
|
|
image.close()
|
|
|
|
|
|
|
|
if not poster and _h >= _w:
|
|
|
|
|
|
|
|
new_path = os.path.join(os.path.dirname(file), f"poster{os.path.splitext(file)[1].lower()}")
|
|
|
|
|
|
|
|
os.rename(file, new_path)
|
|
|
|
|
|
|
|
poster = ImageData("asset_directory", os.path.abspath(new_path), prefix=f"{item.title}'s ", is_url=False)
|
|
|
|
|
|
|
|
elif not background and _w > _h:
|
|
|
|
|
|
|
|
new_path = os.path.join(os.path.dirname(file), f"background{os.path.splitext(file)[1].lower()}")
|
|
|
|
|
|
|
|
os.rename(file, new_path)
|
|
|
|
|
|
|
|
background = ImageData("asset_directory", os.path.abspath(new_path), prefix=f"{item.title}'s ", is_poster=False, is_url=False)
|
|
|
|
|
|
|
|
if poster and background:
|
|
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
except OSError:
|
|
|
|
|
|
|
|
logger.error(f"Asset Error: Failed to open image: {file}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return poster, background, item_dir, folder_name
|
|
|
|
|
|
|
|
|
|
|
|
def get_ids(self, item):
|
|
|
|
def get_ids(self, item):
|
|
|
|
tmdb_id = None
|
|
|
|
tmdb_id = None
|
|
|
|