[61] add translations

pull/1064/head
meisnate12 2 years ago
parent a823b7f0be
commit b4d9fbbb6f

@ -1 +1 @@
1.17.3-develop60 1.17.3-develop61

@ -0,0 +1,9 @@
translations:
bafta_best_name: BAFTA Best Films
bafta_best_summary: British Academy of Film and Television Arts Best Film Winners
bafta_year_name: BAFTA <<key_name>>
bafta_year_summary: <<key>> BAFTA Awards
cannes_best_name: Cannes Golden Palm Winners
cannes_best_summary: Cannes Golden Palm Winners
cannes_year_name: Cannes <<key_name>>
cannes_year_summary: <<key>> Cannes Awards

@ -387,6 +387,9 @@ class ConfigFile:
"test": check_for_attribute(self.data, "test", parent="notifiarr", var_type="bool", default=False, do_print=False, save=False) "test": check_for_attribute(self.data, "test", parent="notifiarr", var_type="bool", default=False, do_print=False, save=False)
}) })
except Failed as e: except Failed as e:
if str(e).endswith("is blank"):
logger.warning(e)
else:
logger.stacktrace() logger.stacktrace()
logger.error(e) logger.error(e)
logger.info(f"Notifiarr Connection {'Failed' if self.NotifiarrFactory is None else 'Successful'}") logger.info(f"Notifiarr Connection {'Failed' if self.NotifiarrFactory is None else 'Successful'}")
@ -438,6 +441,9 @@ class ConfigFile:
"expiration": check_for_attribute(self.data, "cache_expiration", parent="omdb", var_type="int", default=60, int_min=1) "expiration": check_for_attribute(self.data, "cache_expiration", parent="omdb", var_type="int", default=60, int_min=1)
}) })
except Failed as e: except Failed as e:
if str(e).endswith("is blank"):
logger.warning(e)
else:
logger.error(e) logger.error(e)
logger.info(f"OMDb Connection {'Failed' if self.OMDb is None else 'Successful'}") logger.info(f"OMDb Connection {'Failed' if self.OMDb is None else 'Successful'}")
else: else:
@ -455,6 +461,9 @@ class ConfigFile:
) )
logger.info("Mdblist Connection Successful") logger.info("Mdblist Connection Successful")
except Failed as e: except Failed as e:
if str(e).endswith("is blank"):
logger.warning(e)
else:
logger.error(e) logger.error(e)
logger.info("Mdblist Connection Failed") logger.info("Mdblist Connection Failed")
else: else:
@ -474,6 +483,9 @@ class ConfigFile:
"authorization": self.data["trakt"]["authorization"] if "authorization" in self.data["trakt"] else None "authorization": self.data["trakt"]["authorization"] if "authorization" in self.data["trakt"] else None
}) })
except Failed as e: except Failed as e:
if str(e).endswith("is blank"):
logger.warning(e)
else:
logger.error(e) logger.error(e)
logger.info(f"Trakt Connection {'Failed' if self.Trakt is None else 'Successful'}") logger.info(f"Trakt Connection {'Failed' if self.Trakt is None else 'Successful'}")
else: else:
@ -494,6 +506,9 @@ class ConfigFile:
"authorization": self.data["mal"]["authorization"] if "authorization" in self.data["mal"] else None "authorization": self.data["mal"]["authorization"] if "authorization" in self.data["mal"] else None
}) })
except Failed as e: except Failed as e:
if str(e).endswith("is blank"):
logger.warning(e)
else:
logger.error(e) logger.error(e)
logger.info(f"My Anime List Connection {'Failed' if self.MyAnimeList is None else 'Successful'}") logger.info(f"My Anime List Connection {'Failed' if self.MyAnimeList is None else 'Successful'}")
else: else:
@ -510,6 +525,9 @@ class ConfigFile:
check_for_attribute(self.data, "cache_expiration", parent="anidb", var_type="int", default=60, int_min=1) check_for_attribute(self.data, "cache_expiration", parent="anidb", var_type="int", default=60, int_min=1)
) )
except Failed as e: except Failed as e:
if str(e).endswith("is blank"):
logger.warning(e)
else:
logger.error(e) logger.error(e)
logger.info(f"AniDB API Connection {'Successful' if self.AniDB.is_authorized else 'Failed'}") logger.info(f"AniDB API Connection {'Successful' if self.AniDB.is_authorized else 'Failed'}")
try: try:
@ -518,6 +536,9 @@ class ConfigFile:
check_for_attribute(self.data, "password", parent="anidb", throw=True) check_for_attribute(self.data, "password", parent="anidb", throw=True)
) )
except Failed as e: except Failed as e:
if str(e).endswith("is blank"):
logger.warning(e)
else:
logger.error(e) logger.error(e)
logger.info(f"AniDB Login {'Successful' if self.AniDB.username else 'Failed Continuing as Guest'}") logger.info(f"AniDB Login {'Successful' if self.AniDB.username else 'Failed Continuing as Guest'}")

