From 4dcd5e684f9461145c5b8656b1a91f99ace26b27 Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Tue, 6 Sep 2022 16:31:08 +1000 Subject: Move deserialization into init (#1456) Co-authored-by: Daniel Girtler --- archinstall/lib/menu/global_menu.py | 57 ++++++++++++++--------------------- archinstall/lib/translationhandler.py | 50 +++++++++++++++++++++++++++--- 2 files changed, 68 insertions(+), 39 deletions(-) (limited to 'archinstall/lib') diff --git a/archinstall/lib/menu/global_menu.py b/archinstall/lib/menu/global_menu.py index fc7c90bc..d1bec189 100644 --- a/archinstall/lib/menu/global_menu.py +++ b/archinstall/lib/menu/global_menu.py @@ -3,54 +3,41 @@ from __future__ import annotations from typing import Any, List, Optional, Union, Dict, TYPE_CHECKING import archinstall - -from ..menu import Menu -from ..menu.selection_menu import Selector, GeneralMenu +from ..disk import encrypted_partitions from ..general import SysCommand, secret from ..hardware import has_uefi +from ..menu import Menu +from ..menu.selection_menu import Selector, GeneralMenu from ..models import NetworkConfiguration -from ..storage import storage +from ..models.users import User +from ..output import FormattedOutput from ..profiles import is_desktop_profile, Profile -from ..disk import encrypted_partitions - -from ..user_interaction import get_password, ask_for_a_timezone, save_config -from ..user_interaction import ask_ntp -from ..user_interaction import ask_for_swap +from ..storage import storage +from ..user_interaction import add_number_of_parrallel_downloads +from ..user_interaction import ask_additional_packages_to_install +from ..user_interaction import ask_for_additional_users +from ..user_interaction import ask_for_audio_selection from ..user_interaction import ask_for_bootloader +from ..user_interaction import ask_for_swap from ..user_interaction import ask_hostname -from ..user_interaction import ask_for_audio_selection -from ..user_interaction import ask_additional_packages_to_install +from ..user_interaction import ask_ntp from ..user_interaction import ask_to_configure_network -from ..user_interaction import ask_for_additional_users -from ..user_interaction import select_language -from ..user_interaction import select_mirror_regions -from ..user_interaction import select_locale_lang -from ..user_interaction import select_locale_enc +from ..user_interaction import get_password, ask_for_a_timezone, save_config +from ..user_interaction import select_additional_repositories from ..user_interaction import select_disk_layout -from ..user_interaction import select_kernel from ..user_interaction import select_encrypted_partitions from ..user_interaction import select_harddrives +from ..user_interaction import select_kernel +from ..user_interaction import select_language +from ..user_interaction import select_locale_enc +from ..user_interaction import select_locale_lang +from ..user_interaction import select_mirror_regions from ..user_interaction import select_profile -from ..user_interaction import select_additional_repositories -from ..user_interaction import add_number_of_parrallel_downloads -from ..models.users import User from ..user_interaction.partitioning_conf import current_partition_layout -from ..output import FormattedOutput -from ..translationhandler import Language if TYPE_CHECKING: _: Any -def display_language(global_menu, x): - if type(x) == Language: - return x - elif type(x) == str: - translation_handler = global_menu._translation_handler - for language in translation_handler._get_translations(): - if language.lang == x: - return language - else: - raise ValueError(f"Language entry needs to Language() object or string of full language like 'English'.") class GlobalMenu(GeneralMenu): def __init__(self,data_store): @@ -62,9 +49,9 @@ class GlobalMenu(GeneralMenu): self._menu_options['archinstall-language'] = \ Selector( _('Archinstall language'), - lambda x: self._select_archinstall_language(display_language(self, x)), - display_func=lambda x: display_language(self, x).display_name, - default=self.translation_handler.get_language('en')) + lambda x: self._select_archinstall_language(x), + display_func=lambda x: x.display_name, + default=self.translation_handler.get_language_by_abbr('en')) self._menu_options['keyboard-layout'] = \ Selector( _('Keyboard layout'), diff --git a/archinstall/lib/translationhandler.py b/archinstall/lib/translationhandler.py index 58b7ebd4..d6b3ccb6 100644 --- a/archinstall/lib/translationhandler.py +++ b/archinstall/lib/translationhandler.py @@ -40,6 +40,7 @@ class Language: def json(self) -> str: return self.lang + class TranslationHandler: _base_pot = 'base.pot' _languages = 'languages.json' @@ -48,7 +49,7 @@ class TranslationHandler: # to display cyrillic languages correctly self._set_font('UniCyr_8x16') - self._total_messages = self._get_total_messages() + self._total_messages = self._get_total_active_messages() self._translated_languages = self._get_translations() @property @@ -56,6 +57,9 @@ class TranslationHandler: return self._translated_languages def _get_translations(self) -> List[Language]: + """ + Load all translated languages and return a list of such + """ mappings = self._load_language_mappings() defined_languages = self._defined_languages() @@ -68,13 +72,17 @@ class TranslationHandler: translated_lang = mapping_entry.get('translated_lang', None) try: + # get a translation for a specific language translation = gettext.translation('base', localedir=self._get_locales_dir(), languages=(abbr, lang)) + # calculate the percentage of total translated text to total number of messages if abbr == 'en': percent = 100 else: num_translations = self._get_catalog_size(translation) percent = int((num_translations / self._total_messages) * 100) + # prevent cases where the .pot file is out of date and the percentage is above 100 + percent = min(100, percent) language = Language(abbr, lang, translation, percent, translated_lang) languages.append(language) @@ -84,6 +92,9 @@ class TranslationHandler: return languages def _set_font(self, font: str): + """ + Set the provided font as the new terminal font + """ from archinstall import SysCommand, log try: log(f'Setting font: {font}', level=logging.DEBUG) @@ -92,6 +103,9 @@ class TranslationHandler: log(f'Unable to set font {font}', level=logging.ERROR) def _load_language_mappings(self) -> List[Dict[str, Any]]: + """ + Load the mapping table of all known languages + """ locales_dir = self._get_locales_dir() languages = Path.joinpath(locales_dir, self._languages) @@ -99,34 +113,62 @@ class TranslationHandler: return json.load(fp) def _get_catalog_size(self, translation: gettext.NullTranslations) -> int: - # this is a ery naughty way of retrieving the data but + """ + Get the number of translated messages for a translations + """ + # this is a very naughty way of retrieving the data but # there's no alternative method exposed unfortunately catalog = translation._catalog # type: ignore messages = {k: v for k, v in catalog.items() if k and v} return len(messages) - def _get_total_messages(self) -> int: + def _get_total_active_messages(self) -> int: + """ + Get total messages that could be translated + """ locales = self._get_locales_dir() with open(f'{locales}/{self._base_pot}', 'r') as fp: lines = fp.readlines() msgid_lines = [line for line in lines if 'msgid' in line] + return len(msgid_lines) - 1 # don't count the first line which contains the metadata - def get_language(self, abbr: str) -> Language: + def get_language_by_name(self, name: str) -> Language: + """ + Get a language object by it's name, e.g. English + """ + try: + return next(filter(lambda x: x.lang == name, self._translated_languages)) + except Exception: + raise ValueError(f'No language with name found: {name}') + + def get_language_by_abbr(self, abbr: str) -> Language: + """ + Get a language object by its abbrevation, e.g. en + """ try: return next(filter(lambda x: x.abbr == abbr, self._translated_languages)) except Exception: raise ValueError(f'No language with abbreviation "{abbr}" found') def activate(self, language: Language): + """ + Set the provided language as the current translation + """ language.translation.install() def _get_locales_dir(self) -> Path: + """ + Get the locales directory path + """ cur_path = Path(__file__).parent.parent locales_dir = Path.joinpath(cur_path, 'locales') return locales_dir def _defined_languages(self) -> List[str]: + """ + Get a list of all known languages + """ locales_dir = self._get_locales_dir() filenames = os.listdir(locales_dir) return list(filter(lambda x: len(x) == 2 or x == 'pt_BR', filenames)) -- cgit v1.2.3-54-g00ecf