From dbb8be4e72283a5624f7a5a92b202e8ba122aa94 Mon Sep 17 00:00:00 2001 From: Dan Bungert Date: Tue, 19 Jul 2022 16:11:33 -0600 Subject: [PATCH] keyboard: suggest language / variant for locale --- subiquity/models/keyboard.py | 57 ++++++++++++++++++++++- subiquity/models/tests/test_keyboard.py | 59 ++++++++++++++++++++++++ subiquity/server/controllers/keyboard.py | 6 +-- 3 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 subiquity/models/tests/test_keyboard.py diff --git a/subiquity/models/keyboard.py b/subiquity/models/keyboard.py index cdfade80..986c6ff9 100644 --- a/subiquity/models/keyboard.py +++ b/subiquity/models/keyboard.py @@ -35,6 +35,40 @@ XKBOPTIONS="{options}" BACKSPACE="guess" """ +layout_for_lang = { + # In the same order as the Welcome screen + # https://salsa.debian.org/installer-team/console-setup/-/blob/master/debian/keyboard-configuration.config + # None values indicate that this lang should use the default setting. + 'ast_ES.UTF-8': KeyboardSetting(layout='es', variant='ast'), + 'id_ID.UTF-8': None, + 'ca_ES.UTF-8': KeyboardSetting(layout='es', variant='cat'), + 'de_DE.UTF-8': KeyboardSetting(layout='de'), + 'en_US.UTF-8': KeyboardSetting(layout='us'), + 'en_GB.UTF-8': KeyboardSetting(layout='gb'), + 'es_ES.UTF-8': KeyboardSetting(layout='es'), + 'fr_FR.UTF-8': KeyboardSetting(layout='fr', variant='latin9'), + 'hr_HR.UTF-8': KeyboardSetting(layout='hr'), + 'lv_LV.UTF-8': KeyboardSetting(layout='lv'), + 'lt_LT.UTF-8': KeyboardSetting(layout='lt'), + 'hu_HU.UTF-8': KeyboardSetting(layout='hu'), + 'nl_NL.UTF-8': KeyboardSetting(layout='us'), + 'nb': KeyboardSetting(layout='no'), + 'bo_IN': KeyboardSetting(layout='us,cn', variant=',tib'), + 'pl_PL.UTF-8': KeyboardSetting(layout='pl'), + 'fi_FI.UTF-8': KeyboardSetting(layout='fi'), + 'sv_SE.UTF-8': KeyboardSetting(layout='se'), + 'kab_DZ.UTF-8': KeyboardSetting(layout='dz', variant='la'), + 'cs_CZ.UTF-8': KeyboardSetting(layout='cz'), + 'el_GR.UTF-8': KeyboardSetting(layout='us,gr'), + 'be_BY.UTF-8': KeyboardSetting(layout='us,by'), + 'ru_RU.UTF-8': KeyboardSetting(layout='us,ru'), + 'sr_RS': KeyboardSetting(layout='rs', variant='latin'), + 'uk_UA.UTF-8': KeyboardSetting(layout='us,ua'), + 'he_IL.UTF-8': KeyboardSetting(layout='us,il'), + 'oc': None, + 'zh_CN.UTF-8': KeyboardSetting(layout='cn'), +} + def from_config_file(config_file): with open(config_file) as fp: @@ -64,9 +98,20 @@ class KeyboardModel: self.config_path = os.path.join( root, 'etc', 'default', 'keyboard') if os.path.exists(self.config_path): - self.setting = from_config_file(self.config_path) + self.default_setting = from_config_file(self.config_path) else: - self.setting = KeyboardSetting(layout='us') + self.default_setting = layout_for_lang['en_US.UTF-8'] + self._setting = None + + @property + def setting(self): + if self._setting is None: + return self.default_setting + return self._setting + + @setting.setter + def setting(self, value): + self._setting = value def render_config_file(self): options = "" @@ -87,3 +132,11 @@ class KeyboardModel: }, }, } + + def setting_for_lang(self, lang): + if self._setting is not None: + return self._setting + layout = layout_for_lang.get(lang, None) + if layout is None: + return self.default_setting + return layout diff --git a/subiquity/models/tests/test_keyboard.py b/subiquity/models/tests/test_keyboard.py new file mode 100644 index 00000000..0be28ab5 --- /dev/null +++ b/subiquity/models/tests/test_keyboard.py @@ -0,0 +1,59 @@ +# Copyright 2022 Canonical, Ltd. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from parameterized import parameterized + +from subiquitycore.tests import SubiTestCase + +from subiquity.common.types import KeyboardSetting +from subiquity.models.keyboard import ( + KeyboardModel, + layout_for_lang, + ) + + +class TestKeyboardModel(SubiTestCase): + def setUp(self): + self.model = KeyboardModel(self.tmp_dir()) + + def testDefaultUS(self): + self.assertIsNone(self.model._setting) + self.assertEqual('us', self.model.setting.layout) + + def testSetToZZ(self): + val = KeyboardSetting(layout='zz') + self.model.setting = val + self.assertEqual(val, self.model.setting) + self.assertEqual(val, self.model._setting) + + @parameterized.expand([ + ['ast_ES.UTF-8', 'es', 'ast'], + ['de_DE.UTF-8', 'de', ''], + ['fr_FR.UTF-8', 'fr', 'latin9'], + ['oc', 'us', ''], + ]) + def testSettingForLang(self, lang, layout, variant): + val = self.model.setting_for_lang(lang) + self.assertEqual(layout, val.layout) + self.assertEqual(variant, val.variant) + + def testAllLangsHaveKeyboardSuggestion(self): + # every language in the list needs a suggestion, + # even if only the default + with open('languagelist') as fp: + for line in fp.readlines(): + tokens = line.split(':') + locale = tokens[1] + self.assertIn(locale, layout_for_lang.keys()) diff --git a/subiquity/server/controllers/keyboard.py b/subiquity/server/controllers/keyboard.py index 8fb7f930..e462e35d 100644 --- a/subiquity/server/controllers/keyboard.py +++ b/subiquity/server/controllers/keyboard.py @@ -215,10 +215,10 @@ class KeyboardController(SubiquityController): await arun_command(cmd) async def GET(self) -> KeyboardSetup: - self.keyboard_list.load_language( - self.app.base_model.locale.selected_language) + lang = self.app.base_model.locale.selected_language + self.keyboard_list.load_language(lang) return KeyboardSetup( - setting=for_ui(self.model.setting), + setting=for_ui(self.model.setting_for_lang(lang)), layouts=self.keyboard_list.layouts) async def POST(self, data: KeyboardSetting):