Update handling of unsupported translations (#1467)

* Handle unsupported fonts

* Update archinstall/locales/README.md

Co-authored-by: codefiles <11915375+codefiles@users.noreply.github.com>

Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
Co-authored-by: codefiles <11915375+codefiles@users.noreply.github.com>
This commit is contained in:
Daniel Girtler 2022-09-12 05:23:21 +10:00 committed by GitHub
parent c373607f8c
commit 94df913e0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 85 additions and 27 deletions

View File

@ -1,7 +1,7 @@
from dataclasses import dataclass
from enum import Enum, auto
from os import system
from typing import Dict, List, Union, Any, TYPE_CHECKING, Optional
from typing import Dict, List, Union, Any, TYPE_CHECKING, Optional, Callable
from archinstall.lib.menu.simple_menu import TerminalMenu
@ -52,9 +52,9 @@ class Menu(TerminalMenu):
sort :bool = True,
preset_values :Union[str, List[str]] = None,
cursor_index : Optional[int] = None,
preview_command=None,
preview_size=0.75,
preview_title='Info',
preview_command: Optional[Callable] = None,
preview_size: float = 0.75,
preview_title: str = 'Info',
header :Union[List[str],str] = None,
raise_error_on_interrupt :bool = False,
raise_error_warning_msg :str = '',
@ -152,6 +152,7 @@ class Menu(TerminalMenu):
self._multi = multi
self._raise_error_on_interrupt = raise_error_on_interrupt
self._raise_error_warning_msg = raise_error_warning_msg
self._preview_command = preview_command
menu_title = f'\n{title}\n\n'
@ -198,7 +199,7 @@ class Menu(TerminalMenu):
# show_search_hint=True,
preselected_entries=self.preset_values,
cursor_index=self.cursor_index,
preview_command=preview_command,
preview_command=lambda x: self._preview_wrapper(preview_command, x),
preview_size=preview_size,
preview_title=preview_title,
raise_error_on_interrupt=self._raise_error_on_interrupt,
@ -235,6 +236,13 @@ class Menu(TerminalMenu):
else:
return MenuSelection(type_=MenuSelectionType.Esc)
def _preview_wrapper(self, preview_command: Optional[Callable], current_selection: str) -> Optional[str]:
if preview_command:
if self._default_option is not None and f'{self._default_option} {self._default_str}' == current_selection:
current_selection = self._default_option
return preview_command(current_selection)
return None
def run(self) -> MenuSelection:
ret = self._show()

View File

@ -17,41 +17,55 @@ if TYPE_CHECKING:
@dataclass
class Language:
abbr: str
lang: str
name_en: str
translation: gettext.NullTranslations
translation_percent: int
translated_lang: Optional[str]
external_dep: Optional[str]
@property
def display_name(self) -> str:
if self.translated_lang:
if not self.external_dep and self.translated_lang:
name = self.translated_lang
else:
name = self.lang
name = self.name_en
return f'{name} ({self.translation_percent}%)'
def is_match(self, lang_or_translated_lang: str) -> bool:
if self.lang == lang_or_translated_lang:
if self.name_en == lang_or_translated_lang:
return True
elif self.translated_lang == lang_or_translated_lang:
return True
return False
def json(self) -> str:
return self.lang
return self.name_en
class TranslationHandler:
_base_pot = 'base.pot'
_languages = 'languages.json'
def __init__(self):
# to display latin, greek, cyrillic characters
self._set_font('LatGrkCyr-8x16')
self._base_pot = 'base.pot'
self._languages = 'languages.json'
# check if a custom font was provided, otherwise we'll
# use one that can display latin, greek, cyrillic characters
if self.is_custom_font_enabled():
self._set_font(self.custom_font_path().name)
else:
self._set_font('LatGrkCyr-8x16')
self._total_messages = self._get_total_active_messages()
self._translated_languages = self._get_translations()
@classmethod
def custom_font_path(cls) -> Path:
return Path('/usr/share/kbd/consolefonts/archinstall_font.psfu.gz')
@classmethod
def is_custom_font_enabled(cls) -> bool:
return cls.custom_font_path().exists()
@property
def translated_languages(self) -> List[Language]:
return self._translated_languages
@ -70,6 +84,7 @@ class TranslationHandler:
abbr = mapping_entry['abbr']
lang = mapping_entry['lang']
translated_lang = mapping_entry.get('translated_lang', None)
external_dep = mapping_entry.get('external_dep', False)
try:
# get a translation for a specific language
@ -84,7 +99,7 @@ class TranslationHandler:
# 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)
language = Language(abbr, lang, translation, percent, translated_lang, external_dep)
languages.append(language)
except FileNotFoundError as error:
raise TranslationError(f"Could not locate language file for '{lang}': {error}")
@ -138,7 +153,7 @@ class TranslationHandler:
Get a language object by it's name, e.g. English
"""
try:
return next(filter(lambda x: x.lang == name, self._translated_languages))
return next(filter(lambda x: x.name_en == name, self._translated_languages))
except Exception:
raise ValueError(f'No language with name found: {name}')
@ -175,8 +190,7 @@ class TranslationHandler:
translation_files = []
for filename in filenames:
if len(filename) == 2 or filename == 'pt_BR':
if filename not in ['ur', 'ta']:
translation_files.append(filename)
translation_files.append(filename)
return translation_files

View File

@ -13,7 +13,7 @@ from ..output import log
from ..profiles import Profile, list_profiles
from ..mirrors import list_mirrors
from ..translationhandler import Language
from ..translationhandler import Language, TranslationHandler
from ..packages.packages import validate_package_list
from ..storage import storage
@ -125,16 +125,34 @@ def select_archinstall_language(languages: List[Language], preset_value: Languag
# name of the language in its own language
options = {lang.display_name: lang for lang in languages}
def dependency_preview(current_selection: str) -> Optional[str]:
current_lang = options[current_selection]
if current_lang.external_dep and not TranslationHandler.is_custom_font_enabled():
font_file = TranslationHandler.custom_font_path()
text = str(_('To be able to use this translation, please install a font manually that supports the language.')) + '\n'
text += str(_('The font should be stored as {}')).format(font_file)
return text
return None
choice = Menu(
_('Archinstall language'),
list(options.keys()),
default_option=preset_value.display_name
default_option=preset_value.display_name,
preview_command=lambda x: dependency_preview(x),
preview_size=0.5
).run()
match choice.type_:
case MenuSelectionType.Esc: return preset_value
case MenuSelectionType.Esc:
return preset_value
case MenuSelectionType.Selection:
return options[choice.value]
language: Language = options[choice.value]
# we have to make sure that the proper AUR dependency is
# present to be able to use this language
if not language.external_dep or TranslationHandler.is_custom_font_enabled():
return language
return select_archinstall_language(languages, preset_value)
def select_profile(preset) -> Optional[Profile]:

View File

@ -1,8 +1,26 @@
# Nationalization
Archinstall supports multiple languages, which depend on translations coming from the community :)
Archinstall supports multiple languages, which depend on translations coming from the community :)
New languages can be added simply by creating a new folder with the proper language abbrevation (see list `languages.json` if unsure).
## Important Note
Before starting a new language translation be aware that a font for that language may not be
available on the ISO. We are using the pre-installed font `/usr/share/kbd/consolefonts/LatGrkCyr-8x16.psfu.gz` in archinstall
which should cover a fair amount of different languages but unfortunately not all of them.
We have the option to provide a custom font in case the above is not covering a specific language, which can
be achieved by installing the font yourself on the ISO and saving it to `/usr/share/kbd/consolefonts/archinstall_font.psfu.gz`.
If this font is present it will be automatically loaded and all languages which are not supported by the default font will
be enabled (but only some might actually work).
Please make sure that the provided language works with the default font on the ISO, and if not mark it in the `languages.json`
that it needs an external dependency
```
{"abbr": "ur", "lang": "Urdu", "translated_lang": "اردو", "external_dep": true},
```
## Adding new languages
New languages can be added simply by creating a new folder with the proper language abbreviation (see list `languages.json` if unsure).
Run the following command to create a new template for a language
```
mkdir -p <abbr>/LC_MESSAGES/ && touch <abbr>/LC_MESSAGES/base.po

View File

@ -155,7 +155,7 @@
{"abbr": "sw", "lang": "Swahili (macrolanguage)"},
{"abbr": "sv", "lang": "Swedish", "translated_lang": "Svenska"},
{"abbr": "ty", "lang": "Tahitian"},
{"abbr": "ta", "lang": "Tamil", "translated_lang": "தமிழ்"},
{"abbr": "ta", "lang": "Tamil", "translated_lang": "தமிழ்", "external_dep": true},
{"abbr": "tt", "lang": "Tatar"},
{"abbr": "te", "lang": "Telugu"},
{"abbr": "tg", "lang": "Tajik"},
@ -170,7 +170,7 @@
{"abbr": "tw", "lang": "Twi"},
{"abbr": "ug", "lang": "Uighur"},
{"abbr": "uk", "lang": "Ukrainian"},
{"abbr": "ur", "lang": "Urdu", "translated_lang": "اردو"},
{"abbr": "ur", "lang": "Urdu", "translated_lang": "اردو", "external_dep": true},
{"abbr": "uz", "lang": "Uzbek"},
{"abbr": "ve", "lang": "Venda"},
{"abbr": "vi", "lang": "Vietnamese"},