We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Functions `select_language()` and `select_kb_layout()` are identical
https://github.com/archlinux/archinstall/blob/edbc13590366e93bb8a85eacf104d5613bc5793a/archinstall/lib/interactions/general_conf.py#L88-L111

https://github.com/archlinux/archinstall/blob/edbc13590366e93bb8a85eacf104d5613bc5793a/archinstall/lib/locale/locale_menu.py#L132-L155

The function `select_language()` is not used.

The function `select_kb_layout()` is used once:

https://github.com/archlinux/archinstall/blob/edbc13590366e93bb8a85eacf104d5613bc5793a/archinstall/lib/locale/locale_menu.py#L90

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `archinstall/lib/interactions/general_conf.py`
Content:
```
1 from __future__ import annotations
2 
3 import pathlib
4 from typing import List, Any, Optional, TYPE_CHECKING
5 
6 from ..locale import list_timezones, list_keyboard_languages
7 from ..menu import MenuSelectionType, Menu, TextInput
8 from ..models.audio_configuration import Audio, AudioConfiguration
9 from ..output import warn
10 from ..packages.packages import validate_package_list
11 from ..storage import storage
12 from ..translationhandler import Language
13 
14 if TYPE_CHECKING:
15 	_: Any
16 
17 
18 def ask_ntp(preset: bool = True) -> bool:
19 	prompt = str(_('Would you like to use automatic time synchronization (NTP) with the default time servers?\n'))
20 	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'))
21 	if preset:
22 		preset_val = Menu.yes()
23 	else:
24 		preset_val = Menu.no()
25 	choice = Menu(prompt, Menu.yes_no(), skip=False, preset_values=preset_val, default_option=Menu.yes()).run()
26 
27 	return False if choice.value == Menu.no() else True
28 
29 
30 def ask_hostname(preset: str = '') -> str:
31 	hostname = TextInput(
32 		str(_('Desired hostname for the installation: ')),
33 		preset
34 	).run().strip()
35 
36 	if not hostname:
37 		return preset
38 
39 	return hostname
40 
41 
42 def ask_for_a_timezone(preset: Optional[str] = None) -> Optional[str]:
43 	timezones = list_timezones()
44 	default = 'UTC'
45 
46 	choice = Menu(
47 		_('Select a timezone'),
48 		timezones,
49 		preset_values=preset,
50 		default_option=default
51 	).run()
52 
53 	match choice.type_:
54 		case MenuSelectionType.Skip: return preset
55 		case MenuSelectionType.Selection: return choice.single_value
56 
57 	return None
58 
59 
60 def ask_for_audio_selection(
61 	current: Optional[AudioConfiguration] = None
62 ) -> Optional[AudioConfiguration]:
63 	choices = [
64 		Audio.Pipewire.name,
65 		Audio.Pulseaudio.name,
66 		Audio.no_audio_text()
67 	]
68 
69 	preset = current.audio.name if current else None
70 
71 	choice = Menu(
72 		_('Choose an audio server'),
73 		choices,
74 		preset_values=preset
75 	).run()
76 
77 	match choice.type_:
78 		case MenuSelectionType.Skip: return current
79 		case MenuSelectionType.Selection:
80 			value = choice.single_value
81 			if value == Audio.no_audio_text():
82 				return None
83 			else:
84 				return AudioConfiguration(Audio[value])
85 
86 	return None
87 
88 
89 def select_language(preset: Optional[str] = None) -> Optional[str]:
90 	"""
91 	Asks the user to select a language
92 	Usually this is combined with :ref:`archinstall.list_keyboard_languages`.
93 
94 	:return: The language/dictionary key of the selected language
95 	:rtype: str
96 	"""
97 	kb_lang = list_keyboard_languages()
98 	# sort alphabetically and then by length
99 	sorted_kb_lang = sorted(kb_lang, key=lambda x: (len(x), x))
100 
101 	choice = Menu(
102 		_('Select keyboard layout'),
103 		sorted_kb_lang,
104 		preset_values=preset,
105 		sort=False
106 	).run()
107 
108 	match choice.type_:
109 		case MenuSelectionType.Skip: return preset
110 		case MenuSelectionType.Selection: return choice.single_value
111 
112 	return None
113 
114 
115 def select_archinstall_language(languages: List[Language], preset: Language) -> Language:
116 	# these are the displayed language names which can either be
117 	# the english name of a language or, if present, the
118 	# name of the language in its own language
119 	options = {lang.display_name: lang for lang in languages}
120 
121 	title = 'NOTE: If a language can not displayed properly, a proper font must be set manually in the console.\n'
122 	title += 'All available fonts can be found in "/usr/share/kbd/consolefonts"\n'
123 	title += 'e.g. setfont LatGrkCyr-8x16 (to display latin/greek/cyrillic characters)\n'
124 
125 	choice = Menu(
126 		title,
127 		list(options.keys()),
128 		default_option=preset.display_name,
129 		preview_size=0.5
130 	).run()
131 
132 	match choice.type_:
133 		case MenuSelectionType.Skip: return preset
134 		case MenuSelectionType.Selection: return options[choice.single_value]
135 
136 	raise ValueError('Language selection not handled')
137 
138 
139 def ask_additional_packages_to_install(preset: List[str] = []) -> List[str]:
140 	# Additional packages (with some light weight error handling for invalid package names)
141 	print(_('Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed.'))
142 	print(_('If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt.'))
143 
144 	def read_packages(p: List = []) -> list:
145 		display = ' '.join(p)
146 		input_packages = TextInput(_('Write additional packages to install (space separated, leave blank to skip): '), display).run().strip()
147 		return input_packages.split() if input_packages else []
148 
149 	preset = preset if preset else []
150 	packages = read_packages(preset)
151 
152 	if not storage['arguments']['offline'] and not storage['arguments']['no_pkg_lookups']:
153 		while True:
154 			if len(packages):
155 				# Verify packages that were given
156 				print(_("Verifying that additional packages exist (this might take a few seconds)"))
157 				valid, invalid = validate_package_list(packages)
158 
159 				if invalid:
160 					warn(f"Some packages could not be found in the repository: {invalid}")
161 					packages = read_packages(valid)
162 					continue
163 			break
164 
165 	return packages
166 
167 
168 def add_number_of_parallel_downloads(input_number :Optional[int] = None) -> Optional[int]:
169 	max_recommended = 5
170 	print(_(f"This option enables the number of parallel downloads that can occur during package downloads"))
171 	print(_("Enter the number of parallel downloads to be enabled.\n\nNote:\n"))
172 	print(str(_(" - Maximum recommended value : {} ( Allows {} parallel downloads at a time )")).format(max_recommended, max_recommended))
173 	print(_(" - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )\n"))
174 
175 	while True:
176 		try:
177 			input_number = int(TextInput(_("[Default value: 0] > ")).run().strip() or 0)
178 			if input_number <= 0:
179 				input_number = 0
180 			break
181 		except:
182 			print(str(_("Invalid input! Try again with a valid input [or 0 to disable]")).format(max_recommended))
183 
184 	pacman_conf_path = pathlib.Path("/etc/pacman.conf")
185 	with pacman_conf_path.open() as f:
186 		pacman_conf = f.read().split("\n")
187 
188 	with pacman_conf_path.open("w") as fwrite:
189 		for line in pacman_conf:
190 			if "ParallelDownloads" in line:
191 				fwrite.write(f"ParallelDownloads = {input_number}\n") if not input_number == 0 else fwrite.write("#ParallelDownloads = 0\n")
192 			else:
193 				fwrite.write(f"{line}\n")
194 
195 	return input_number
196 
197 
198 def select_additional_repositories(preset: List[str]) -> List[str]:
199 	"""
200 	Allows the user to select additional repositories (multilib, and testing) if desired.
201 
202 	:return: The string as a selected repository
203 	:rtype: string
204 	"""
205 
206 	repositories = ["multilib", "testing"]
207 
208 	choice = Menu(
209 		_('Choose which optional additional repositories to enable'),
210 		repositories,
211 		sort=False,
212 		multi=True,
213 		preset_values=preset,
214 		allow_reset=True
215 	).run()
216 
217 	match choice.type_:
218 		case MenuSelectionType.Skip: return preset
219 		case MenuSelectionType.Reset: return []
220 		case MenuSelectionType.Selection: return choice.single_value
221 
222 	return []
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/archinstall/lib/interactions/general_conf.py b/archinstall/lib/interactions/general_conf.py
--- a/archinstall/lib/interactions/general_conf.py
+++ b/archinstall/lib/interactions/general_conf.py
@@ -3,7 +3,7 @@
 import pathlib
 from typing import List, Any, Optional, TYPE_CHECKING
 
-from ..locale import list_timezones, list_keyboard_languages
+from ..locale import list_timezones
 from ..menu import MenuSelectionType, Menu, TextInput
 from ..models.audio_configuration import Audio, AudioConfiguration
 from ..output import warn
@@ -87,29 +87,16 @@
 
 
 def select_language(preset: Optional[str] = None) -> Optional[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
-	sorted_kb_lang = sorted(kb_lang, key=lambda x: (len(x), x))
+	from ..locale.locale_menu import select_kb_layout
 
-	choice = Menu(
-		_('Select keyboard layout'),
-		sorted_kb_lang,
-		preset_values=preset,
-		sort=False
-	).run()
+	# We'll raise an exception in an upcoming version.
+	# from ..exceptions import Deprecated
+	# raise Deprecated("select_language() has been deprecated, use select_kb_layout() instead.")
 
-	match choice.type_:
-		case MenuSelectionType.Skip: return preset
-		case MenuSelectionType.Selection: return choice.single_value
+	# No need to translate this i feel, as it's a short lived message.
+	warn("select_language() is deprecated, use select_kb_layout() instead. select_language() will be removed in a future version")
 
-	return None
+	return select_kb_layout(preset)
 
 
 def select_archinstall_language(languages: List[Language], preset: Language) -> Language:

{"golden_diff": "diff --git a/archinstall/lib/interactions/general_conf.py b/archinstall/lib/interactions/general_conf.py\n--- a/archinstall/lib/interactions/general_conf.py\n+++ b/archinstall/lib/interactions/general_conf.py\n@@ -3,7 +3,7 @@\n import pathlib\n from typing import List, Any, Optional, TYPE_CHECKING\n \n-from ..locale import list_timezones, list_keyboard_languages\n+from ..locale import list_timezones\n from ..menu import MenuSelectionType, Menu, TextInput\n from ..models.audio_configuration import Audio, AudioConfiguration\n from ..output import warn\n@@ -87,29 +87,16 @@\n \n \n def select_language(preset: Optional[str] = None) -> Optional[str]:\n-\t\"\"\"\n-\tAsks the user to select a language\n-\tUsually this is combined with :ref:`archinstall.list_keyboard_languages`.\n-\n-\t:return: The language/dictionary key of the selected language\n-\t:rtype: str\n-\t\"\"\"\n-\tkb_lang = list_keyboard_languages()\n-\t# sort alphabetically and then by length\n-\tsorted_kb_lang = sorted(kb_lang, key=lambda x: (len(x), x))\n+\tfrom ..locale.locale_menu import select_kb_layout\n \n-\tchoice = Menu(\n-\t\t_('Select keyboard layout'),\n-\t\tsorted_kb_lang,\n-\t\tpreset_values=preset,\n-\t\tsort=False\n-\t).run()\n+\t# We'll raise an exception in an upcoming version.\n+\t# from ..exceptions import Deprecated\n+\t# raise Deprecated(\"select_language() has been deprecated, use select_kb_layout() instead.\")\n \n-\tmatch choice.type_:\n-\t\tcase MenuSelectionType.Skip: return preset\n-\t\tcase MenuSelectionType.Selection: return choice.single_value\n+\t# No need to translate this i feel, as it's a short lived message.\n+\twarn(\"select_language() is deprecated, use select_kb_layout() instead. select_language() will be removed in a future version\")\n \n-\treturn None\n+\treturn select_kb_layout(preset)\n \n \n def select_archinstall_language(languages: List[Language], preset: Language) -> Language:\n", "issue": "Functions `select_language()` and `select_kb_layout()` are identical\nhttps://github.com/archlinux/archinstall/blob/edbc13590366e93bb8a85eacf104d5613bc5793a/archinstall/lib/interactions/general_conf.py#L88-L111\r\n\r\nhttps://github.com/archlinux/archinstall/blob/edbc13590366e93bb8a85eacf104d5613bc5793a/archinstall/lib/locale/locale_menu.py#L132-L155\r\n\r\nThe function `select_language()` is not used.\r\n\r\nThe function `select_kb_layout()` is used once:\r\n\r\nhttps://github.com/archlinux/archinstall/blob/edbc13590366e93bb8a85eacf104d5613bc5793a/archinstall/lib/locale/locale_menu.py#L90\n", "before_files": [{"content": "from __future__ import annotations\n\nimport pathlib\nfrom typing import List, Any, Optional, TYPE_CHECKING\n\nfrom ..locale import list_timezones, list_keyboard_languages\nfrom ..menu import MenuSelectionType, Menu, TextInput\nfrom ..models.audio_configuration import Audio, AudioConfiguration\nfrom ..output import warn\nfrom ..packages.packages import validate_package_list\nfrom ..storage import storage\nfrom ..translationhandler import Language\n\nif TYPE_CHECKING:\n\t_: Any\n\n\ndef ask_ntp(preset: bool = True) -> bool:\n\tprompt = str(_('Would you like to use automatic time synchronization (NTP) with the default time servers?\\n'))\n\tprompt += 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'))\n\tif preset:\n\t\tpreset_val = Menu.yes()\n\telse:\n\t\tpreset_val = Menu.no()\n\tchoice = Menu(prompt, Menu.yes_no(), skip=False, preset_values=preset_val, default_option=Menu.yes()).run()\n\n\treturn False if choice.value == Menu.no() else True\n\n\ndef ask_hostname(preset: str = '') -> str:\n\thostname = TextInput(\n\t\tstr(_('Desired hostname for the installation: ')),\n\t\tpreset\n\t).run().strip()\n\n\tif not hostname:\n\t\treturn preset\n\n\treturn hostname\n\n\ndef ask_for_a_timezone(preset: Optional[str] = None) -> Optional[str]:\n\ttimezones = list_timezones()\n\tdefault = 'UTC'\n\n\tchoice = Menu(\n\t\t_('Select a timezone'),\n\t\ttimezones,\n\t\tpreset_values=preset,\n\t\tdefault_option=default\n\t).run()\n\n\tmatch choice.type_:\n\t\tcase MenuSelectionType.Skip: return preset\n\t\tcase MenuSelectionType.Selection: return choice.single_value\n\n\treturn None\n\n\ndef ask_for_audio_selection(\n\tcurrent: Optional[AudioConfiguration] = None\n) -> Optional[AudioConfiguration]:\n\tchoices = [\n\t\tAudio.Pipewire.name,\n\t\tAudio.Pulseaudio.name,\n\t\tAudio.no_audio_text()\n\t]\n\n\tpreset = current.audio.name if current else None\n\n\tchoice = Menu(\n\t\t_('Choose an audio server'),\n\t\tchoices,\n\t\tpreset_values=preset\n\t).run()\n\n\tmatch choice.type_:\n\t\tcase MenuSelectionType.Skip: return current\n\t\tcase MenuSelectionType.Selection:\n\t\t\tvalue = choice.single_value\n\t\t\tif value == Audio.no_audio_text():\n\t\t\t\treturn None\n\t\t\telse:\n\t\t\t\treturn AudioConfiguration(Audio[value])\n\n\treturn None\n\n\ndef select_language(preset: Optional[str] = None) -> Optional[str]:\n\t\"\"\"\n\tAsks the user to select a language\n\tUsually this is combined with :ref:`archinstall.list_keyboard_languages`.\n\n\t:return: The language/dictionary key of the selected language\n\t:rtype: str\n\t\"\"\"\n\tkb_lang = list_keyboard_languages()\n\t# sort alphabetically and then by length\n\tsorted_kb_lang = sorted(kb_lang, key=lambda x: (len(x), x))\n\n\tchoice = Menu(\n\t\t_('Select keyboard layout'),\n\t\tsorted_kb_lang,\n\t\tpreset_values=preset,\n\t\tsort=False\n\t).run()\n\n\tmatch choice.type_:\n\t\tcase MenuSelectionType.Skip: return preset\n\t\tcase MenuSelectionType.Selection: return choice.single_value\n\n\treturn None\n\n\ndef select_archinstall_language(languages: List[Language], preset: Language) -> Language:\n\t# these are the displayed language names which can either be\n\t# the english name of a language or, if present, the\n\t# name of the language in its own language\n\toptions = {lang.display_name: lang for lang in languages}\n\n\ttitle = 'NOTE: If a language can not displayed properly, a proper font must be set manually in the console.\\n'\n\ttitle += 'All available fonts can be found in \"/usr/share/kbd/consolefonts\"\\n'\n\ttitle += 'e.g. setfont LatGrkCyr-8x16 (to display latin/greek/cyrillic characters)\\n'\n\n\tchoice = Menu(\n\t\ttitle,\n\t\tlist(options.keys()),\n\t\tdefault_option=preset.display_name,\n\t\tpreview_size=0.5\n\t).run()\n\n\tmatch choice.type_:\n\t\tcase MenuSelectionType.Skip: return preset\n\t\tcase MenuSelectionType.Selection: return options[choice.single_value]\n\n\traise ValueError('Language selection not handled')\n\n\ndef ask_additional_packages_to_install(preset: List[str] = []) -> List[str]:\n\t# Additional packages (with some light weight error handling for invalid package names)\n\tprint(_('Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed.'))\n\tprint(_('If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt.'))\n\n\tdef read_packages(p: List = []) -> list:\n\t\tdisplay = ' '.join(p)\n\t\tinput_packages = TextInput(_('Write additional packages to install (space separated, leave blank to skip): '), display).run().strip()\n\t\treturn input_packages.split() if input_packages else []\n\n\tpreset = preset if preset else []\n\tpackages = read_packages(preset)\n\n\tif not storage['arguments']['offline'] and not storage['arguments']['no_pkg_lookups']:\n\t\twhile True:\n\t\t\tif len(packages):\n\t\t\t\t# Verify packages that were given\n\t\t\t\tprint(_(\"Verifying that additional packages exist (this might take a few seconds)\"))\n\t\t\t\tvalid, invalid = validate_package_list(packages)\n\n\t\t\t\tif invalid:\n\t\t\t\t\twarn(f\"Some packages could not be found in the repository: {invalid}\")\n\t\t\t\t\tpackages = read_packages(valid)\n\t\t\t\t\tcontinue\n\t\t\tbreak\n\n\treturn packages\n\n\ndef add_number_of_parallel_downloads(input_number :Optional[int] = None) -> Optional[int]:\n\tmax_recommended = 5\n\tprint(_(f\"This option enables the number of parallel downloads that can occur during package downloads\"))\n\tprint(_(\"Enter the number of parallel downloads to be enabled.\\n\\nNote:\\n\"))\n\tprint(str(_(\" - Maximum recommended value : {} ( Allows {} parallel downloads at a time )\")).format(max_recommended, max_recommended))\n\tprint(_(\" - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )\\n\"))\n\n\twhile True:\n\t\ttry:\n\t\t\tinput_number = int(TextInput(_(\"[Default value: 0] > \")).run().strip() or 0)\n\t\t\tif input_number <= 0:\n\t\t\t\tinput_number = 0\n\t\t\tbreak\n\t\texcept:\n\t\t\tprint(str(_(\"Invalid input! Try again with a valid input [or 0 to disable]\")).format(max_recommended))\n\n\tpacman_conf_path = pathlib.Path(\"/etc/pacman.conf\")\n\twith pacman_conf_path.open() as f:\n\t\tpacman_conf = f.read().split(\"\\n\")\n\n\twith pacman_conf_path.open(\"w\") as fwrite:\n\t\tfor line in pacman_conf:\n\t\t\tif \"ParallelDownloads\" in line:\n\t\t\t\tfwrite.write(f\"ParallelDownloads = {input_number}\\n\") if not input_number == 0 else fwrite.write(\"#ParallelDownloads = 0\\n\")\n\t\t\telse:\n\t\t\t\tfwrite.write(f\"{line}\\n\")\n\n\treturn input_number\n\n\ndef select_additional_repositories(preset: List[str]) -> List[str]:\n\t\"\"\"\n\tAllows the user to select additional repositories (multilib, and testing) if desired.\n\n\t:return: The string as a selected repository\n\t:rtype: string\n\t\"\"\"\n\n\trepositories = [\"multilib\", \"testing\"]\n\n\tchoice = Menu(\n\t\t_('Choose which optional additional repositories to enable'),\n\t\trepositories,\n\t\tsort=False,\n\t\tmulti=True,\n\t\tpreset_values=preset,\n\t\tallow_reset=True\n\t).run()\n\n\tmatch choice.type_:\n\t\tcase MenuSelectionType.Skip: return preset\n\t\tcase MenuSelectionType.Reset: return []\n\t\tcase MenuSelectionType.Selection: return choice.single_value\n\n\treturn []", "path": "archinstall/lib/interactions/general_conf.py"}], "after_files": [{"content": "from __future__ import annotations\n\nimport pathlib\nfrom typing import List, Any, Optional, TYPE_CHECKING\n\nfrom ..locale import list_timezones\nfrom ..menu import MenuSelectionType, Menu, TextInput\nfrom ..models.audio_configuration import Audio, AudioConfiguration\nfrom ..output import warn\nfrom ..packages.packages import validate_package_list\nfrom ..storage import storage\nfrom ..translationhandler import Language\n\nif TYPE_CHECKING:\n\t_: Any\n\n\ndef ask_ntp(preset: bool = True) -> bool:\n\tprompt = str(_('Would you like to use automatic time synchronization (NTP) with the default time servers?\\n'))\n\tprompt += 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'))\n\tif preset:\n\t\tpreset_val = Menu.yes()\n\telse:\n\t\tpreset_val = Menu.no()\n\tchoice = Menu(prompt, Menu.yes_no(), skip=False, preset_values=preset_val, default_option=Menu.yes()).run()\n\n\treturn False if choice.value == Menu.no() else True\n\n\ndef ask_hostname(preset: str = '') -> str:\n\thostname = TextInput(\n\t\tstr(_('Desired hostname for the installation: ')),\n\t\tpreset\n\t).run().strip()\n\n\tif not hostname:\n\t\treturn preset\n\n\treturn hostname\n\n\ndef ask_for_a_timezone(preset: Optional[str] = None) -> Optional[str]:\n\ttimezones = list_timezones()\n\tdefault = 'UTC'\n\n\tchoice = Menu(\n\t\t_('Select a timezone'),\n\t\ttimezones,\n\t\tpreset_values=preset,\n\t\tdefault_option=default\n\t).run()\n\n\tmatch choice.type_:\n\t\tcase MenuSelectionType.Skip: return preset\n\t\tcase MenuSelectionType.Selection: return choice.single_value\n\n\treturn None\n\n\ndef ask_for_audio_selection(\n\tcurrent: Optional[AudioConfiguration] = None\n) -> Optional[AudioConfiguration]:\n\tchoices = [\n\t\tAudio.Pipewire.name,\n\t\tAudio.Pulseaudio.name,\n\t\tAudio.no_audio_text()\n\t]\n\n\tpreset = current.audio.name if current else None\n\n\tchoice = Menu(\n\t\t_('Choose an audio server'),\n\t\tchoices,\n\t\tpreset_values=preset\n\t).run()\n\n\tmatch choice.type_:\n\t\tcase MenuSelectionType.Skip: return current\n\t\tcase MenuSelectionType.Selection:\n\t\t\tvalue = choice.single_value\n\t\t\tif value == Audio.no_audio_text():\n\t\t\t\treturn None\n\t\t\telse:\n\t\t\t\treturn AudioConfiguration(Audio[value])\n\n\treturn None\n\n\ndef select_language(preset: Optional[str] = None) -> Optional[str]:\n\tfrom ..locale.locale_menu import select_kb_layout\n\n\t# We'll raise an exception in an upcoming version.\n\t# from ..exceptions import Deprecated\n\t# raise Deprecated(\"select_language() has been deprecated, use select_kb_layout() instead.\")\n\n\t# No need to translate this i feel, as it's a short lived message.\n\twarn(\"select_language() is deprecated, use select_kb_layout() instead. select_language() will be removed in a future version\")\n\n\treturn select_kb_layout(preset)\n\n\ndef select_archinstall_language(languages: List[Language], preset: Language) -> Language:\n\t# these are the displayed language names which can either be\n\t# the english name of a language or, if present, the\n\t# name of the language in its own language\n\toptions = {lang.display_name: lang for lang in languages}\n\n\ttitle = 'NOTE: If a language can not displayed properly, a proper font must be set manually in the console.\\n'\n\ttitle += 'All available fonts can be found in \"/usr/share/kbd/consolefonts\"\\n'\n\ttitle += 'e.g. setfont LatGrkCyr-8x16 (to display latin/greek/cyrillic characters)\\n'\n\n\tchoice = Menu(\n\t\ttitle,\n\t\tlist(options.keys()),\n\t\tdefault_option=preset.display_name,\n\t\tpreview_size=0.5\n\t).run()\n\n\tmatch choice.type_:\n\t\tcase MenuSelectionType.Skip: return preset\n\t\tcase MenuSelectionType.Selection: return options[choice.single_value]\n\n\traise ValueError('Language selection not handled')\n\n\ndef ask_additional_packages_to_install(preset: List[str] = []) -> List[str]:\n\t# Additional packages (with some light weight error handling for invalid package names)\n\tprint(_('Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed.'))\n\tprint(_('If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt.'))\n\n\tdef read_packages(p: List = []) -> list:\n\t\tdisplay = ' '.join(p)\n\t\tinput_packages = TextInput(_('Write additional packages to install (space separated, leave blank to skip): '), display).run().strip()\n\t\treturn input_packages.split() if input_packages else []\n\n\tpreset = preset if preset else []\n\tpackages = read_packages(preset)\n\n\tif not storage['arguments']['offline'] and not storage['arguments']['no_pkg_lookups']:\n\t\twhile True:\n\t\t\tif len(packages):\n\t\t\t\t# Verify packages that were given\n\t\t\t\tprint(_(\"Verifying that additional packages exist (this might take a few seconds)\"))\n\t\t\t\tvalid, invalid = validate_package_list(packages)\n\n\t\t\t\tif invalid:\n\t\t\t\t\twarn(f\"Some packages could not be found in the repository: {invalid}\")\n\t\t\t\t\tpackages = read_packages(valid)\n\t\t\t\t\tcontinue\n\t\t\tbreak\n\n\treturn packages\n\n\ndef add_number_of_parallel_downloads(input_number :Optional[int] = None) -> Optional[int]:\n\tmax_recommended = 5\n\tprint(_(f\"This option enables the number of parallel downloads that can occur during package downloads\"))\n\tprint(_(\"Enter the number of parallel downloads to be enabled.\\n\\nNote:\\n\"))\n\tprint(str(_(\" - Maximum recommended value : {} ( Allows {} parallel downloads at a time )\")).format(max_recommended, max_recommended))\n\tprint(_(\" - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )\\n\"))\n\n\twhile True:\n\t\ttry:\n\t\t\tinput_number = int(TextInput(_(\"[Default value: 0] > \")).run().strip() or 0)\n\t\t\tif input_number <= 0:\n\t\t\t\tinput_number = 0\n\t\t\tbreak\n\t\texcept:\n\t\t\tprint(str(_(\"Invalid input! Try again with a valid input [or 0 to disable]\")).format(max_recommended))\n\n\tpacman_conf_path = pathlib.Path(\"/etc/pacman.conf\")\n\twith pacman_conf_path.open() as f:\n\t\tpacman_conf = f.read().split(\"\\n\")\n\n\twith pacman_conf_path.open(\"w\") as fwrite:\n\t\tfor line in pacman_conf:\n\t\t\tif \"ParallelDownloads\" in line:\n\t\t\t\tfwrite.write(f\"ParallelDownloads = {input_number}\\n\") if not input_number == 0 else fwrite.write(\"#ParallelDownloads = 0\\n\")\n\t\t\telse:\n\t\t\t\tfwrite.write(f\"{line}\\n\")\n\n\treturn input_number\n\n\ndef select_additional_repositories(preset: List[str]) -> List[str]:\n\t\"\"\"\n\tAllows the user to select additional repositories (multilib, and testing) if desired.\n\n\t:return: The string as a selected repository\n\t:rtype: string\n\t\"\"\"\n\n\trepositories = [\"multilib\", \"testing\"]\n\n\tchoice = Menu(\n\t\t_('Choose which optional additional repositories to enable'),\n\t\trepositories,\n\t\tsort=False,\n\t\tmulti=True,\n\t\tpreset_values=preset,\n\t\tallow_reset=True\n\t).run()\n\n\tmatch choice.type_:\n\t\tcase MenuSelectionType.Skip: return preset\n\t\tcase MenuSelectionType.Reset: return []\n\t\tcase MenuSelectionType.Selection: return choice.single_value\n\n\treturn []", "path": "archinstall/lib/interactions/general_conf.py"}]}