[26] add mass_studio_update

This commit is contained in:
meisnate12 2023-01-25 02:43:25 -05:00
parent 6d81d34be2
commit 8e8a14ab35
8 changed files with 106 additions and 23 deletions

View file

@ -1 +1 @@
1.18.3-develop25 1.18.3-develop26

View file

@ -23,6 +23,7 @@ The available attributes for the operations attribute are as follows
| [Mass Genre Update](#mass-genre-update) | Updates every item's genres in the library to the chosen site's genres. | ✅ | ✅ | ✅ | | [Mass Genre Update](#mass-genre-update) | Updates every item's genres in the library to the chosen site's genres. | ✅ | ✅ | ✅ |
| [Mass Content Rating Update](#mass-content-rating-update) | Updates every item's content rating in the library to the chosen site's content rating. | ✅ | ✅ | ❌ | | [Mass Content Rating Update](#mass-content-rating-update) | Updates every item's content rating in the library to the chosen site's content rating. | ✅ | ✅ | ❌ |
| [Mass Original Title Update](#mass-original-title-update) | Updates every item's original title in the library to the chosen site's original title. | ✅ | ✅ | ❌ | | [Mass Original Title Update](#mass-original-title-update) | Updates every item's original title in the library to the chosen site's original title. | ✅ | ✅ | ❌ |
| [Mass Studio Update](#mass-studio-update) | Updates every item's studio in the library to the chosen site's studio. | ✅ | ✅ | ❌ |
| [Mass Originally Available Update](#mass-originally-available-update) | Updates every item's originally available date in the library to the chosen site's date. | ✅ | ✅ | ❌ | | [Mass Originally Available Update](#mass-originally-available-update) | Updates every item's originally available date in the library to the chosen site's date. | ✅ | ✅ | ❌ |
| [Mass * Rating Update](#mass--rating-update) | Updates every item's audience/critic/user rating in the library to the chosen site's rating. | ✅ | ✅ | ❌ | | [Mass * Rating Update](#mass--rating-update) | Updates every item's audience/critic/user rating in the library to the chosen site's rating. | ✅ | ✅ | ❌ |
| [Mass Episode * Rating Update](#mass-episode--rating-update) | Updates every item's episode's audience/critic/user rating in the library to the chosen site's rating. | ❌ | ✅ | ❌ | | [Mass Episode * Rating Update](#mass-episode--rating-update) | Updates every item's episode's audience/critic/user rating in the library to the chosen site's rating. | ❌ | ✅ | ❌ |
@ -137,6 +138,24 @@ Updates every item's original title in the library to the chosen site's original
| `remove` | Remove Original Title and Lock Field | | `remove` | Remove Original Title and Lock Field |
| `reset` | Remove Original Title and Unlock Field | | `reset` | Remove Original Title and Unlock Field |
## Mass Studio Update
Updates every item's studio in the library to the chosen site's studio.
**Attribute:** `mass_studio_update`
**Values:**
| Value | Description |
|:---------|:---------------------------------------|
| `anidb` | Use AniDB Animation Work for Studio |
| `mal` | Use MyAnimeList Studio for Studio |
| `tmdb` | Use TMDb Studio for Studio |
| `lock` | Lock Original Title Field |
| `unlock` | Unlock Original Title Field |
| `remove` | Remove Original Title and Lock Field |
| `reset` | Remove Original Title and Unlock Field |
## Mass Originally Available Update ## Mass Originally Available Update
Updates every item's originally available date in the library to the chosen site's date. Updates every item's originally available date in the library to the chosen site's date.

View file

@ -22,29 +22,29 @@ class AniDBObj:
self.anidb_id = anidb_id self.anidb_id = anidb_id
self._data = data self._data = data
def _parse(attr, xpath, is_list=False, is_dict=False, is_float=False, is_date=False, fail=False): def _parse(attr, xpath, is_list=False, is_dict=False, is_int=False, is_float=False, is_date=False, fail=False):
try: try:
if isinstance(data, dict): if isinstance(data, dict):
if is_list: if is_list:
return data[attr].split("|") if data[attr] else [] return data[attr].split("|") if data[attr] else []
elif is_dict: elif is_dict:
return json.loads(data[attr]) return json.loads(data[attr])
elif is_float: elif is_int or is_float:
return util.check_num(data[attr], is_int=False) return util.check_num(data[attr], is_int=is_int)
elif is_date: elif is_date:
return datetime.strptime(data[attr], "%Y-%m-%d") return datetime.strptime(data[attr], "%Y-%m-%d")
else: else:
return data[attr] return data[attr]
parse_results = data.xpath(xpath) parse_results = data.xpath(xpath)
if len(parse_results) > 0: if is_dict:
return {ta.get("xml:lang"): ta.text_content() for ta in parse_results}
elif len(parse_results) > 0:
parse_results = [r.strip() for r in parse_results if len(r) > 0] parse_results = [r.strip() for r in parse_results if len(r) > 0]
if parse_results: if parse_results:
if is_list: if is_list:
return parse_results return parse_results
elif is_dict: elif is_int or is_float:
return {ta.get("xml:lang"): ta.text_content() for ta in parse_results} return util.check_num(parse_results[0], is_int=is_int)
elif is_float:
return float(parse_results[0])
elif is_date: elif is_date:
return datetime.strptime(parse_results[0], "%Y-%m-%d") return datetime.strptime(parse_results[0], "%Y-%m-%d")
else: else:
@ -63,11 +63,26 @@ class AniDBObj:
self.main_title = _parse("main_title", "//anime/titles/title[@type='main']/text()", fail=True) self.main_title = _parse("main_title", "//anime/titles/title[@type='main']/text()", fail=True)
self.titles = _parse("titles", "//anime/titles/title[@type='official']", is_dict=True) self.titles = _parse("titles", "//anime/titles/title[@type='official']", is_dict=True)
self.official_title = self.titles[self._anidb.language] if self._anidb.language in self.titles else self.main_title self.official_title = self.titles[self._anidb.language] if self._anidb.language in self.titles else self.main_title
self.studio = _parse("studio", "//anime/creators/name[@type='Animation Work']/text()")
self.rating = _parse("rating", "//anime/ratings/permanent/text()", is_float=True) self.rating = _parse("rating", "//anime/ratings/permanent/text()", is_float=True)
self.average = _parse("average", "//anime/ratings/temporary/text()", is_float=True) self.average = _parse("average", "//anime/ratings/temporary/text()", is_float=True)
self.score = _parse("score", "//anime/ratings/review/text()", is_float=True) self.score = _parse("score", "//anime/ratings/review/text()", is_float=True)
self.released = _parse("released", "//anime/startdate/text()", is_date=True) self.released = _parse("released", "//anime/startdate/text()", is_date=True)
self.tags = _parse("tags", "//anime/tags/tag[@infobox='true']/name/text()", is_list=True) self.tags = _parse("tags", "//anime/tags/tag[@infobox='true']/name/text()", is_list=True)
self.mal_id = _parse("mal_id", "//anime/resources/resource[@type='2']/externalentity/identifier/text()", is_int=True)
self.imdb_id = _parse("imdb_id", "//anime/resources/resource[@type='43']/externalentity/identifier/text()")
if isinstance(data, dict):
self.tmdb_id = _parse("tmdb_id", "", is_int=True)
self.tmdb_type = _parse("tmdb_type", "")
else:
tmdb = _parse("tmdb", "//anime/resources/resource[@type='44']/externalentity/identifier/text()", is_list=True)
self.tmdb_id = None
self.tmdb_type = None
for i in tmdb:
try:
self.tmdb_id = int(i)
except ValueError:
self.tmdb_type = i
class AniDB: class AniDB:

View file

@ -30,6 +30,8 @@ class Cache:
cursor.execute("DROP TABLE IF EXISTS tvdb_data") cursor.execute("DROP TABLE IF EXISTS tvdb_data")
cursor.execute("DROP TABLE IF EXISTS tvdb_data2") cursor.execute("DROP TABLE IF EXISTS tvdb_data2")
cursor.execute("DROP TABLE IF EXISTS overlay_ratings") cursor.execute("DROP TABLE IF EXISTS overlay_ratings")
cursor.execute("DROP TABLE IF EXISTS anidb_data")
cursor.execute("DROP TABLE IF EXISTS mal_data")
cursor.execute( cursor.execute(
"""CREATE TABLE IF NOT EXISTS guids_map ( """CREATE TABLE IF NOT EXISTS guids_map (
key INTEGER PRIMARY KEY, key INTEGER PRIMARY KEY,
@ -121,20 +123,25 @@ class Cache:
expiration_date TEXT)""" expiration_date TEXT)"""
) )
cursor.execute( cursor.execute(
"""CREATE TABLE IF NOT EXISTS anidb_data ( """CREATE TABLE IF NOT EXISTS anidb_data2 (
key INTEGER PRIMARY KEY, key INTEGER PRIMARY KEY,
anidb_id INTEGER UNIQUE, anidb_id INTEGER UNIQUE,
main_title TEXT, main_title TEXT,
titles TEXT, titles TEXT,
studio TEXT,
rating REAL, rating REAL,
average REAL, average REAL,
score REAL, score REAL,
released TEXT, released TEXT,
tags TEXT, tags TEXT,
mal_id INTEGER,
imdb_id TEXT,
tmdb_id INTEGER,
tmdb_type TEXT,
expiration_date TEXT)""" expiration_date TEXT)"""
) )
cursor.execute( cursor.execute(
"""CREATE TABLE IF NOT EXISTS mal_data ( """CREATE TABLE IF NOT EXISTS mal_data2 (
key INTEGER PRIMARY KEY, key INTEGER PRIMARY KEY,
mal_id INTEGER UNIQUE, mal_id INTEGER UNIQUE,
title TEXT, title TEXT,
@ -148,6 +155,7 @@ class Cache:
rank INTEGER, rank INTEGER,
popularity TEXT, popularity TEXT,
genres TEXT, genres TEXT,
studio TEXT,
expiration_date TEXT)""" expiration_date TEXT)"""
) )
cursor.execute( cursor.execute(
@ -518,16 +526,21 @@ class Cache:
with sqlite3.connect(self.cache_path) as connection: with sqlite3.connect(self.cache_path) as connection:
connection.row_factory = sqlite3.Row connection.row_factory = sqlite3.Row
with closing(connection.cursor()) as cursor: with closing(connection.cursor()) as cursor:
cursor.execute("SELECT * FROM anidb_data WHERE anidb_id = ?", (anidb_id,)) cursor.execute("SELECT * FROM anidb_data2 WHERE anidb_id = ?", (anidb_id,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
anidb_dict["main_title"] = row["main_title"] anidb_dict["main_title"] = row["main_title"]
anidb_dict["titles"] = row["titles"] if row["titles"] else None anidb_dict["titles"] = row["titles"] if row["titles"] else None
anidb_dict["studio"] = row["studio"] if row["studio"] else None
anidb_dict["rating"] = row["rating"] if row["rating"] else None anidb_dict["rating"] = row["rating"] if row["rating"] else None
anidb_dict["average"] = row["average"] if row["average"] else None anidb_dict["average"] = row["average"] if row["average"] else None
anidb_dict["score"] = row["score"] if row["score"] else None anidb_dict["score"] = row["score"] if row["score"] else None
anidb_dict["released"] = row["released"] if row["released"] else None anidb_dict["released"] = row["released"] if row["released"] else None
anidb_dict["tags"] = row["tags"] if row["tags"] else None anidb_dict["tags"] = row["tags"] if row["tags"] else None
anidb_dict["mal_id"] = row["mal_id"] if row["mal_id"] else None
anidb_dict["imdb_id"] = row["imdb_id"] if row["imdb_id"] else None
anidb_dict["tmdb_id"] = row["tmdb_id"] if row["tmdb_id"] else None
anidb_dict["tmdb_type"] = row["tmdb_type"] if row["tmdb_type"] else None
datetime_object = datetime.strptime(row["expiration_date"], "%Y-%m-%d") datetime_object = datetime.strptime(row["expiration_date"], "%Y-%m-%d")
time_between_insertion = datetime.now() - datetime_object time_between_insertion = datetime.now() - datetime_object
expired = time_between_insertion.days > expiration expired = time_between_insertion.days > expiration
@ -538,12 +551,13 @@ class Cache:
with sqlite3.connect(self.cache_path) as connection: with sqlite3.connect(self.cache_path) as connection:
connection.row_factory = sqlite3.Row connection.row_factory = sqlite3.Row
with closing(connection.cursor()) as cursor: with closing(connection.cursor()) as cursor:
cursor.execute("INSERT OR IGNORE INTO anidb_data(anidb_id) VALUES(?)", (anidb_id,)) cursor.execute("INSERT OR IGNORE INTO anidb_data2(anidb_id) VALUES(?)", (anidb_id,))
update_sql = "UPDATE anidb_data SET main_title = ?, titles = ?, rating = ?, average = ?, score = ?, " \ update_sql = "UPDATE anidb_data SET main_title = ?, titles = ?, studio = ?, rating = ?, average = ?, score = ?, " \
"released = ?, tags = ?, expiration_date = ? WHERE anidb_id = ?" "released = ?, tags = ?, mal_id = ?, imdb_id = ?, tmdb_id = ?, tmdb_type = ?, expiration_date = ? WHERE anidb_id = ?"
cursor.execute(update_sql, ( cursor.execute(update_sql, (
anidb.main_title, str(anidb.titles), anidb.rating, anidb.average, anidb.score, anidb.main_title, str(anidb.titles), anidb.studio, anidb.rating, anidb.average, anidb.score,
anidb.released.strftime("%Y-%m-%d") if anidb.released else None, "|".join(anidb.tags), anidb.released.strftime("%Y-%m-%d") if anidb.released else None, "|".join(anidb.tags),
anidb_id.mal_id, anidb.imdb_id, anidb.tmdb_id, anidb.tmdb_type,
expiration_date.strftime("%Y-%m-%d"), anidb_id expiration_date.strftime("%Y-%m-%d"), anidb_id
)) ))
@ -553,7 +567,7 @@ class Cache:
with sqlite3.connect(self.cache_path) as connection: with sqlite3.connect(self.cache_path) as connection:
connection.row_factory = sqlite3.Row connection.row_factory = sqlite3.Row
with closing(connection.cursor()) as cursor: with closing(connection.cursor()) as cursor:
cursor.execute("SELECT * FROM mal_data WHERE mal_id = ?", (mal_id,)) cursor.execute("SELECT * FROM mal_data2 WHERE mal_id = ?", (mal_id,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
mal_dict["title"] = row["title"] mal_dict["title"] = row["title"]
@ -567,6 +581,7 @@ class Cache:
mal_dict["rank"] = row["rank"] if row["rank"] else None mal_dict["rank"] = row["rank"] if row["rank"] else None
mal_dict["popularity"] = row["popularity"] if row["popularity"] else None mal_dict["popularity"] = row["popularity"] if row["popularity"] else None
mal_dict["genres"] = row["genres"] if row["genres"] else None mal_dict["genres"] = row["genres"] if row["genres"] else None
mal_dict["studio"] = row["studio"] if row["studio"] else None
datetime_object = datetime.strptime(row["expiration_date"], "%Y-%m-%d") datetime_object = datetime.strptime(row["expiration_date"], "%Y-%m-%d")
time_between_insertion = datetime.now() - datetime_object time_between_insertion = datetime.now() - datetime_object
expired = time_between_insertion.days > expiration expired = time_between_insertion.days > expiration
@ -577,12 +592,12 @@ class Cache:
with sqlite3.connect(self.cache_path) as connection: with sqlite3.connect(self.cache_path) as connection:
connection.row_factory = sqlite3.Row connection.row_factory = sqlite3.Row
with closing(connection.cursor()) as cursor: with closing(connection.cursor()) as cursor:
cursor.execute("INSERT OR IGNORE INTO mal_data(mal_id) VALUES(?)", (mal_id,)) cursor.execute("INSERT OR IGNORE INTO mal_data2(mal_id) VALUES(?)", (mal_id,))
update_sql = "UPDATE mal_data SET title = ?, title_english = ?, title_japanese = ?, status = ?, airing = ?, " \ update_sql = "UPDATE mal_data SET title = ?, title_english = ?, title_japanese = ?, status = ?, airing = ?, " \
"aired = ?, rating = ?, score = ?, rank = ?, popularity = ?, genres = ? , expiration_date = ? WHERE mal_id = ?" "aired = ?, rating = ?, score = ?, rank = ?, popularity = ?, genres = ?, studio = ? expiration_date = ? WHERE mal_id = ?"
cursor.execute(update_sql, ( cursor.execute(update_sql, (
mal.title, mal.title_english, mal.title_japanese, mal.status, mal.airing, mal.aired.strftime("%Y-%m-%d") if mal.aired else None, mal.title, mal.title_english, mal.title_japanese, mal.status, mal.airing, mal.aired.strftime("%Y-%m-%d") if mal.aired else None,
mal.rating, mal.score, mal.rank, mal.popularity, "|".join(mal.genres), expiration_date.strftime("%Y-%m-%d"), mal_id mal.rating, mal.score, mal.rank, mal.popularity, "|".join(mal.genres), mal.studio, expiration_date.strftime("%Y-%m-%d"), mal_id
)) ))
def query_tmdb_movie(self, tmdb_id, expiration): def query_tmdb_movie(self, tmdb_id, expiration):

View file

@ -44,6 +44,10 @@ mass_content_options = {
"omdb": "Use IMDb Rating through OMDb", "mdb": "Use MdbList Rating", "mdb_commonsense": "Use Commonsense Rating through MDbList", "omdb": "Use IMDb Rating through OMDb", "mdb": "Use MdbList Rating", "mdb_commonsense": "Use Commonsense Rating through MDbList",
"mdb_commonsense0": "Use Commonsense Rating with Zero Padding through MDbList", "mal": "Use MyAnimeList Rating" "mdb_commonsense0": "Use Commonsense Rating with Zero Padding through MDbList", "mal": "Use MyAnimeList Rating"
} }
mass_studio_options = {
"lock": "Unlock Rating", "unlock": "Unlock Rating", "remove": "Remove and Lock Rating", "reset": "Remove and Unlock Rating",
"tmdb": "Use TMDb Studio", "anidb": "Use AniDB Animation Work", "mal": "Use MyAnimeList Studio"
}
mass_original_title_options = { mass_original_title_options = {
"lock": "Unlock Original Title", "unlock": "Unlock Original Title", "remove": "Remove and Lock Original Title", "reset": "Remove and Unlock Original Title", "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", "anidb": "Use AniDB Main Title", "anidb_official": "Use AniDB Official Title based on the language attribute in the config file",
@ -90,7 +94,7 @@ reset_overlay_options = {"tmdb": "Reset to TMDb poster", "plex": "Reset to Plex
library_operations = { library_operations = {
"assets_for_all": "bool", "split_duplicates": "bool", "update_blank_track_titles": "bool", "remove_title_parentheses": "bool", "assets_for_all": "bool", "split_duplicates": "bool", "update_blank_track_titles": "bool", "remove_title_parentheses": "bool",
"radarr_add_all_existing": "bool", "radarr_remove_by_tag": "bool", "sonarr_add_all_existing": "bool", "sonarr_remove_by_tag": "bool", "radarr_add_all_existing": "bool", "radarr_remove_by_tag": "bool", "sonarr_add_all_existing": "bool", "sonarr_remove_by_tag": "bool",
"mass_genre_update": mass_genre_options, "mass_content_rating_update": mass_content_options, "mass_genre_update": mass_genre_options, "mass_content_rating_update": mass_content_options, "mass_studio_update": mass_studio_options,
"mass_audience_rating_update": mass_rating_options, "mass_episode_audience_rating_update": mass_episode_rating_options, "mass_audience_rating_update": mass_rating_options, "mass_episode_audience_rating_update": mass_episode_rating_options,
"mass_critic_rating_update": mass_rating_options, "mass_episode_critic_rating_update": mass_episode_rating_options, "mass_critic_rating_update": mass_rating_options, "mass_episode_critic_rating_update": mass_episode_rating_options,
"mass_user_rating_update": mass_rating_options, "mass_episode_user_rating_update": mass_episode_rating_options, "mass_user_rating_update": mass_rating_options, "mass_episode_user_rating_update": mass_episode_rating_options,

View file

@ -74,6 +74,7 @@ class Library(ABC):
self.ignore_imdb_ids = params["ignore_imdb_ids"] self.ignore_imdb_ids = params["ignore_imdb_ids"]
self.assets_for_all = params["assets_for_all"] self.assets_for_all = params["assets_for_all"]
self.delete_collections = params["delete_collections"] self.delete_collections = params["delete_collections"]
self.mass_studio_update = params["mass_studio_update"]
self.mass_genre_update = params["mass_genre_update"] self.mass_genre_update = params["mass_genre_update"]
self.mass_audience_rating_update = params["mass_audience_rating_update"] self.mass_audience_rating_update = params["mass_audience_rating_update"]
self.mass_critic_rating_update = params["mass_critic_rating_update"] self.mass_critic_rating_update = params["mass_critic_rating_update"]
@ -112,7 +113,7 @@ class Library(ABC):
or self.mass_audience_rating_update or self.mass_critic_rating_update or self.mass_user_rating_update \ 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_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_original_title_update\ or self.mass_content_rating_update or self.mass_originally_available_update or self.mass_original_title_update\
or self.mass_imdb_parental_labels or self.genre_mapper or self.content_rating_mapper \ or self.mass_imdb_parental_labels or self.genre_mapper or self.content_rating_mapper or self.mass_studio_update\
or self.radarr_add_all_existing or self.sonarr_add_all_existing or self.mass_poster_update or self.mass_background_update else False or self.radarr_add_all_existing or self.sonarr_add_all_existing or self.mass_poster_update or self.mass_background_update else False
self.library_operation = True if self.items_library_operation or self.delete_collections or self.mass_collection_mode \ self.library_operation = True if self.items_library_operation or self.delete_collections or self.mass_collection_mode \
or self.radarr_remove_by_tag or self.sonarr_remove_by_tag or self.show_unmanaged or self.show_unconfigured \ or self.radarr_remove_by_tag or self.sonarr_remove_by_tag or self.show_unmanaged or self.show_unconfigured \

View file

@ -75,6 +75,7 @@ class MyAnimeListObj:
self.rank = self._data["rank"] self.rank = self._data["rank"]
self.popularity = self._data["popularity"] self.popularity = self._data["popularity"]
self.genres = [] if not self._data["genres"] else self._data["genres"].split("|") if cache else [g["name"] for g in self._data["genres"]] self.genres = [] if not self._data["genres"] else self._data["genres"].split("|") if cache else [g["name"] for g in self._data["genres"]]
self.studio = self._data["studio"] if cache else self._data["studios"][0]["name"] if self._data["studios"] else None
class MyAnimeList: class MyAnimeList:

View file

@ -10,7 +10,7 @@ meta_operations = [
"mass_audience_rating_update", "mass_user_rating_update", "mass_critic_rating_update", "mass_audience_rating_update", "mass_user_rating_update", "mass_critic_rating_update",
"mass_episode_audience_rating_update", "mass_episode_user_rating_update", "mass_episode_critic_rating_update", "mass_episode_audience_rating_update", "mass_episode_user_rating_update", "mass_episode_critic_rating_update",
"mass_genre_update", "mass_content_rating_update", "mass_originally_available_update", "mass_original_title_update", "mass_genre_update", "mass_content_rating_update", "mass_originally_available_update", "mass_original_title_update",
"mass_poster_update", "mass_background_update" "mass_poster_update", "mass_background_update", "mass_studio_update"
] ]
class Operations: class Operations:
@ -425,6 +425,34 @@ class Operations:
except Failed: except Failed:
pass pass
if self.library.mass_studio_update:
if self.library.mass_studio_update in ["remove", "reset"] and item.studio:
item.editField("studio", None, locked=self.library.mass_studio_update == "remove")
batch_display += f"\nStudio | None"
elif self.library.mass_studio_update in ["unlock", "reset"] and "studio" in locked_fields:
self.library.edit_query(item, {"originalTitle.locked": 0})
batch_display += f"\nStudio | Unlocked"
elif self.library.mass_studio_update in ["lock", "remove"] and "studio" not in locked_fields:
self.library.edit_query(item, {"studio.locked": 1})
batch_display += f"\nStudio | Locked"
elif self.library.mass_studio_update not in ["lock", "unlock", "remove", "reset"]:
try:
if anidb_item and self.library.mass_studio_update == "anidb":
new_studio = anidb_item.studio
elif mal_item and self.library.mass_studio_update == "mal":
new_studio = mal_item.studio
elif tmdb_item and self.library.mass_studio_update == "tmdb":
new_studio = tmdb_item.studio
else:
raise Failed
if not new_studio:
logger.info(f"No Studio Found")
elif str(item.studio) != str(new_studio):
item.editStudio(new_studio)
batch_display += f"\nStudio | {new_studio}"
except Failed:
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: 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") item.editField("originallyAvailableAt", None, locked=self.library.mass_originally_available_update == "remove")