[40] add lock, unlock, remove, reset options to mass_* operations

pull/1052/head
meisnate12 2 years ago
parent eaf0c2fe5d
commit d683dd172f

@ -1 +1 @@
1.17.3-develop39 1.17.3-develop40

@ -17,16 +17,16 @@ libraries:
The available attributes for the operations attribute are as follows The available attributes for the operations attribute are as follows
| Attribute | Description | | Attribute | Description |
|:--------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |:--------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `assets_for_all` | Search in assets for images for every item in your library.<br>**Values:** `true` or `false` | | `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_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` | | `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>`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_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><tr><td>`lock`</td><td>Lock Genre Field</td></tr><tr><td>`unlock`</td><td>Unlock Genre Field</td></tr><tr><td>`remove`</td><td>Remove all Genres and Lock Field</td></tr><tr><td>`reset`</td><td>Remove all Genres and Unlock Field</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_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><tr><td>`lock`</td><td>Lock Rating Field</td></tr><tr><td>`unlock`</td><td>Unlock Rating Field</td></tr><tr><td>`remove`</td><td>Remove Rating and Lock Field</td></tr><tr><td>`reset`</td><td>Remove Rating and Unlock Field</td></tr></table> |
| `mass_original_title_update` | Updates every item's original title in the library to the chosen site's content rating<br>**Values:** <table class="clearTable"><tr><td>`anidb`</td><td>Use AniDB Main Title for Original Titles</td></tr><tr><td>`anidb_official`</td><td>Use AniDB Official Title based on the language attribute in the config file for Original Titles</td></tr></table> | | `mass_original_title_update` | Updates every item's original title in the library to the chosen site's content rating<br>**Values:** <table class="clearTable"><tr><td>`anidb`</td><td>Use AniDB Main Title for Original Titles</td></tr><tr><td>`anidb_official`</td><td>Use AniDB Official Title based on the language attribute in the config file for Original Titles</td></tr><tr><td>`lock`</td><td>Lock Original Title Field</td></tr><tr><td>`unlock`</td><td>Unlock Original Title Field</td></tr><tr><td>`remove`</td><td>Remove Original Title and Lock Field</td></tr><tr><td>`reset`</td><td>Remove Original Title and Unlock Field</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_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><tr><td>`lock`</td><td>Lock Originally Available Field</td></tr><tr><td>`unlock`</td><td>Unlock Originally Available Field</td></tr><tr><td>`remove`</td><td>Remove Originally Available and Lock Field</td></tr><tr><td>`reset`</td><td>Remove Originally Available and Unlock Field</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>`trakt_user`</td><td>Use Trakt User's Personal 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>`mdb_myanimelist`</td><td>Use MyAnimeList 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>`trakt_user`</td><td>Use Trakt User's Personal 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>`mdb_myanimelist`</td><td>Use MyAnimeList 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><tr><td>`lock`</td><td>Lock Rating Field</td></tr><tr><td>`unlock`</td><td>Unlock Rating Field</td></tr><tr><td>`remove`</td><td>Remove Rating and Lock Field</td></tr><tr><td>`reset`</td><td>Remove Rating and Unlock Field</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_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><tr><td>`lock`</td><td>Lock Rating Field</td></tr><tr><td>`unlock`</td><td>Unlock Rating Field</td></tr><tr><td>`remove`</td><td>Remove Rating and Lock Field</td></tr><tr><td>`reset`</td><td>Remove Rating and Unlock Field</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_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_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> | | `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` | | `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` |