@ -72,6 +72,7 @@ class DataFile:
self.asset_directory = asset_directory self.asset_directory = asset_directory
self.data_type = "" self.data_type = ""
self.templates = {} self.templates = {}
self.translations = {}
def get_file_name(self): def get_file_name(self):
data = f"{self.config.GitHub.configs_url}{self.path}.yml" if self.type == "GIT" else self.path data = f"{self.config.GitHub.configs_url}{self.path}.yml" if self.type == "GIT" else self.path
@ -88,13 +89,18 @@ class DataFile:
else: else:
return data return data
def load_file(self, file_type, file_path, library_type=None, overlay=False): def load_file(self, file_type, file_path, library_type=None, overlay=False, translation=False):
if not file_path.endswith(".yml"): if translation and file_path.endswith(".yml"):
file_path = file_path[:-4]
if not translation and not file_path.endswith(".yml"):
file_path = f"{file_path}.yml" file_path = f"{file_path}.yml"
if file_type in ["URL", "Git", "Repo"]: if file_type in ["URL", "Git", "Repo"]:
if file_type == "Repo" and not self.config.custom_repo: if file_type == "Repo" and not self.config.custom_repo:
raise Failed("Config Error: No custom_repo defined") raise Failed("Config Error: No custom_repo defined")
content_path = file_path if file_type == "URL" else f"{self.config.custom_repo if file_type == 'Repo' else self.config.GitHub.configs_url}{file_path}" content_path = file_path if file_type == "URL" else f"{self.config.custom_repo if file_type == 'Repo' else self.config.GitHub.configs_url}{file_path}"
dir_path = content_path
if translation:
content_path = f"{content_path}/default.yml"
response = self.config.get(content_path) response = self.config.get(content_path)
if response.status_code >= 400: if response.status_code >= 400:
raise Failed(f"URL Error: No file found at {content_path}") raise Failed(f"URL Error: No file found at {content_path}")
@ -117,10 +123,41 @@ class DataFile:
file_path = os.path.abspath(os.path.join(defaults_path, library_type.lower(), file_path)) file_path = os.path.abspath(os.path.join(defaults_path, library_type.lower(), file_path))
elif os.path.exists(os.path.abspath(os.path.join(defaults_path, "both", file_path))): elif os.path.exists(os.path.abspath(os.path.join(defaults_path, "both", file_path))):
file_path = os.path.abspath(os.path.join(defaults_path, "movie", file_path)) file_path = os.path.abspath(os.path.join(defaults_path, "movie", file_path))
if not os.path.exists(os.path.abspath(file_path)): content_path = os.path.abspath(f"{file_path}/default.yml" if translation else file_path)
raise Failed(f"File Error: File does not exist {os.path.abspath(file_path)}") dir_path = file_path
yaml = YAML(path=os.path.abspath(file_path), check_empty=True) if not os.path.exists(content_path):
raise Failed(f"File Error: File does not exist {content_path}")
yaml = YAML(path=content_path, check_empty=True)
if not translation:
return yaml.data return yaml.data
if "translations" not in yaml.data:
raise Failed(f"URL Error: Top Level translations attribute not found in {content_path}")
translations = {k: {"default": v} for k, v in yaml.data["translations"]}
def add_translation(yaml_path, yaml_key, data=None):
yaml_content = YAML(input_data=data, path=yaml_path if data is None else None, check_empty=True)
if "translations" in yaml_content.data:
for ky, vy in yaml_content.data["translations"]:
if ky in translations:
translations[ky][yaml_key] = vy
else:
logger.error(f"Config Error: {ky} must have a default value")
else:
logger.error(f"Config Error: Top Level translations attribute not found in {yaml_path}")
if file_type in ["URL", "Git", "Repo"]:
if "languages" in yaml.data and isinstance(yaml.data["language"], list):
for language in yaml.data["language"]:
response = self.config.get(f"{dir_path}/{language}.yml")
if response.status_code < 400:
add_translation(f"{dir_path}/{language}.yml", language, data=response.content)
else:
logger.error(f"URL Error: Language file not found at {dir_path}/{language}.yml")
else:
for file in os.listdir(dir_path):
if file.endswith(".yml") and file != "default.yml":
add_translation(os.path.abspath(f"{dir_path}/{file}"), file[:-4])
return translations
def apply_template(self, name, mapping_name, data, template_call, extra_variables): def apply_template(self, name, mapping_name, data, template_call, extra_variables):
if not self.templates: if not self.templates:
@ -183,6 +220,10 @@ class DataFile:
else: else:
variables[temp_key] = temp_value variables[temp_key] = temp_value
language = variables["language"] if "language" in variables else "default"
for temp_key, temp_value in self.translations.items():
variables[temp_key] = temp_value[language if language in temp_value else "default"]
for key, value in variables.copy().items(): for key, value in variables.copy().items():
variables[f"{key}_encoded"] = requests.utils.quote(str(value)) variables[f"{key}_encoded"] = requests.utils.quote(str(value))
@ -400,6 +441,17 @@ class DataFile:
if temp_key not in self.templates: if temp_key not in self.templates:
self.templates[temp_key] = (temp_value, temp_vars) self.templates[temp_key] = (temp_value, temp_vars)
def translation_files(self, data):
if data and "translations" in data and data["translations"]:
files = util.load_files(data["translations"], "translations")
if not files:
logger.error("Config Error: No Paths Found for translations")
for file_type, template_file, _, _ in files:
temp_data = self.load_file(file_type, template_file, translation=True)
for k, v in temp_data.items():
if k not in self.translations:
self.translations[k] = v
class MetadataFile(DataFile): class MetadataFile(DataFile):
def __init__(self, config, library, file_type, path, temp_vars, asset_directory): def __init__(self, config, library, file_type, path, temp_vars, asset_directory):
super().__init__(config, file_type, path, temp_vars, asset_directory) super().__init__(config, file_type, path, temp_vars, asset_directory)
@ -419,6 +471,7 @@ class MetadataFile(DataFile):
self.metadata = get_dict("metadata", data, library.metadatas) self.metadata = get_dict("metadata", data, library.metadatas)
self.templates = get_dict("templates", data) self.templates = get_dict("templates", data)
self.external_templates(data) self.external_templates(data)
self.translation_files(data)
self.collections = get_dict("collections", data, library.collections) self.collections = get_dict("collections", data, library.collections)
self.dynamic_collections = get_dict("dynamic_collections", data) self.dynamic_collections = get_dict("dynamic_collections", data)
col_names = library.collections + [c for c in self.collections] col_names = library.collections + [c for c in self.collections]
@ -765,7 +818,9 @@ class MetadataFile(DataFile):
used_keys.extend(key_value) used_keys.extend(key_value)
og_call = {"value": key_value, auto_type: key_value, "key_name": key_name, "key": key} og_call = {"value": key_value, auto_type: key_value, "key_name": key_name, "key": key}
for k, v in template_variables.items(): for k, v in template_variables.items():
if key in v: if not isinstance(v, dict):
og_call[k] = v
elif key in v:
og_call[k] = v[key] og_call[k] = v[key]
template_call = [] template_call = []
for template_name in template_names: for template_name in template_names:
@ -794,7 +849,9 @@ class MetadataFile(DataFile):
auto_type: other_keys, "key_name": other_name, "key": "other" auto_type: other_keys, "key_name": other_name, "key": "other"
} }
for k, v in template_variables.items(): for k, v in template_variables.items():
if "other" in v: if not isinstance(v, dict):
og_other[k] = v
elif "other" in v:
og_other[k] = v["other"] og_other[k] = v["other"]
other_call = [] other_call = []
for other_template in other_templates: for other_template in other_templates:
@ -1330,6 +1387,7 @@ class PlaylistFile(DataFile):
self.playlists = get_dict("playlists", data, self.config.playlist_names) self.playlists = get_dict("playlists", data, self.config.playlist_names)
self.templates = get_dict("templates", data) self.templates = get_dict("templates", data)
self.external_templates(data) self.external_templates(data)
self.translation_files(data)
if not self.playlists: if not self.playlists:
raise Failed("YAML Error: playlists attribute is required") raise Failed("YAML Error: playlists attribute is required")
logger.info(f"Playlist File Loaded Successfully") logger.info(f"Playlist File Loaded Successfully")
@ -1346,6 +1404,7 @@ class OverlayFile(DataFile):
self.templates = get_dict("templates", data) self.templates = get_dict("templates", data)
self.queues = get_dict("queues", data, library.queue_names) self.queues = get_dict("queues", data, library.queue_names)
self.external_templates(data) self.external_templates(data)
self.translation_files(data)
if not self.overlays: if not self.overlays:
raise Failed("YAML Error: overlays attribute is required") raise Failed("YAML Error: overlays attribute is required")
logger.info(f"Overlay File Loaded Successfully") logger.info(f"Overlay File Loaded Successfully")

@ -717,7 +717,7 @@ def parse(error, attribute, data, datatype=None, methods=None, parent=None, defa
new_data[str(dict_data_key)] = dict_data_data new_data[str(dict_data_key)] = dict_data_data
final_dict[dict_key] = new_data final_dict[dict_key] = new_data
else: else:
raise Failed(f"{error} Warning: {display} {dict_key} is not a dictionary") final_dict[dict_key] = dict_data
return final_dict return final_dict
else: else:
raise Failed(f"{error} Error: {display} {value} is not a dictionary") raise Failed(f"{error} Error: {display} {value} is not a dictionary")

@ -660,7 +660,7 @@ def run_collection(config, library, metadata, requested_collections):
logger.info("") logger.info("")
logger.info(f"Plex Server Movie pre-roll video updated to {builder.server_preroll}") logger.info(f"Plex Server Movie pre-roll video updated to {builder.server_preroll}")
if valid and run_item_details and builder.builders and (builder.item_details or builder.custom_sort or builder.sync_to_trakt_list): if valid and run_item_details and (builder.item_details or builder.custom_sort or builder.sync_to_trakt_list):
try: try:
builder.load_collection_items() builder.load_collection_items()
except Failed: except Failed:

Loading…
Cancel
Save