Fix 1091 and other minor fixes (#1103)

* Fix 1091

* Update

* flake8

* Only display btrfs options if there is a filesystem

* Fix 1118

Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
This commit is contained in:
Daniel Girtler 2022-05-02 21:02:21 +10:00 committed by GitHub
parent f00717ff6f
commit 2d37157178
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 71 additions and 44 deletions

View File

@ -89,7 +89,7 @@ from .text_input import TextInput
from .menu import Menu
from os import system
from copy import copy
from typing import Union, Any, List, TYPE_CHECKING
from typing import Union, Any, TYPE_CHECKING, Dict
if TYPE_CHECKING:
_: Any
@ -149,18 +149,26 @@ class ListManager:
# default values for the null case
self.target = None
self.action = self._null_action
if len(self._data) == 0 and self._null_action:
self.exec_action(self._data)
def run(self):
while True:
self._data_formatted = self.reformat(self._data)
options = self._data_formatted + [self.separator]
# this will return a dictionary with the key as the menu entry to be displayed
# and the value is the original value from the self._data container
data_formatted = self.reformat(self._data)
options = list(data_formatted.keys())
options.append(self.separator)
if self._default_action:
options += self._default_action
options += self.bottom_list
system('clear')
target = Menu(self._prompt,
target = Menu(
self._prompt,
options,
sort=False,
clear_screen=False,
@ -171,19 +179,20 @@ class ListManager:
if not target or target in self.bottom_list:
self.action = target
break
if target and target == self.separator:
continue
if target and target in self._default_action:
self.action = target
target = None
self.target = None
self.exec_action(self._data)
continue
if isinstance(self._data,dict):
key = list(self._data.keys())[self._data_formatted.index(target)]
self.target = {key: self._data[key]}
data_key = data_formatted[target]
key = self._data[data_key]
self.target = {data_key: key}
else:
self.target = self._data[self._data_formatted.index(target)]
self.target = self._data[data_formatted[target]]
# Possible enhacement. If run_actions returns false a message line indicating the failure
self.run_actions(target)
@ -211,15 +220,15 @@ class ListManager:
The following methods are expected to be overwritten by the user if the needs of the list are beyond the simple case
"""
def reformat(self, data: Any) -> List[Any]:
def reformat(self, data: Any) -> Dict[str, Any]:
"""
method to get the data in a format suitable to be shown
It is executed once for run loop and processes the whole self._data structure
"""
if isinstance(data,dict):
return list(map(lambda x:f"{x} : {data[x]}",data))
return {f'{k}: {v}': k for k, v in data.items()}
else:
return list(map(lambda x:str(x),data))
return {str(k): k for k in data}
def action_list(self):
"""

View File

@ -41,13 +41,13 @@ def select_disk_layout(block_devices: list, advanced_options=False) -> Dict[str,
custome_mode = str(_('Select what to do with each individual drive (followed by partition usage)'))
modes = [wipe_mode, custome_mode]
print(modes)
mode = Menu(_('Select what you wish to do with the selected block devices'), modes, skip=False).run()
mode = Menu(_('Select what you wish to do with the selected block devices'), modes).run()
if mode == wipe_mode:
return get_default_partition_layout(block_devices, advanced_options)
else:
return select_individual_blockdevice_usage(block_devices)
if mode:
if mode == wipe_mode:
return get_default_partition_layout(block_devices, advanced_options)
else:
return select_individual_blockdevice_usage(block_devices)
def select_disk(dict_o_disks: Dict[str, BlockDevice]) -> BlockDevice:

View File

@ -36,7 +36,7 @@ class UserList(ListManager):
]
super().__init__(prompt, lusers, self.actions, self.actions[0])
def reformat(self, data: Any) -> List[Any]:
def reformat(self, data: List) -> Dict:
def format_element(elem :str):
# secret gives away the length of the password
if data[elem].get('!password'):
@ -49,7 +49,7 @@ class UserList(ListManager):
super_user = ' '
return f"{elem:16}: password {pwd:16} {super_user}"
return list(map(lambda x: format_element(x), data))
return {format_element(e): e for e in data}
def action_list(self):
if self.target:

View File

@ -65,21 +65,26 @@ def _current_partition_layout(partitions: List[Partition], with_idx: bool = Fals
return f'\n\n{title}:\n\n{current_layout}'
def select_partition(title :str, partitions :List[Partition], multiple :bool = False, filter :Callable = None) -> Union[int, List[int], None]:
def _get_partitions(partitions :List[Partition], filter_ :Callable = None) -> List[str]:
"""
filter allows to filter out the indexes once they are set. Should return True if element is to be included
"""
partition_indexes = []
for i in range(len(partitions)):
if filter:
if filter(partitions[i]):
if filter_:
if filter_(partitions[i]):
partition_indexes.append(str(i))
else:
partition_indexes.append(str(i))
return partition_indexes
def select_partition(title :str, partitions :List[Partition], multiple :bool = False, filter_ :Callable = None) -> Union[int, List[int], None]:
partition_indexes = _get_partitions(partitions, filter_)
if len(partition_indexes) == 0:
return None
# old code without filter
# partition_indexes = list(map(str, range(len(partitions))))
partition = Menu(title, partition_indexes, multi=multiple).run()
@ -133,7 +138,7 @@ def manage_new_and_existing_partitions(block_device: 'BlockDevice') -> Dict[str,
while True:
modes = [new_partition, suggest_partition_layout]
if len(block_device_struct['partitions']):
if len(block_device_struct['partitions']) > 0:
modes += [
delete_partition,
delete_all_partitions,
@ -143,9 +148,16 @@ def manage_new_and_existing_partitions(block_device: 'BlockDevice') -> Dict[str,
mark_bootable,
mark_compressed,
set_filesystem_partition,
set_btrfs_subvolumes,
]
indexes = _get_partitions(
block_device_struct["partitions"],
filter_=lambda x: True if x.get('filesystem', {}).get('format') == 'btrfs' else False
)
if len(indexes) > 0:
modes += [set_btrfs_subvolumes]
title = _('Select what to do with\n{}').format(block_device)
# show current partition layout:
@ -165,7 +177,10 @@ def manage_new_and_existing_partitions(block_device: 'BlockDevice') -> Dict[str,
# # https://www.gnu.org/software/parted/manual/html_node/mklabel.html
# name = input("Enter a desired name for the partition: ").strip()
fstype = Menu(_('Enter a desired filesystem type for the partition'), fs_types(), skip=False).run()
fstype = Menu(_('Enter a desired filesystem type for the partition'), fs_types()).run()
if not fstype:
continue
prompt = _('Enter the start sector (percentage or block number, default: {}): ').format(
block_device.first_free_sector)
@ -273,14 +288,13 @@ def manage_new_and_existing_partitions(block_device: 'BlockDevice') -> Dict[str,
if not block_device_struct["partitions"][partition].get('filesystem', None):
block_device_struct["partitions"][partition]['filesystem'] = {}
fstype = Menu(_('Enter a desired filesystem type for the partition'), fs_types(),
skip=False).run()
fstype = Menu(_('Enter a desired filesystem type for the partition'), fs_types()).run()
block_device_struct["partitions"][partition]['filesystem']['format'] = fstype
if fstype:
block_device_struct["partitions"][partition]['filesystem']['format'] = fstype
# Negate the current wipe marking
block_device_struct["partitions"][partition][
'wipe'] = not block_device_struct["partitions"][partition].get('wipe', False)
block_device_struct["partitions"][partition]['wipe'] = not block_device_struct["partitions"][partition].get('wipe', False)
elif task == mark_encrypted:
title = _('{}\n\nSelect which partition to mark as encrypted').format(current_layout)
@ -308,16 +322,18 @@ def manage_new_and_existing_partitions(block_device: 'BlockDevice') -> Dict[str,
block_device_struct["partitions"][partition]['filesystem'] = {}
fstype_title = _('Enter a desired filesystem type for the partition: ')
fstype = Menu(fstype_title, fs_types(), skip=False).run()
fstype = Menu(fstype_title, fs_types()).run()
block_device_struct["partitions"][partition]['filesystem']['format'] = fstype
if fstype:
block_device_struct["partitions"][partition]['filesystem']['format'] = fstype
elif task == set_btrfs_subvolumes:
from .subvolume_config import SubvolumeList
# TODO get preexisting partitions
title = _('{}\n\nSelect which partition to set subvolumes on').format(current_layout)
partition = select_partition(title, block_device_struct["partitions"],filter=lambda x:True if x.get('filesystem',{}).get('format') == 'btrfs' else False)
partition = select_partition(title, block_device_struct["partitions"],filter_=lambda x:True if x.get('filesystem',{}).get('format') == 'btrfs' else False)
if partition is not None:
if not block_device_struct["partitions"][partition].get('btrfs', {}):
block_device_struct["partitions"][partition]['btrfs'] = {}

View File

@ -1,9 +1,10 @@
from typing import List, Any, Dict
from typing import Any, Dict
from ..menu.list_manager import ListManager
from ..menu.selection_menu import Selector, GeneralMenu
from ..menu.text_input import TextInput
from ..menu import Menu
"""
UI classes
"""
@ -14,7 +15,7 @@ class SubvolumeList(ListManager):
self.ObjectDefaultAction = str(_('Add'))
super().__init__(prompt,list,None,self.ObjectNullAction,self.ObjectDefaultAction)
def reformat(self, data: Any) -> List[Any]:
def reformat(self, data: Dict) -> Dict:
def presentation(key :str, value :Dict):
text = _(" Subvolume :{:16}").format(key)
if isinstance(value,str):
@ -28,14 +29,15 @@ class SubvolumeList(ListManager):
text += _(" with option {}").format(', '.join(value['options']))
return text
return sorted(list(map(lambda x:presentation(x,data[x]),data)))
formatted = {presentation(k, v): k for k, v in data.items()}
return {k: v for k, v in sorted(formatted.items(), key=lambda e: e[0])}
def action_list(self):
return super().action_list()
def exec_action(self, data: Any):
def exec_action(self, data: Dict):
if self.target:
origkey,origval = list(self.target.items())[0]
origkey, origval = list(self.target.items())[0]
else:
origkey = None
@ -46,8 +48,8 @@ class SubvolumeList(ListManager):
self.target = {}
print(_('\n Fill the desired values for a new subvolume \n'))
with SubvolumeMenu(self.target,self.action) as add_menu:
for data in ['name','mountpoint','options']:
add_menu.exec_option(data)
for elem in ['name','mountpoint','options']:
add_menu.exec_option(elem)
else:
SubvolumeMenu(self.target,self.action).run()