diff --git a/VERSION b/VERSION
index e59b77f0..af45e8b6 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.16.2-develop40
+1.16.2-develop41
diff --git a/docs/config/operations.md b/docs/config/operations.md
index 2fff48d3..8fed22ec 100644
--- a/docs/config/operations.md
+++ b/docs/config/operations.md
@@ -28,7 +28,8 @@ The available attributes for the operations attribute are as follows
| `mass_imdb_parental_labels` | Updates every item's labels in the library to match the IMDb Parental Guide
**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
**Values:** `true` or `false` |
| `mass_collection_mode` | Updates every Collection in your library to the specified Collection Mode
**Values:** `default`: Library default
`hide`: Hide Collection
`hide_items`: Hide Items in this Collection
`show_items`: Show this Collection and its Items
`default` | Library default |
`hide` | Hide Collection |
`hide_items` | Hide Items in this Collection |
`show_items` | Show this Collection and its Items |
|
-| `update_blank_track_titles ` | Search though every track in a music library and replace any blank track titles with the tracks sort title
**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
**Values:** `true` or `false` |
+| `remove_title_parentheses` | Search through every title and remove all ending parentheses in an items title if the title isn not locked. |
| `split_duplicates` | Splits all duplicate movies/shows found in this library
**Values:** `true` or `false` |
| `radarr_add_all` | Adds every item in the library to Radarr. The existing paths in plex will be used as the root folder of each item, if the paths in Plex are not the same as your Radarr paths you can use the `plex_path` and `radarr_path` [Radarr](radarr) details to convert the paths.
**Values:** `true` or `false` |
| `radarr_remove_by_tag` | Removes every item from Radarr with the Tags given
**Values:** List or comma separated string of tags |
diff --git a/modules/config.py b/modules/config.py
index 9b05d7c8..969ed480 100644
--- a/modules/config.py
+++ b/modules/config.py
@@ -211,7 +211,7 @@ class ConfigFile:
if data is None or attribute not in data:
message = f"{text} not found"
if parent and save is True:
- loaded_config, _, _ = yaml.util.load_yaml_guess_indent(open(self.config_path))
+ loaded_config, _, _ = yaml.util.load_yaml_guess_indent(open(self.config_path, encoding="utf-8"))
endline = f"\n{parent} sub-attribute {attribute} added to config"
if parent not in loaded_config or not loaded_config[parent]: loaded_config[parent] = {attribute: default}
elif attribute not in loaded_config[parent]: loaded_config[parent][attribute] = default
@@ -618,7 +618,8 @@ class ConfigFile:
"update_blank_track_titles": None,
"mass_content_rating_update": None,
"mass_originally_available_update": None,
- "mass_imdb_parental_labels": None
+ "mass_imdb_parental_labels": None,
+ "remove_title_parentheses": None
}
display_name = f"{params['name']} ({params['mapping_name']})" if lib and "library_name" in lib and lib["library_name"] else params["mapping_name"]
@@ -705,6 +706,8 @@ class ConfigFile:
params["sonarr_remove_by_tag"] = check_for_attribute(lib["operations"], "sonarr_remove_by_tag", var_type="comma_list", default=False, save=False)
if "update_blank_track_titles" in lib["operations"]:
params["update_blank_track_titles"] = check_for_attribute(lib["operations"], "update_blank_track_titles", var_type="bool", default=False, save=False)
+ if "remove_title_parentheses" in lib["operations"]:
+ params["remove_title_parentheses"] = check_for_attribute(lib["operations"], "remove_title_parentheses", var_type="bool", default=False, save=False)
if "mass_collection_mode" in lib["operations"]:
try:
params["mass_collection_mode"] = util.check_collection_mode(lib["operations"]["mass_collection_mode"])
diff --git a/modules/library.py b/modules/library.py
index 1e2bbb2e..3596512e 100644
--- a/modules/library.py
+++ b/modules/library.py
@@ -79,6 +79,7 @@ class Library(ABC):
self.sonarr_add_all_existing = params["sonarr_add_all_existing"]
self.sonarr_remove_by_tag = params["sonarr_remove_by_tag"]
self.update_blank_track_titles = params["update_blank_track_titles"]
+ self.remove_title_parentheses = params["remove_title_parentheses"]
self.mass_collection_mode = params["mass_collection_mode"]
self.metadata_backup = params["metadata_backup"]
self.tmdb_collections = params["tmdb_collections"]
@@ -98,8 +99,8 @@ class Library(ABC):
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.tmdb_collections 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.genre_collections or self.show_unmanaged or self.metadata_backup or self.update_blank_track_titles else False
+ or self.radarr_remove_by_tag or self.sonarr_remove_by_tag or self.mass_collection_mode or self.genre_collections \
+ or self.show_unmanaged or self.metadata_backup or self.update_blank_track_titles or self.remove_title_parentheses 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]
if self.asset_directory:
diff --git a/modules/mal.py b/modules/mal.py
index b2e01e86..bffb3443 100644
--- a/modules/mal.py
+++ b/modules/mal.py
@@ -111,7 +111,7 @@ class MyAnimeList:
if authorization is not None and "access_token" in authorization and authorization["access_token"] and self._check(authorization):
if self.authorization != authorization and not self.config.read_only:
yaml.YAML().allow_duplicate_keys = True
- config, ind, bsi = yaml.util.load_yaml_guess_indent(open(self.config_path))
+ config, ind, bsi = yaml.util.load_yaml_guess_indent(open(self.config_path, encoding="utf-8"))
config["mal"]["authorization"] = {
"access_token": authorization["access_token"],
"token_type": authorization["token_type"],
diff --git a/modules/trakt.py b/modules/trakt.py
index b0c5218d..604a63fc 100644
--- a/modules/trakt.py
+++ b/modules/trakt.py
@@ -159,7 +159,7 @@ class Trakt:
if authorization and self._check(authorization):
if self.authorization != authorization and not self.config.read_only:
yaml.YAML().allow_duplicate_keys = True
- config, ind, bsi = yaml.util.load_yaml_guess_indent(open(self.config_path))
+ config, ind, bsi = yaml.util.load_yaml_guess_indent(open(self.config_path, encoding="utf-8"))
config["trakt"]["pin"] = None
config["trakt"]["authorization"] = {
"access_token": authorization["access_token"],
diff --git a/plex_meta_manager.py b/plex_meta_manager.py
index ffc4c234..fd40eef7 100644
--- a/plex_meta_manager.py
+++ b/plex_meta_manager.py
@@ -1,4 +1,4 @@
-import argparse, os, sys, time, traceback
+import argparse, os, re, sys, time, traceback
from datetime import datetime
try:
@@ -472,6 +472,12 @@ def library_operations(config, library):
item.batchEdits()
batch_display = "Batch Edits"
+ if library.remove_title_parentheses:
+ if not any([f.name == "title" and f.locked for f in item.fields]) and item.title.endswith(")"):
+ new_title = re.sub(" \(\w+\)$", "", item.title)
+ item.editTitle(new_title)
+ batch_display += f"\n{item.title[:25]:<25} | Title | {new_title}"
+
if library.mass_trakt_rating_update:
try:
if library.is_movie and tmdb_id in trakt_ratings:
@@ -810,7 +816,7 @@ def library_operations(config, library):
meta = None
if os.path.exists(library.metadata_backup["path"]):
try:
- meta, _, _ = yaml.util.load_yaml_guess_indent(open(library.metadata_backup["path"]))
+ meta, _, _ = yaml.util.load_yaml_guess_indent(open(library.metadata_backup["path"], encoding="utf-8"))
except yaml.scanner.ScannerError as e:
logger.error(f"YAML Error: {util.tab_new_lines(e)}")
filename, file_extension = os.path.splitext(library.metadata_backup["path"])