mirror of
https://github.com/meisnate12/Plex-Meta-Manager
synced 2025-02-18 06:48:25 +00:00
[30] add mass episode ratings
This commit is contained in:
parent
64d2d8874f
commit
43d08bad15
8 changed files with 227 additions and 64 deletions
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
1.17.0-develop29
|
||||
1.17.0-develop30
|
||||
|
|
|
@ -17,14 +17,15 @@ libraries:
|
|||
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 than 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><tr><td>`anidb`</td><td>Use AniDB Tags for Genres</td></tr></table> |
|
||||
| `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>`imdb`</td><td>Use IMDb for Genres</td></tr><tr><td>`omdb`</td><td>Use IMDb through OMDb for Genres</td></tr><tr><td>`anidb`</td><td>Use AniDB Tags for Genres</td></tr></table> |
|
||||
| `mass_content_rating_update` | Updates every item's content rating in the library to the chosen site's content rating<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_originally_available_update` | Updates every item's originally available date in the library to the chosen site's date<br>**Values:** <table class="clearTable"><tr><td>`tmdb`</td><td>Use TMDb Release Date</td></tr><tr><td>`tvdb`</td><td>Use TVDb Release Date</td></tr><tr><td>`omdb`</td><td>Use IMDb Release Date through OMDb</td></tr><tr><td>`mdb`</td><td>Use MdbList Release Date</td></tr><tr><td>`anidb`</td><td>Use AniDB Release Date</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><tr><td>`anidb_rating`</td><td>Use AniDB Rating</td></tr><tr><td>`anidb_average`</td><td>Use AniDB Average</td></tr></table> |
|
||||
| `mass_audience_rating_update`/<br>`mass_critic_rating_update`/<br>`mass_user_rating_update` | Updates every item's audience/critic/user 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>`imdb`</td><td>Use IMDb 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><tr><td>`anidb_rating`</td><td>Use AniDB Rating</td></tr><tr><td>`anidb_average`</td><td>Use AniDB Average</td></tr></table> |
|
||||
| `mass_episode_audience_rating_update`/<br>`mass_episode_critic_rating_update`/<br>`mass_episode_user_rating_update` | Updates every item's episode's audience/critic/user 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>`imdb`</td><td>Use IMDb Rating</td></tr></table> |
|
||||
| `mass_imdb_parental_labels` | Updates every item's labels in the library to match the IMDb Parental Guide<br>**Values** `with_none` or `without_none` |
|
||||
| `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> |
|
||||
|
|
|
@ -33,12 +33,14 @@ from retrying import retry
|
|||
logger = util.logger
|
||||
|
||||
sync_modes = {"append": "Only Add Items to the Collection or Playlist", "sync": "Add & Remove Items from the Collection or Playlist"}
|
||||
mass_genre_options = {"tmdb": "Use TMDb Metadata", "omdb": "Use IMDb Metadata through OMDb", "tvdb": "Use TVDb Metadata", "anidb": "Use AniDB Tag Metadata"}
|
||||
mass_genre_options = {"tmdb": "Use TMDb Metadata", "imdb": "Use IMDb Rating", "omdb": "Use IMDb Metadata through OMDb", "tvdb": "Use TVDb Metadata", "anidb": "Use AniDB Tag Metadata"}
|
||||
mass_content_options = {"omdb": "Use IMDb Metadata through OMDb", "mdb": "Use MdbList Metadata", "mdb_commonsense": "Use Commonsense Rating through MDbList"}
|
||||
mass_available_options = {"tmdb": "Use TMDb Metadata", "omdb": "Use IMDb Metadata through OMDb", "mdb": "Use MdbList Metadata", "tvdb": "Use TVDb Metadata", "anidb": "Use AniDB Metadata"}
|
||||
imdb_label_options = {"with_none": "Add IMDb Parental Labels including None", "without_none": "Add IMDb Parental Labels including None"}
|
||||
mass_episode_rating_options = {"tmdb": "Use TMDb Rating", "imdb": "Use IMDb Rating"}
|
||||
mass_rating_options = {
|
||||
"tmdb": "Use TMDb Rating",
|
||||
"imdb": "Use IMDb Rating",
|
||||
"omdb": "Use IMDb Rating through OMDb",
|
||||
"mdb": "Use MdbList Average Score",
|
||||
"mdb_imdb": "Use IMDb Rating through MDbList",
|
||||
|
@ -584,6 +586,9 @@ class ConfigFile:
|
|||
"mass_originally_available_update": None,
|
||||
"mass_imdb_parental_labels": None,
|
||||
"remove_title_parentheses": None,
|
||||
"mass_episode_audience_rating_update": None,
|
||||
"mass_episode_critic_rating_update": None,
|
||||
"mass_episode_user_rating_update": None,
|
||||
}
|
||||
display_name = f"{params['name']} ({params['mapping_name']})" if lib and "library_name" in lib and lib["library_name"] else params["mapping_name"]
|
||||
|
||||
|
@ -652,6 +657,14 @@ class ConfigFile:
|
|||
params["mass_audience_rating_update"] = check_for_attribute(lib["operations"], "mass_audience_rating_update", test_list=mass_rating_options, default_is_none=True, save=False)
|
||||
if "mass_critic_rating_update" in lib["operations"]:
|
||||
params["mass_critic_rating_update"] = check_for_attribute(lib["operations"], "mass_critic_rating_update", test_list=mass_rating_options, default_is_none=True, save=False)
|
||||
if "mass_user_rating_update" in lib["operations"]:
|
||||
params["mass_user_rating_update"] = check_for_attribute(lib["operations"], "mass_user_rating_update", test_list=mass_rating_options, default_is_none=True, save=False)
|
||||
if "mass_episode_audience_rating_update" in lib["operations"]:
|
||||
params["mass_episode_audience_rating_update"] = check_for_attribute(lib["operations"], "mass_episode_audience_rating_update", test_list=mass_episode_rating_options, default_is_none=True, save=False)
|
||||
if "mass_episode_critic_rating_update" in lib["operations"]:
|
||||
params["mass_episode_critic_rating_update"] = check_for_attribute(lib["operations"], "mass_episode_critic_rating_update", test_list=mass_episode_rating_options, default_is_none=True, save=False)
|
||||
if "mass_episode_user_rating_update" in lib["operations"]:
|
||||
params["mass_episode_user_rating_update"] = check_for_attribute(lib["operations"], "mass_episode_user_rating_update", test_list=mass_episode_rating_options, default_is_none=True, save=False)
|
||||
if "mass_content_rating_update" in lib["operations"]:
|
||||
params["mass_content_rating_update"] = check_for_attribute(lib["operations"], "mass_content_rating_update", test_list=mass_content_options, default_is_none=True, save=False)
|
||||
if "mass_originally_available_update" in lib["operations"]:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import math, re, time
|
||||
import csv, gzip, math, os, re, requests, shutil, time
|
||||
from modules import util
|
||||
from modules.util import Failed
|
||||
from urllib.parse import urlparse, parse_qs
|
||||
|
@ -30,6 +30,9 @@ urls = {
|
|||
class IMDb:
|
||||
def __init__(self, config):
|
||||
self.config = config
|
||||
self._ratings = None
|
||||
self._genres = None
|
||||
self._episode_ratings = None
|
||||
|
||||
def validate_imdb_lists(self, err_type, imdb_lists, language):
|
||||
valid_lists = []
|
||||
|
@ -185,3 +188,71 @@ class IMDb:
|
|||
return [(_i, "imdb") for _i in self._ids_from_chart(data)]
|
||||
else:
|
||||
raise Failed(f"IMDb Error: Method {method} not supported")
|
||||
|
||||
def _interface(self, interface):
|
||||
gz = os.path.join(self.config.default_dir, f"title.{interface}.tsv.gz")
|
||||
tsv = os.path.join(self.config.default_dir, f"title.{interface}.tsv")
|
||||
|
||||
if os.path.exists(gz):
|
||||
os.remove(gz)
|
||||
if os.path.exists(tsv):
|
||||
os.remove(tsv)
|
||||
|
||||
with requests.get(f"https://datasets.imdbws.com/title.{interface}.tsv.gz", stream=True) as r:
|
||||
r.raise_for_status()
|
||||
total_length = r.headers.get('content-length')
|
||||
if total_length is not None:
|
||||
total_length = int(total_length)
|
||||
dl = 0
|
||||
with open(gz, "wb") as f:
|
||||
for chunk in r.iter_content(chunk_size=8192):
|
||||
dl += len(chunk)
|
||||
f.write(chunk)
|
||||
logger.ghost(f"Downloading IMDb Interface: {dl / total_length * 100:6.2f}%")
|
||||
logger.exorcise()
|
||||
|
||||
with open(tsv, "wb") as f_out:
|
||||
with gzip.open(gz, "rb") as f_in:
|
||||
shutil.copyfileobj(f_in, f_out)
|
||||
|
||||
with open(tsv, "r") as t:
|
||||
if interface == "ratings":
|
||||
return {line[0]: line[1] for line in csv.reader(t, delimiter="\t")}
|
||||
elif interface == "basics":
|
||||
return {line[0]: str(line[-1]).split(",") for line in csv.reader(tsv, delimiter="\t")}
|
||||
else:
|
||||
return [line for line in csv.reader(t, delimiter="\t")]
|
||||
|
||||
@property
|
||||
def ratings(self):
|
||||
if self._ratings is None:
|
||||
self._ratings = self._interface("ratings")
|
||||
return self._ratings
|
||||
|
||||
@property
|
||||
def genres(self):
|
||||
if self._genres is None:
|
||||
self._genres = self._interface("basics")
|
||||
return self._genres
|
||||
|
||||
@property
|
||||
def episode_ratings(self):
|
||||
if self._episode_ratings is None:
|
||||
self._episode_ratings = {}
|
||||
for imdb_id, parent_id, season_num, episode_num in self._interface("episode"):
|
||||
if imdb_id not in self.ratings:
|
||||
continue
|
||||
if parent_id not in self._episode_ratings:
|
||||
self._episode_ratings[parent_id] = {}
|
||||
if season_num not in self._episode_ratings[parent_id]:
|
||||
self._episode_ratings[parent_id][season_num] = {}
|
||||
self._episode_ratings[parent_id][season_num][episode_num] = self.ratings[imdb_id]
|
||||
return self._episode_ratings
|
||||
|
||||
def get_rating(self, imdb_id):
|
||||
return self.ratings[imdb_id] if imdb_id in self.ratings else None
|
||||
|
||||
def get_episode_rating(self, imdb_id, season_num, episode_num):
|
||||
if imdb_id not in self.episode_ratings or season_num not in self.episode_ratings[imdb_id] or episode_num not in self.episode_ratings[imdb_id][season_num]:
|
||||
return None
|
||||
return self.episode_ratings[imdb_id][season_num][episode_num]
|
||||
|
|
|
@ -77,6 +77,10 @@ class Library(ABC):
|
|||
self.mass_genre_update = params["mass_genre_update"]
|
||||
self.mass_audience_rating_update = params["mass_audience_rating_update"]
|
||||
self.mass_critic_rating_update = params["mass_critic_rating_update"]
|
||||
self.mass_user_rating_update = params["mass_user_rating_update"]
|
||||
self.mass_episode_audience_rating_update = params["mass_episode_audience_rating_update"]
|
||||
self.mass_episode_critic_rating_update = params["mass_episode_critic_rating_update"]
|
||||
self.mass_episode_user_rating_update = params["mass_episode_user_rating_update"]
|
||||
self.mass_content_rating_update = params["mass_content_rating_update"]
|
||||
self.mass_originally_available_update = params["mass_originally_available_update"]
|
||||
self.mass_imdb_parental_labels = params["mass_imdb_parental_labels"]
|
||||
|
@ -101,13 +105,18 @@ class Library(ABC):
|
|||
self.stats = {"created": 0, "modified": 0, "deleted": 0, "added": 0, "unchanged": 0, "removed": 0, "radarr": 0, "sonarr": 0, "names": []}
|
||||
self.status = {}
|
||||
|
||||
self.items_library_operation = True if self.assets_for_all or self.mass_genre_update or self.mass_audience_rating_update or self.remove_title_parentheses \
|
||||
or self.mass_critic_rating_update or self.mass_content_rating_update or self.mass_originally_available_update or self.mass_imdb_parental_labels or self.mass_trakt_rating_update \
|
||||
or self.genre_mapper or self.content_rating_mapper or self.radarr_add_all_existing or self.sonarr_add_all_existing else False
|
||||
self.items_library_operation = True if self.assets_for_all or self.mass_genre_update or self.remove_title_parentheses \
|
||||
or self.mass_audience_rating_update or self.mass_critic_rating_update or self.mass_user_rating_update \
|
||||
or self.mass_episode_audience_rating_update or self.mass_episode_critic_rating_update or self.mass_episode_user_rating_update \
|
||||
or self.mass_content_rating_update or self.mass_originally_available_update or self.mass_imdb_parental_labels \
|
||||
or self.mass_trakt_rating_update or self.genre_mapper or self.content_rating_mapper \
|
||||
or self.radarr_add_all_existing or self.sonarr_add_all_existing else False
|
||||
self.library_operation = True if self.items_library_operation or self.delete_unmanaged_collections or self.delete_collections_with_less \
|
||||
or self.radarr_remove_by_tag or self.sonarr_remove_by_tag or self.mass_collection_mode \
|
||||
or self.show_unmanaged or self.metadata_backup or self.update_blank_track_titles else False
|
||||
self.meta_operations = [self.mass_genre_update, self.mass_audience_rating_update, self.mass_critic_rating_update, self.mass_content_rating_update, self.mass_originally_available_update]
|
||||
self.meta_operations = [self.mass_genre_update, self.mass_audience_rating_update, self.mass_critic_rating_update,
|
||||
self.mass_user_rating_update, self.mass_episode_audience_rating_update, self.mass_episode_critic_rating_update,
|
||||
self.mass_episode_user_rating_update, self.mass_content_rating_update, self.mass_originally_available_update]
|
||||
|
||||
if self.asset_directory:
|
||||
logger.info("")
|
||||
|
|
|
@ -2,8 +2,6 @@ import os, re
|
|||
from datetime import datetime
|
||||
from modules import plex, util
|
||||
from modules.util import Failed, YAML
|
||||
from plexapi.audio import Artist
|
||||
from plexapi.video import Show
|
||||
|
||||
logger = util.logger
|
||||
|
||||
|
@ -23,6 +21,10 @@ class Operations:
|
|||
logger.debug(f"Mass Genre Update: {self.library.mass_genre_update}")
|
||||
logger.debug(f"Mass Audience Rating Update: {self.library.mass_audience_rating_update}")
|
||||
logger.debug(f"Mass Critic Rating Update: {self.library.mass_critic_rating_update}")
|
||||
logger.debug(f"Mass User Rating Update: {self.library.mass_user_rating_update}")
|
||||
logger.debug(f"Mass Episode Audience Rating Update: {self.library.mass_episode_audience_rating_update}")
|
||||
logger.debug(f"Mass Episode Critic Rating Update: {self.library.mass_episode_critic_rating_update}")
|
||||
logger.debug(f"Mass Episode User Rating Update: {self.library.mass_episode_user_rating_update}")
|
||||
logger.debug(f"Mass Content Rating Update: {self.library.mass_content_rating_update}")
|
||||
logger.debug(f"Mass Originally Available Update: {self.library.mass_originally_available_update}")
|
||||
logger.debug(f"Mass IMDb Parental Labels: {self.library.mass_imdb_parental_labels}")
|
||||
|
@ -136,12 +138,11 @@ class Operations:
|
|||
|
||||
omdb_item = None
|
||||
if any([o == "omdb" for o in self.library.meta_operations]):
|
||||
if self.config.OMDb.limit is False:
|
||||
if tmdb_id and not imdb_id:
|
||||
imdb_id = self.config.Convert.tmdb_to_imdb(tmdb_id)
|
||||
elif tvdb_id and not imdb_id:
|
||||
imdb_id = self.config.Convert.tvdb_to_imdb(tvdb_id)
|
||||
if imdb_id:
|
||||
if self.config.OMDb.limit is not False:
|
||||
logger.error("Daily OMDb Limit Reached")
|
||||
elif not imdb_id:
|
||||
logger.info(f"{item.title[:25]:<25} | No IMDb ID for Guid: {item.guid}")
|
||||
else:
|
||||
try:
|
||||
omdb_item = self.config.OMDb.get_omdb(imdb_id)
|
||||
except Failed as e:
|
||||
|
@ -149,8 +150,6 @@ class Operations:
|
|||
except Exception:
|
||||
logger.error(f"IMDb ID: {imdb_id}")
|
||||
raise
|
||||
else:
|
||||
logger.info(f"{item.title[:25]:<25} | No IMDb ID for Guid: {item.guid}")
|
||||
|
||||
tvdb_item = None
|
||||
if any([o == "tvdb" for o in self.library.meta_operations]):
|
||||
|
@ -200,6 +199,8 @@ class Operations:
|
|||
def get_rating(attribute):
|
||||
if tmdb_item and attribute == "tmdb":
|
||||
return tmdb_item.vote_average
|
||||
elif imdb_id and attribute == "imdb":
|
||||
return self.config.imdb.get_rating(imdb_id)
|
||||
elif omdb_item and attribute == "omdb":
|
||||
return omdb_item.imdb_rating
|
||||
elif mdb_item and attribute == "mdb":
|
||||
|
@ -233,6 +234,8 @@ class Operations:
|
|||
if self.library.mass_genre_update:
|
||||
if tmdb_item and self.library.mass_genre_update == "tmdb":
|
||||
new_genres = tmdb_item.genres
|
||||
elif imdb_id and self.library.mass_genre_update == "imdb" and imdb_id in self.config.imdb.genres:
|
||||
new_genres = self.config.imdb.genres[imdb_id]
|
||||
elif omdb_item and self.library.mass_genre_update == "omdb":
|
||||
new_genres = omdb_item.genres
|
||||
elif tvdb_item and self.library.mass_genre_update == "tvdb":
|
||||
|
@ -276,7 +279,18 @@ class Operations:
|
|||
logger.info(f"{item.title[:25]:<25} | No Rating Found")
|
||||
elif str(item.rating) != str(new_rating):
|
||||
item.editField("rating", new_rating)
|
||||
batch_display += f"{item.title[:25]:<25} | Critic Rating | {new_rating}"
|
||||
batch_display += f"\n{item.title[:25]:<25} | Critic Rating | {new_rating}"
|
||||
except Failed:
|
||||
pass
|
||||
|
||||
if self.library.mass_user_rating_update:
|
||||
try:
|
||||
new_rating = get_rating(self.library.mass_user_rating_update)
|
||||
if new_rating is None:
|
||||
logger.info(f"{item.title[:25]:<25} | No Rating Found")
|
||||
elif str(item.userRating) != str(new_rating):
|
||||
item.editField("userRating", new_rating)
|
||||
batch_display += f"\n{item.title[:25]:<25} | User Rating | {new_rating}"
|
||||
except Failed:
|
||||
pass
|
||||
|
||||
|
@ -327,6 +341,62 @@ class Operations:
|
|||
pass
|
||||
|
||||
item.saveEdits()
|
||||
logger.info(batch_display)
|
||||
|
||||
episode_ops = [self.library.mass_episode_audience_rating_update, self.library.mass_episode_critic_rating_update, self.library.mass_episode_user_rating_update]
|
||||
|
||||
if any([x is not None for x in episode_ops]):
|
||||
|
||||
if any([x == "imdb" for x in episode_ops]) and not imdb_id:
|
||||
logger.info(f"{item.title[:25]:<25} | No IMDb ID for Guid: {item.guid}")
|
||||
|
||||
for ep in item.episodes():
|
||||
ep.batchEdits()
|
||||
item_title = self.library.get_item_sort_title(ep, atr="title")
|
||||
|
||||
def get_episode_rating(attribute):
|
||||
if tmdb_id and attribute == "tmdb":
|
||||
try:
|
||||
return self.config.TMDb.get_episode(tmdb_id, ep.seasonNumber, ep.episodeNumber).vote_average
|
||||
except Failed as er:
|
||||
logger.error(er)
|
||||
elif imdb_id and attribute == "imdb":
|
||||
return self.config.IMDb.get_episode_rating(imdb_id, ep.seasonNumber, ep.episodeNumber)
|
||||
else:
|
||||
raise Failed
|
||||
|
||||
if self.library.mass_episode_audience_rating_update:
|
||||
try:
|
||||
new_rating = get_episode_rating(self.library.mass_episode_audience_rating_update)
|
||||
if new_rating is None:
|
||||
logger.info(f"{item_title[:25]:<25} | No Rating Found")
|
||||
elif str(ep.audienceRating) != str(new_rating):
|
||||
ep.editField("audienceRating", new_rating)
|
||||
logger.info(f"\n{item_title[:25]:<25} | Audience Rating | {new_rating}")
|
||||
except Failed:
|
||||
pass
|
||||
|
||||
if self.library.mass_episode_critic_rating_update:
|
||||
try:
|
||||
new_rating = get_episode_rating(self.library.mass_episode_critic_rating_update)
|
||||
if new_rating is None:
|
||||
logger.info(f"{item_title[:25]:<25} | No Rating Found")
|
||||
elif str(ep.rating) != str(new_rating):
|
||||
ep.editField("rating", new_rating)
|
||||
logger.info(f"{item_title[:25]:<25} | Critic Rating | {new_rating}")
|
||||
except Failed:
|
||||
pass
|
||||
|
||||
if self.library.mass_episode_user_rating_update:
|
||||
try:
|
||||
new_rating = get_episode_rating(self.library.mass_episode_user_rating_update)
|
||||
if new_rating is None:
|
||||
logger.info(f"{item_title[:25]:<25} | No Rating Found")
|
||||
elif str(ep.userRating) != str(new_rating):
|
||||
ep.editField("userRating", new_rating)
|
||||
logger.info(f"{item_title[:25]:<25} | User Rating | {new_rating}")
|
||||
except Failed:
|
||||
pass
|
||||
|
||||
if self.library.Radarr and self.library.radarr_add_all_existing:
|
||||
try:
|
||||
|
|
|
@ -3,7 +3,6 @@ from datetime import datetime
|
|||
from modules import plex, util
|
||||
from modules.builder import CollectionBuilder
|
||||
from modules.util import Failed, NotScheduled
|
||||
from plexapi.audio import Album
|
||||
from plexapi.exceptions import BadRequest
|
||||
from plexapi.video import Movie, Show, Season, Episode
|
||||
from PIL import Image, ImageFilter
|
||||
|
@ -37,7 +36,7 @@ class Overlays:
|
|||
logger.separator(f"Removing {old_overlay.title}")
|
||||
logger.info("")
|
||||
for i, item in enumerate(label_items, 1):
|
||||
item_title = self.get_item_sort_title(item, atr="title")
|
||||
item_title = self.library.get_item_sort_title(item, atr="title")
|
||||
logger.ghost(f"Restoring {old_overlay.title}: {i}/{len(label_items)} {item_title}")
|
||||
self.remove_overlay(item, item_title, old_overlay.title, [
|
||||
os.path.join(self.library.overlay_folder, old_overlay.title[:-8], f"{item.ratingKey}.png")
|
||||
|
@ -61,7 +60,7 @@ class Overlays:
|
|||
if remove_overlays:
|
||||
logger.separator(f"Removing Overlays for the {self.library.name} Library")
|
||||
for i, item in enumerate(remove_overlays, 1):
|
||||
item_title = self.get_item_sort_title(item, atr="title")
|
||||
item_title = self.library.get_item_sort_title(item, atr="title")
|
||||
logger.ghost(f"Restoring: {i}/{len(remove_overlays)} {item_title}")
|
||||
self.remove_overlay(item, item_title, "Overlay", [
|
||||
os.path.join(self.library.overlay_backup, f"{item.ratingKey}.png"),
|
||||
|
@ -75,9 +74,9 @@ class Overlays:
|
|||
logger.info("")
|
||||
logger.separator(f"Applying Overlays for the {self.library.name} Library")
|
||||
logger.info("")
|
||||
for i, (over_key, (item, over_names)) in enumerate(sorted(key_to_overlays.items(), key=lambda io: self.get_item_sort_title(io[1][0])), 1):
|
||||
for i, (over_key, (item, over_names)) in enumerate(sorted(key_to_overlays.items(), key=lambda io: self.library.get_item_sort_title(io[1][0])), 1):
|
||||
try:
|
||||
item_title = self.get_item_sort_title(item, atr="title")
|
||||
item_title = self.library.get_item_sort_title(item, atr="title")
|
||||
logger.ghost(f"Overlaying: {i}/{len(key_to_overlays)} {item_title}")
|
||||
image_compare = None
|
||||
overlay_compare = None
|
||||
|
@ -278,16 +277,6 @@ class Overlays:
|
|||
logger.separator(f"Finished {self.library.name} Library Overlays\nOverlays Run Time: {overlay_run_time}")
|
||||
return overlay_run_time
|
||||
|
||||
def get_item_sort_title(self, item_to_sort, atr="titleSort"):
|
||||
if isinstance(item_to_sort, Album):
|
||||
return f"{getattr(item_to_sort.artist(), atr)} Album {getattr(item_to_sort, atr)}"
|
||||
elif isinstance(item_to_sort, Season):
|
||||
return f"{getattr(item_to_sort.show(), atr)} Season {item_to_sort.seasonNumber}"
|
||||
elif isinstance(item_to_sort, Episode):
|
||||
return f"{getattr(item_to_sort.show(), atr)} {item_to_sort.seasonEpisode.upper()}"
|
||||
else:
|
||||
return getattr(item_to_sort, atr)
|
||||
|
||||
def compile_overlays(self):
|
||||
key_to_item = {}
|
||||
properties = {}
|
||||
|
@ -334,7 +323,7 @@ class Overlays:
|
|||
if item.ratingKey not in properties[builder.overlay.name].keys:
|
||||
properties[builder.overlay.name].keys.append(item.ratingKey)
|
||||
if added_titles:
|
||||
logger.debug(f"{len(added_titles)} Titles Found: {[self.get_item_sort_title(a, atr='title') for a in added_titles]}")
|
||||
logger.debug(f"{len(added_titles)} Titles Found: {[self.library.get_item_sort_title(a, atr='title') for a in added_titles]}")
|
||||
logger.info(f"{len(added_titles) if added_titles else 'No'} Items found for {builder.overlay.name}")
|
||||
except NotScheduled as e:
|
||||
logger.info(e)
|
||||
|
|
|
@ -1184,6 +1184,16 @@ class Plex(Library):
|
|||
|
||||
return map_key, attrs
|
||||
|
||||
def get_item_sort_title(self, item_to_sort, atr="titleSort"):
|
||||
if isinstance(item_to_sort, Album):
|
||||
return f"{getattr(item_to_sort.artist(), atr)} Album {getattr(item_to_sort, atr)}"
|
||||
elif isinstance(item_to_sort, Season):
|
||||
return f"{getattr(item_to_sort.show(), atr)} Season {item_to_sort.seasonNumber}"
|
||||
elif isinstance(item_to_sort, Episode):
|
||||
return f"{getattr(item_to_sort.show(), atr)} {item_to_sort.seasonEpisode.upper()}"
|
||||
else:
|
||||
return getattr(item_to_sort, atr)
|
||||
|
||||
def split(self, text):
|
||||
attribute, modifier = os.path.splitext(str(text).lower())
|
||||
attribute = method_alias[attribute] if attribute in method_alias else attribute
|
||||
|
|
Loading…
Add table
Reference in a new issue