Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/archinstall/lib/user_interaction/subvolume_config.py
blob: 94150dee6a68bf6b9fef252ae3339699d890d97f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
from typing import Dict, List, Optional, Any, TYPE_CHECKING

from ..menu.list_manager import ListManager
from ..menu.menu import MenuSelectionType
from ..menu.text_input import TextInput
from ..menu import Menu
from ..models.subvolume import Subvolume
from ... import FormattedOutput

if TYPE_CHECKING:
	_: Any


class SubvolumeList(ListManager):
	def __init__(self, prompt: str, subvolumes: List[Subvolume]):
		self._actions = [
			str(_('Add subvolume')),
			str(_('Edit subvolume')),
			str(_('Delete subvolume'))
		]
		super().__init__(prompt, subvolumes, [self._actions[0]], self._actions[1:])

	def reformat(self, data: List[Subvolume]) -> Dict[str, Optional[Subvolume]]:
		table = FormattedOutput.as_table(data)
		rows = table.split('\n')

		# these are the header rows of the table and do not map to any User obviously
		# we're adding 2 spaces as prefix because the menu selector '> ' will be put before
		# the selectable rows so the header has to be aligned
		display_data: Dict[str, Optional[Subvolume]] = {f'  {rows[0]}': None, f'  {rows[1]}': None}

		for row, subvol in zip(rows[2:], data):
			row = row.replace('|', '\\|')
			display_data[row] = subvol

		return display_data

	def selected_action_display(self, subvolume: Subvolume) -> str:
		return subvolume.name

	def _prompt_options(self, editing: Optional[Subvolume] = None) -> List[str]:
		preset_options = []
		if editing:
			preset_options = editing.options

		choice = Menu(
			str(_("Select the desired subvolume options ")),
			['nodatacow','compress'],
			skip=True,
			preset_values=preset_options,
			multi=True
		).run()

		if choice.type_ == MenuSelectionType.Selection:
			return choice.value  # type: ignore

		return []

	def _add_subvolume(self, editing: Optional[Subvolume] = None) -> Optional[Subvolume]:
		name = TextInput(f'\n\n{_("Subvolume name")}: ', editing.name if editing else '').run()

		if not name:
			return None

		mountpoint = TextInput(f'\n{_("Subvolume mountpoint")}: ', editing.mountpoint if editing else '').run()

		if not mountpoint:
			return None

		options = self._prompt_options(editing)

		subvolume = Subvolume(name, mountpoint)
		subvolume.compress = 'compress' in options
		subvolume.nodatacow = 'nodatacow' in options

		return subvolume

	def handle_action(self, action: str, entry: Optional[Subvolume], data: List[Subvolume]) -> List[Subvolume]:
		if action == self._actions[0]:  # add
			new_subvolume = self._add_subvolume()

			if new_subvolume is not None:
				# in case a user with the same username as an existing user
				# was created we'll replace the existing one
				data = [d for d in data if d.name != new_subvolume.name]
				data += [new_subvolume]
		elif entry is not None:
			if action == self._actions[1]:  # edit subvolume
				new_subvolume = self._add_subvolume(entry)

				if new_subvolume is not None:
					# we'll remove the original subvolume and add the modified version
					data = [d for d in data if d.name != entry.name and d.name != new_subvolume.name]
					data += [new_subvolume]
			elif action == self._actions[2]:  # delete
				data = [d for d in data if d != entry]

		return data