@ -33,13 +33,32 @@ from retrying import retry
logger = util.logger logger = util.logger
sync_modes = {"append": "Only Add Items to the Collection or Playlist", "sync": "Add & Remove Items from the Collection or Playlist"} 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", "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_original_title_options = {"anidb": "Use AniDB Main Title", "anidb_official": "Use AniDB Official Title based on the language attribute in the config file"}
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"} 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_genre_options = {
"lock": "Unlock Genre", "unlock": "Unlock Genre", "remove": "Remove and Lock Genre", "reset": "Remove and Unlock Genre",
"tmdb": "Use TMDb Genres", "imdb": "Use IMDb Genres", "omdb": "Use IMDb Genres through OMDb", "tvdb": "Use TVDb Genres", "anidb": "Use AniDB Tags"
}
mass_content_options = {
"lock": "Unlock Rating", "unlock": "Unlock Rating", "remove": "Remove and Lock Rating", "reset": "Remove and Unlock Rating",
"omdb": "Use IMDb Rating through OMDb", "mdb": "Use MdbList Rating", "mdb_commonsense": "Use Commonsense Rating through MDbList"
}
mass_original_title_options = {
"lock": "Unlock Original Title", "unlock": "Unlock Original Title", "remove": "Remove and Lock Original Title", "reset": "Remove and Unlock Original Title",
"anidb": "Use AniDB Main Title", "anidb_official": "Use AniDB Official Title based on the language attribute in the config file"
}
mass_available_options = {
"lock": "Unlock Originally Available", "unlock": "Unlock Originally Available", "remove": "Remove and Lock Originally Available", "reset": "Remove and Unlock Originally Available",
"tmdb": "Use TMDb Release", "omdb": "Use IMDb Release through OMDb", "mdb": "Use MdbList Release", "tvdb": "Use TVDb Release", "anidb": "Use AniDB Release"
}
mass_episode_rating_options = {
"lock": "Unlock Rating", "unlock": "Unlock Rating", "remove": "Remove and Lock Rating", "reset": "Remove and Unlock Rating",
"tmdb": "Use TMDb Rating", "imdb": "Use IMDb Rating"
}
mass_rating_options = { mass_rating_options = {
"lock": "Lock Rating",
"unlock": "Unlock Rating",
"remove": "Remove and Lock Rating",
"reset": "Remove and Unlock Rating",
"tmdb": "Use TMDb Rating", "tmdb": "Use TMDb Rating",
"imdb": "Use IMDb Rating", "imdb": "Use IMDb Rating",
"trakt_user": "Use Trakt User Rating", "trakt_user": "Use Trakt User Rating",

@ -222,7 +222,7 @@ class Library(ABC):
pass pass
@abstractmethod @abstractmethod
def edit_tags(self, attr, obj, add_tags=None, remove_tags=None, sync_tags=None, do_print=True): def edit_tags(self, attr, obj, add_tags=None, remove_tags=None, sync_tags=None, do_print=True, locked=True, is_locked=None):
pass pass
@abstractmethod @abstractmethod

@ -93,6 +93,8 @@ class Operations:
if self.library.assets_for_all and self.library.asset_directory: if self.library.assets_for_all and self.library.asset_directory:
self.library.find_and_upload_assets(item, current_labels) self.library.find_and_upload_assets(item, current_labels)
locked_fields = [f.name for f in item.fields if f.locked]
tmdb_id, tvdb_id, imdb_id = self.library.get_ids(item) tmdb_id, tvdb_id, imdb_id = self.library.get_ids(item)
item.batchEdits() item.batchEdits()
@ -201,7 +203,16 @@ class Operations:
if mdb_item is None: if mdb_item is None:
logger.warning(f"No TMDb ID, TVDb ID, or IMDb ID for Guid: {item.guid}") logger.warning(f"No TMDb ID, TVDb ID, or IMDb ID for Guid: {item.guid}")
def get_rating(attribute): def update_rating(attribute, item_attr, display):
current = getattr(item, item_attr)
if attribute in ["remove", "reset"] and current:
item.editField(item_attr, None, locked=attribute == "remove")
return f"\n{display} | None"
elif attribute in ["unlock", "reset"] and item_attr in locked_fields:
self.library.edit_query(item, {f"{item_attr}.locked": 0})
elif attribute in ["lock", "remove"] and item_attr not in locked_fields:
self.library.edit_query(item, {f"{item_attr}.locked": 1})
elif attribute not in ["lock", "unlock", "remove", "reset"]:
if tmdb_item and attribute == "tmdb": if tmdb_item and attribute == "tmdb":
found_rating = tmdb_item.vote_average found_rating = tmdb_item.vote_average
elif imdb_id and attribute == "imdb": elif imdb_id and attribute == "imdb":
@ -240,14 +251,27 @@ class Operations:
found_rating = anidb_item.score found_rating = anidb_item.score
else: else:
found_rating = None found_rating = None
if found_rating is None: if found_rating is None:
raise Failed logger.info(f"No {display} Found")
return found_rating elif str(current) != str(found_rating):
item.editField(item_attr, found_rating)
return f"\n{display} | {found_rating}"
return ""
if self.library.mass_audience_rating_update:
batch_display += update_rating(self.library.mass_audience_rating_update, "audienceRating", "Audience Rating")
if self.library.mass_critic_rating_update:
batch_display += update_rating(self.library.mass_critic_rating_update, "rating", "Critic Rating")
if self.library.mass_user_rating_update:
batch_display += update_rating(self.library.mass_user_rating_update, "userRating", "User Rating")
if self.library.mass_genre_update or self.library.genre_mapper: if self.library.mass_genre_update or self.library.genre_mapper:
try: try:
new_genres = [] new_genres = []
if self.library.mass_genre_update: if self.library.mass_genre_update and self.library.mass_genre_update not in ["lock", "unlock", "remove", "reset"]:
if tmdb_item and self.library.mass_genre_update == "tmdb": if tmdb_item and self.library.mass_genre_update == "tmdb":
new_genres = tmdb_item.genres new_genres = tmdb_item.genres
elif imdb_id and self.library.mass_genre_update == "imdb" and imdb_id in self.config.IMDb.genres: elif imdb_id and self.library.mass_genre_update == "imdb" and imdb_id in self.config.IMDb.genres:
@ -263,7 +287,7 @@ class Operations:
if not new_genres: if not new_genres:
logger.info(f"No Genres Found") logger.info(f"No Genres Found")
if self.library.genre_mapper: if self.library.genre_mapper:
if not new_genres: if not new_genres and self.library.mass_genre_update not in ["remove", "reset"]:
new_genres = [g.tag for g in item.genres] new_genres = [g.tag for g in item.genres]
mapped_genres = [] mapped_genres = []
for genre in new_genres: for genre in new_genres:
@ -273,43 +297,18 @@ class Operations:
else: else:
mapped_genres.append(genre) mapped_genres.append(genre)
new_genres = mapped_genres new_genres = mapped_genres
temp_display = self.library.edit_tags('genre', item, sync_tags=new_genres, do_print=False) temp_display = self.library.edit_tags("genre", item, sync_tags=new_genres, do_print=False,
locked=False if self.library.mass_genre_update in ["unlock", "reset"] else True,
is_locked="genre" in locked_fields)
if temp_display: if temp_display:
batch_display += f"\n{temp_display}" batch_display += f"\n{temp_display}"
except Failed: except Failed:
pass pass
if self.library.mass_audience_rating_update:
try:
new_rating = get_rating(self.library.mass_audience_rating_update)
if str(item.audienceRating) != str(new_rating):
item.editField("audienceRating", new_rating)
batch_display += f"\nAudience Rating | {new_rating}"
except Failed:
logger.info(f"No Audience Rating Found")
if self.library.mass_critic_rating_update:
try:
new_rating = get_rating(self.library.mass_critic_rating_update)
if str(item.rating) != str(new_rating):
item.editField("rating", new_rating)
batch_display += f"\nCritic Rating | {new_rating}"
except Failed:
logger.info(f"No Critic Rating Found")
if self.library.mass_user_rating_update:
try:
new_rating = get_rating(self.library.mass_user_rating_update)
if str(item.userRating) != str(new_rating):
item.editField("userRating", new_rating)
batch_display += f"\nUser Rating | {new_rating}"
except Failed:
logger.info(f"No User Rating Found")
if self.library.mass_content_rating_update or self.library.content_rating_mapper: if self.library.mass_content_rating_update or self.library.content_rating_mapper:
try: try:
new_rating = None new_rating = None
if self.library.mass_content_rating_update: if self.library.mass_content_rating_update and self.library.mass_genre_update not in ["lock", "unlock", "remove", "reset"]:
if omdb_item and self.library.mass_content_rating_update == "omdb": if omdb_item and self.library.mass_content_rating_update == "omdb":
new_rating = omdb_item.content_rating new_rating = omdb_item.content_rating
elif mdb_item and self.library.mass_content_rating_update == "mdb": elif mdb_item and self.library.mass_content_rating_update == "mdb":
@ -319,19 +318,35 @@ class Operations:
else: else:
raise Failed raise Failed
if self.library.content_rating_mapper: if self.library.content_rating_mapper:
if new_rating is None: if new_rating is None and self.library.mass_genre_update not in ["remove", "reset"]:
new_rating = item.contentRating new_rating = item.contentRating
if new_rating in self.library.content_rating_mapper: if new_rating in self.library.content_rating_mapper:
new_rating = self.library.content_rating_mapper[new_rating] new_rating = self.library.content_rating_mapper[new_rating]
if not new_rating:
if self.library.mass_content_rating_update in ["remove", "reset"] and item.contentRating:
item.editField("contentRating", None, locked=self.library.mass_content_rating_update == "remove")
batch_display += f"\nContent Rating | None"
elif not new_rating and self.library.mass_genre_update not in ["lock", "unlock", "remove", "reset"]:
logger.info(f"No Content Rating Found") logger.info(f"No Content Rating Found")
elif str(item.contentRating) != str(new_rating): elif str(item.contentRating) != str(new_rating):
item.editContentRating(new_rating) item.editContentRating(new_rating)
batch_display += f"\nContent Rating | {new_rating}" batch_display += f"\nContent Rating | {new_rating}"
elif self.library.mass_content_rating_update in ["unlock", "reset"] and "contentRating" in locked_fields:
self.library.edit_query(item, {"contentRating.locked": 0})
elif self.library.mass_content_rating_update in ["lock", "remove"] and "contentRating" not in locked_fields:
self.library.edit_query(item, {"contentRating.locked": 1})
except Failed: except Failed:
pass pass
if self.library.mass_original_title_update: if self.library.mass_original_title_update:
if self.library.mass_original_title_update in ["remove", "reset"] and item.originalTitle:
item.editField("originalTitle", None, locked=self.library.mass_original_title_update == "remove")
batch_display += f"\nOriginal Title | None"
elif self.library.mass_original_title_update in ["unlock", "reset"] and "originalTitle" in locked_fields:
self.library.edit_query(item, {"originalTitle.locked": 0})
elif self.library.mass_original_title_update in ["lock", "remove"] and "originalTitle" not in locked_fields:
self.library.edit_query(item, {"originalTitle.locked": 1})
elif self.library.mass_original_title_update not in ["lock", "unlock", "remove", "reset"]:
try: try:
if anidb_item and self.library.mass_original_title_update == "anidb": if anidb_item and self.library.mass_original_title_update == "anidb":
new_original_title = anidb_item.main_title new_original_title = anidb_item.main_title
@ -348,6 +363,14 @@ class Operations:
pass pass
if self.library.mass_originally_available_update: if self.library.mass_originally_available_update:
if self.library.mass_originally_available_update in ["remove", "reset"] and item.originallyAvailableAt:
item.editField("originallyAvailableAt", None, locked=self.library.mass_originally_available_update == "remove")
batch_display += f"\nOriginally Available Date | None"
elif self.library.mass_originally_available_update in ["unlock", "reset"] and "originallyAvailableAt" in locked_fields:
self.library.edit_query(item, {"originallyAvailableAt.locked": 0})
elif self.library.mass_originally_available_update in ["lock", "remove"] and "originallyAvailableAt" not in locked_fields:
self.library.edit_query(item, {"originallyAvailableAt.locked": 1})
elif self.library.mass_originally_available_update not in ["lock", "unlock", "remove", "reset"]:
try: try:
if omdb_item and self.library.mass_originally_available_update == "omdb": if omdb_item and self.library.mass_originally_available_update == "omdb":
new_date = omdb_item.released new_date = omdb_item.released
@ -369,8 +392,8 @@ class Operations:
except Failed: except Failed:
pass pass
item.saveEdits()
if len(batch_display) > 0: if len(batch_display) > 0:
item.saveEdits()
logger.info(f"Batch Edits{batch_display}") logger.info(f"Batch Edits{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] episode_ops = [self.library.mass_episode_audience_rating_update, self.library.mass_episode_critic_rating_update, self.library.mass_episode_user_rating_update]
@ -386,52 +409,45 @@ class Operations:
item_title = self.library.get_item_sort_title(ep, atr="title") item_title = self.library.get_item_sort_title(ep, atr="title")
logger.info("") logger.info("")
logger.info(f"Processing {item_title}") logger.info(f"Processing {item_title}")
def get_episode_rating(attribute): episode_locked_fields = [f.name for f in ep.fields if f.locked]
def update_episode_rating(attribute, item_attr, display):
current = getattr(ep, item_attr)
if attribute in ["remove", "reset"] and current:
ep.editField(item_attr, None, locked=attribute == "remove")
return f"\n{display} | None"
elif attribute in ["unlock", "reset"] and item_attr in episode_locked_fields:
self.library.edit_query(ep, {f"{item_attr}.locked": 0})
elif attribute in ["lock", "remove"] and item_attr not in episode_locked_fields:
self.library.edit_query(ep, {f"{item_attr}.locked": 1})
elif attribute not in ["lock", "unlock", "remove", "reset"]:
found_rating = None
if tmdb_item and attribute == "tmdb": if tmdb_item and attribute == "tmdb":
try: try:
return self.config.TMDb.get_episode(tmdb_item.tmdb_id, ep.seasonNumber, ep.episodeNumber).vote_average found_rating = self.config.TMDb.get_episode(tmdb_item.tmdb_id, ep.seasonNumber, ep.episodeNumber).vote_average
except Failed as er: except Failed as er:
logger.error(er) logger.error(er)
elif imdb_id and attribute == "imdb": elif imdb_id and attribute == "imdb":
return self.config.IMDb.get_episode_rating(imdb_id, ep.seasonNumber, ep.episodeNumber) found_rating = self.config.IMDb.get_episode_rating(imdb_id, ep.seasonNumber, ep.episodeNumber)
else:
raise Failed if found_rating is None:
logger.info(f"No {display} Found")
elif str(current) != str(found_rating):
ep.editField(item_attr, found_rating)
return f"\n{display} | {found_rating}"
return ""
if self.library.mass_episode_audience_rating_update: if self.library.mass_episode_audience_rating_update:
try: batch_display += update_episode_rating(self.library.mass_episode_audience_rating_update, "audienceRating", "Audience Rating")
new_rating = get_episode_rating(self.library.mass_episode_audience_rating_update)
if not new_rating:
logger.info(f"No Audience Rating Found")
elif str(ep.audienceRating) != str(new_rating):
ep.editField("audienceRating", new_rating)
batch_display += f"\nAudience Rating | {new_rating}"
except Failed:
pass
if self.library.mass_episode_critic_rating_update: if self.library.mass_episode_critic_rating_update:
try: batch_display += update_episode_rating(self.library.mass_episode_critic_rating_update, "rating", "Critic Rating")
new_rating = get_episode_rating(self.library.mass_episode_critic_rating_update)
if not new_rating:
logger.info(f"No Critic Rating Found")
elif str(ep.rating) != str(new_rating):
ep.editField("rating", new_rating)
batch_display += f"\nCritic Rating | {new_rating}"
except Failed:
pass
if self.library.mass_episode_user_rating_update: if self.library.mass_episode_user_rating_update:
try: batch_display += update_episode_rating(self.library.mass_episode_user_rating_update, "userRating", "User Rating")
new_rating = get_episode_rating(self.library.mass_episode_user_rating_update)
if not new_rating:
logger.info(f"No User Rating Found")
elif str(ep.userRating) != str(new_rating):
ep.editField("userRating", new_rating)
batch_display += f"\nUser Rating | {new_rating}"
except Failed:
pass
ep.saveEdits()
if len(batch_display) > 0: if len(batch_display) > 0:
ep.saveEdits()
logger.info(f"Batch Edits:{batch_display}") logger.info(f"Batch Edits:{batch_display}")
if self.library.Radarr and self.library.radarr_add_all_existing: if self.library.Radarr and self.library.radarr_add_all_existing:

@ -548,6 +548,10 @@ class Plex(Library):
def query_data(self, method, data): def query_data(self, method, data):
return method(data) return method(data)
@retry(stop_max_attempt_number=6, wait_fixed=10000, retry_on_exception=util.retry_if_not_plex)
def tag_edit(self, item, attribute, data, locked=True, remove=False):
return item.editTags(attribute, data, locked=locked, remove=remove)
@retry(stop_max_attempt_number=6, wait_fixed=10000, retry_on_exception=util.retry_if_not_failed) @retry(stop_max_attempt_number=6, wait_fixed=10000, retry_on_exception=util.retry_if_not_failed)
def query_collection(self, item, collection, locked=True, add=True): def query_collection(self, item, collection, locked=True, add=True):
if add: if add:
@ -975,12 +979,12 @@ class Plex(Library):
logger.stacktrace() logger.stacktrace()
return False return False
def edit_tags(self, attr, obj, add_tags=None, remove_tags=None, sync_tags=None, do_print=True): def edit_tags(self, attr, obj, add_tags=None, remove_tags=None, sync_tags=None, do_print=True, locked=True, is_locked=None):
display = "" display = ""
final = "" final = ""
key = attribute_translation[attr] if attr in attribute_translation else attr key = attribute_translation[attr] if attr in attribute_translation else attr
actual = "similar" if attr == "similar_artist" else attr
attr_display = attr.replace("_", " ").title() attr_display = attr.replace("_", " ").title()
attr_call = attr_display.replace(" ", "")
if add_tags or remove_tags or sync_tags is not None: if add_tags or remove_tags or sync_tags is not None:
_add_tags = add_tags if add_tags else [] _add_tags = add_tags if add_tags else []
_remove_tags = remove_tags if remove_tags else [] _remove_tags = remove_tags if remove_tags else []
@ -993,13 +997,15 @@ class Plex(Library):
_add = [t for t in _add_tags + _sync_tags if t not in _item_tags] _add = [t for t in _add_tags + _sync_tags if t not in _item_tags]
_remove = [t for t in _item_tags if (sync_tags is not None and t not in _sync_tags) or t in _remove_tags] _remove = [t for t in _item_tags if (sync_tags is not None and t not in _sync_tags) or t in _remove_tags]
if _add: if _add:
self.query_data(getattr(obj, f"add{attr_call}"), _add) self.tag_edit(obj, actual, _add, locked=locked)
display += f"+{', +'.join(_add)}" display += f"+{', +'.join(_add)}"
if _remove: if _remove:
self.query_data(getattr(obj, f"remove{attr_call}"), _remove) self.tag_edit(obj, actual, _remove, locked=locked, remove=True)
if display: if display:
display += ", " display += ", "
display += f"-{', -'.join(_remove)}" display += f"-{', -'.join(_remove)}"
if is_locked is not None and not display and is_locked != locked:
self.edit_query(obj, {f"{actual}.locked": 1 if locked else 0})
final = f"{obj.title[:25]:<25} | {attr_display} | {display}" if display else display final = f"{obj.title[:25]:<25} | {attr_display} | {display}" if display else display
if do_print and final: if do_print and final:
logger.info(final) logger.info(final)

Loading…
Cancel
Save