From 3dc0d957e838c34b48a0782d2540341e33b24070 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 28 Mar 2022 22:49:05 +1100 Subject: Deflate user interactions (#1019) * Deflate the user interactions file * Fix flake8 Co-authored-by: Daniel Girtler --- archinstall/lib/user_interaction/general_conf.py | 184 +++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 archinstall/lib/user_interaction/general_conf.py (limited to 'archinstall/lib/user_interaction/general_conf.py') diff --git a/archinstall/lib/user_interaction/general_conf.py b/archinstall/lib/user_interaction/general_conf.py new file mode 100644 index 00000000..c42e9e27 --- /dev/null +++ b/archinstall/lib/user_interaction/general_conf.py @@ -0,0 +1,184 @@ +from __future__ import annotations + +import logging +from typing import List, Any, Optional, Dict, TYPE_CHECKING + +from ..menu.text_input import TextInput + +from ..locale_helpers import list_keyboard_languages, list_timezones +from ..menu import Menu +from ..output import log +from ..profiles import Profile, list_profiles +from ..mirrors import list_mirrors + +from ..translation import Translation +from ..packages.packages import validate_package_list + +if TYPE_CHECKING: + _: Any + + +def ask_ntp(preset: bool = True) -> bool: + prompt = str(_('Would you like to use automatic time synchronization (NTP) with the default time servers?\n')) + prompt += str(_('Hardware time and other post-configuration steps might be required in order for NTP to work.\nFor more information, please check the Arch wiki')) + if preset: + preset_val = 'yes' + else: + preset_val = 'no' + choice = Menu(prompt, ['yes', 'no'], skip=False, preset_values=preset_val, default_option='yes').run() + return False if choice == 'no' else True + + +def ask_hostname(preset: str = None) -> str: + hostname = TextInput(_('Desired hostname for the installation: '), preset).run().strip(' ') + return hostname + + +def ask_for_a_timezone(preset: str = None) -> str: + timezones = list_timezones() + default = 'UTC' + + selected_tz = Menu(_('Select a timezone'), + list(timezones), + skip=False, + preset_values=preset, + default_option=default).run() + + return selected_tz + + +def ask_for_audio_selection(desktop: bool = True, preset: str = None) -> str: + audio = 'pipewire' if desktop else 'none' + choices = ['pipewire', 'pulseaudio'] if desktop else ['pipewire', 'pulseaudio', 'none'] + selected_audio = Menu(_('Choose an audio server'), choices, preset_values=preset, default_option=audio, skip=False).run() + return selected_audio + + +def select_language(default_value: str, preset_value: str = None) -> str: + """ + Asks the user to select a language + Usually this is combined with :ref:`archinstall.list_keyboard_languages`. + + :return: The language/dictionary key of the selected language + :rtype: str + """ + kb_lang = list_keyboard_languages() + # sort alphabetically and then by length + # it's fine if the list is big because the Menu + # allows for searching anyways + sorted_kb_lang = sorted(sorted(list(kb_lang)), key=len) + + selected_lang = Menu(_('Select Keyboard layout'), + sorted_kb_lang, + default_option=default_value, + preset_values=preset_value, + sort=False).run() + return selected_lang + + +def select_mirror_regions(preset_values: Dict[str, Any] = {}) -> Dict[str, Any]: + """ + Asks the user to select a mirror or region + Usually this is combined with :ref:`archinstall.list_mirrors`. + + :return: The dictionary information about a mirror/region. + :rtype: dict + """ + if preset_values is None: + preselected = None + else: + preselected = list(preset_values.keys()) + mirrors = list_mirrors() + selected_mirror = Menu(_('Select one of the regions to download packages from'), + list(mirrors.keys()), + preset_values=preselected, + multi=True).run() + + if selected_mirror is not None: + return {selected: mirrors[selected] for selected in selected_mirror} + + return {} + + +def select_archinstall_language(default='English'): + languages = Translation.get_all_names() + language = Menu(_('Select Archinstall language'), languages, default_option=default).run() + return language + + +def select_profile() -> Optional[Profile]: + """ + # Asks the user to select a profile from the available profiles. + # + # :return: The name/dictionary key of the selected profile + # :rtype: str + # """ + top_level_profiles = sorted(list(list_profiles(filter_top_level_profiles=True))) + options = {} + + for profile in top_level_profiles: + profile = Profile(None, profile) + description = profile.get_profile_description() + + option = f'{profile.profile}: {description}' + options[option] = profile + + title = _('This is a list of pre-programmed profiles, they might make it easier to install things like desktop environments') + + selection = Menu(title=title, p_options=list(options.keys())).run() + + if selection is not None: + return options[selection] + + return None + + +def ask_additional_packages_to_install(pre_set_packages: List[str] = []) -> List[str]: + # Additional packages (with some light weight error handling for invalid package names) + print(_('Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed.')) + print(_('If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt.')) + + def read_packages(already_defined: list = []) -> list: + display = ' '.join(already_defined) + input_packages = TextInput(_('Write additional packages to install (space separated, leave blank to skip): '), display).run() + return input_packages.split(' ') if input_packages else [] + + pre_set_packages = pre_set_packages if pre_set_packages else [] + packages = read_packages(pre_set_packages) + + while True: + if len(packages): + # Verify packages that were given + print(_("Verifying that additional packages exist (this might take a few seconds)")) + valid, invalid = validate_package_list(packages) + + if invalid: + log(f"Some packages could not be found in the repository: {invalid}", level=logging.WARNING, fg='red') + packages = read_packages(valid) + continue + break + + return packages + + +def select_additional_repositories(preset: List[str]) -> List[str]: + """ + Allows the user to select additional repositories (multilib, and testing) if desired. + + :return: The string as a selected repository + :rtype: string + """ + + repositories = ["multilib", "testing"] + + additional_repositories = Menu(_('Choose which optional additional repositories to enable'), + repositories, + sort=False, + multi=True, + preset_values=preset, + default_option=[]).run() + + if additional_repositories is not None: + return additional_repositories + + return [] -- cgit v1.2.3-54-g00ecf