Update list manager (#1331)
* Rework partition management * Update * Update list manager * Update * Update Co-authored-by: Daniel Girtler <girtler.daniel@gmail.com>
This commit is contained in:
parent
86531ef62f
commit
5c3c1312a4
|
|
@ -17,14 +17,16 @@ from .btrfs.btrfs_helpers import subvolume_info_from_path
|
|||
from .btrfs.btrfssubvolumeinfo import BtrfsSubvolumeInfo
|
||||
|
||||
class Partition:
|
||||
def __init__(self,
|
||||
def __init__(
|
||||
self,
|
||||
path: str,
|
||||
block_device: BlockDevice,
|
||||
part_id :Optional[str] = None,
|
||||
filesystem :Optional[str] = None,
|
||||
mountpoint :Optional[str] = None,
|
||||
encrypted :bool = False,
|
||||
autodetect_filesystem :bool = True):
|
||||
autodetect_filesystem :bool = True
|
||||
):
|
||||
|
||||
if not part_id:
|
||||
part_id = os.path.basename(path)
|
||||
|
|
@ -76,7 +78,30 @@ class Partition:
|
|||
else:
|
||||
return f'Partition(path={self.path}, size={self.size}, PARTUUID={self._safe_uuid}, fs={self.filesystem}{mount_repr})'
|
||||
|
||||
def as_json(self) -> Dict[str, Any]:
|
||||
"""
|
||||
this is used for the table representation of the partition (see FormattedOutput)
|
||||
"""
|
||||
partition_info = {
|
||||
'type': 'primary',
|
||||
'PARTUUID': self._safe_uuid,
|
||||
'wipe': self.allow_formatting,
|
||||
'boot': self.boot,
|
||||
'ESP': self.boot,
|
||||
'mountpoint': self.target_mountpoint,
|
||||
'encrypted': self._encrypted,
|
||||
'start': self.start,
|
||||
'size': self.end,
|
||||
'filesystem': self.filesystem_type
|
||||
}
|
||||
|
||||
return partition_info
|
||||
|
||||
def __dump__(self) -> Dict[str, Any]:
|
||||
# TODO remove this in favour of as_json
|
||||
|
||||
log(get_filesystem_type(self.path))
|
||||
|
||||
return {
|
||||
'type': 'primary',
|
||||
'PARTUUID': self._safe_uuid,
|
||||
|
|
@ -88,10 +113,14 @@ class Partition:
|
|||
'start': self.start,
|
||||
'size': self.end,
|
||||
'filesystem': {
|
||||
'format': get_filesystem_type(self.path)
|
||||
'format': self.filesystem_type
|
||||
}
|
||||
}
|
||||
|
||||
@property
|
||||
def filesystem_type(self) -> Optional[str]:
|
||||
return get_filesystem_type(self.path)
|
||||
|
||||
@property
|
||||
def mountpoint(self) -> Optional[str]:
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -1,94 +1,7 @@
|
|||
#!/usr/bin/python
|
||||
"""
|
||||
# Purpose
|
||||
ListManager is a widget based on `menu` which allows the handling of repetitive operations in a list.
|
||||
Imagine you have a list and want to add/copy/edit/delete their elements. With this widget you will be shown the list
|
||||
```
|
||||
Vamos alla
|
||||
|
||||
Use ESC to skip
|
||||
|
||||
|
||||
> uno : 1
|
||||
dos : 2
|
||||
tres : 3
|
||||
cuatro : 4
|
||||
==>
|
||||
Confirm and exit
|
||||
Cancel
|
||||
(Press "/" to search)
|
||||
```
|
||||
Once you select one of the elements of the list, you will be promted with the action to be done to the selected element
|
||||
```
|
||||
|
||||
uno : 1
|
||||
dos : 2
|
||||
> tres : 3
|
||||
cuatro : 4
|
||||
==>
|
||||
Confirm and exit
|
||||
Cancel
|
||||
(Press "/" to search)
|
||||
|
||||
Select an action for < {'tres': 3} >
|
||||
|
||||
|
||||
Add
|
||||
Copy
|
||||
Edit
|
||||
Delete
|
||||
> Cancel
|
||||
```
|
||||
You execute the action for this element (which might or not involve user interaction) and return to the list main page
|
||||
till you call one of the options `confirm and exit` which returns the modified list or `cancel` which returns the original list unchanged.
|
||||
If the list is empty one action can be defined as default (usually Add). We call it **null_action**
|
||||
YOu can also define a **default_action** which will appear below the separator, not tied to any element of the list. Barring explicit definition, default_action will be the null_action
|
||||
```
|
||||
==>
|
||||
Add
|
||||
Confirm and exit
|
||||
Cancel
|
||||
(Press "/" to search)
|
||||
```
|
||||
The default implementation can handle simple lists and a key:value dictionary. The default actions are the shown above.
|
||||
A sample of basic usage is included at the end of the source.
|
||||
|
||||
More sophisticaded uses can be achieved by
|
||||
* changing the action list and the null_action during initialization
|
||||
```
|
||||
opciones = ListManager('Vamos alla',opciones,[str(_('Add')),str(_('Delete'))],_('Add')).run()
|
||||
```
|
||||
* And using following methods to overwrite/define user actions and other details:
|
||||
* * `reformat`. To change the appearance of the list elements
|
||||
* * `action_list`. To modify the content of the action list once an element is defined. F.i. to avoid Delete to appear for certain elements, or to add/modify action based in the value of the element.
|
||||
* * `exec_action` which contains the actual code to be executed when an action is selected
|
||||
|
||||
The contents in the base class of this methods serve for a very basic usage, and are to be taken as samples. Thus the best use of this class would be to subclass in your code
|
||||
|
||||
```
|
||||
class ObjectList(archinstall.ListManager):
|
||||
def __init__(prompt,list):
|
||||
self.ObjectAction = [... list of actions ...]
|
||||
self.ObjectNullAction = one ObjectAction
|
||||
super().__init__(prompt,list,ObjectActions,ObjectNullAction)
|
||||
def reformat(self):
|
||||
... beautfy the output of the list
|
||||
def action_list(self):
|
||||
... if you need some changes to the action list based on self.target
|
||||
def exec_action(self):
|
||||
if self.action == self.ObjectAction[0]:
|
||||
performFirstAction(self.target, ...)
|
||||
|
||||
...
|
||||
resultList = ObjectList(prompt,originallist).run()
|
||||
```
|
||||
|
||||
"""
|
||||
import copy
|
||||
from os import system
|
||||
from typing import Union, Any, TYPE_CHECKING, Dict, Optional, Tuple, List
|
||||
from typing import Any, TYPE_CHECKING, Dict, Optional, Tuple, List
|
||||
|
||||
from .text_input import TextInput
|
||||
from .menu import Menu
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -98,58 +11,38 @@ if TYPE_CHECKING:
|
|||
class ListManager:
|
||||
def __init__(
|
||||
self,
|
||||
prompt :str,
|
||||
base_list :Union[list,dict] ,
|
||||
base_actions :list = None,
|
||||
null_action :str = None,
|
||||
default_action :Union[str,list] = None,
|
||||
header :Union[str,list] = None):
|
||||
prompt: str,
|
||||
entries: List[Any],
|
||||
base_actions: List[str],
|
||||
sub_menu_actions: List[str]
|
||||
):
|
||||
"""
|
||||
param :prompt Text which will appear at the header
|
||||
:param prompt: Text which will appear at the header
|
||||
type param: string | DeferredTranslation
|
||||
|
||||
param :base:_list list/dict of option to be shown / mainpulated
|
||||
type param: list | dict
|
||||
|
||||
param base_actions an alternate list of actions to the items of the object
|
||||
:param entries: list/dict of option to be shown / manipulated
|
||||
type param: list
|
||||
|
||||
param: null_action action which will be taken (if any) when base_list is empty
|
||||
type param: string
|
||||
:param base_actions: list of actions that is displayed in the main list manager,
|
||||
usually global actions such as 'Add...'
|
||||
type param: list
|
||||
|
||||
param: default_action action which will be presented at the bottom of the list. Shouldn't need a target. If not present, null_action is set there.
|
||||
Both Null and Default actions can be defined outside the base_actions list, as long as they are launched in exec_action
|
||||
type param: string or list
|
||||
|
||||
param: header one or more header lines for the list
|
||||
type param: string or list
|
||||
:param sub_menu_actions: list of actions available for a chosen entry
|
||||
type param: list
|
||||
"""
|
||||
self._original_data = copy.deepcopy(entries)
|
||||
self._data = copy.deepcopy(entries)
|
||||
|
||||
explainer = str(_('\n Choose an object from the list, and select one of the available actions for it to execute'))
|
||||
self._prompt = prompt + explainer if prompt else explainer
|
||||
|
||||
self._null_action = str(null_action) if null_action else None
|
||||
|
||||
if not default_action:
|
||||
self._default_action = [self._null_action]
|
||||
elif isinstance(default_action,(list,tuple)):
|
||||
self._default_action = default_action
|
||||
else:
|
||||
self._default_action = [str(default_action)]
|
||||
|
||||
self._header = header if header else ''
|
||||
self._cancel_action = str(_('Cancel'))
|
||||
self._confirm_action = str(_('Confirm and exit'))
|
||||
self._separator = ''
|
||||
self._bottom_list = [self._confirm_action, self._cancel_action]
|
||||
self._bottom_item = [self._cancel_action]
|
||||
self._base_actions = base_actions if base_actions else [str(_('Add')), str(_('Copy')), str(_('Edit')), str(_('Delete'))]
|
||||
self._original_data = copy.deepcopy(base_list)
|
||||
self._data = copy.deepcopy(base_list) # as refs, changes are immediate
|
||||
self._confirm_action = str(_('Confirm and exit'))
|
||||
self._cancel_action = str(_('Cancel'))
|
||||
|
||||
# default values for the null case
|
||||
self.target: Optional[Any] = None
|
||||
self.action = self._null_action
|
||||
self._terminate_actions = [self._confirm_action, self._cancel_action]
|
||||
self._base_actions = base_actions
|
||||
self._sub_menu_actions = sub_menu_actions
|
||||
|
||||
def run(self):
|
||||
while True:
|
||||
|
|
@ -158,11 +51,6 @@ class ListManager:
|
|||
data_formatted = self.reformat(self._data)
|
||||
options, header = self._prepare_selection(data_formatted)
|
||||
|
||||
menu_header = self._header
|
||||
|
||||
if header:
|
||||
menu_header += header
|
||||
|
||||
system('clear')
|
||||
|
||||
choice = Menu(
|
||||
|
|
@ -177,27 +65,13 @@ class ListManager:
|
|||
show_search_hint=False
|
||||
).run()
|
||||
|
||||
if not choice.value or choice.value in self._bottom_list:
|
||||
self.action = choice
|
||||
if choice.value in self._base_actions:
|
||||
self._data = self.handle_action(choice.value, None, self._data)
|
||||
elif choice.value in self._terminate_actions:
|
||||
break
|
||||
|
||||
if choice.value and choice.value in self._default_action:
|
||||
self.action = choice.value
|
||||
self.target = None
|
||||
self._data = self.exec_action(self._data)
|
||||
continue
|
||||
|
||||
if isinstance(self._data, dict):
|
||||
data_key = data_formatted[choice.value]
|
||||
key = self._data[data_key]
|
||||
self.target = {data_key: key}
|
||||
elif isinstance(self._data, list):
|
||||
self.target = [d for d in self._data if d == data_formatted[choice.value]][0]
|
||||
else:
|
||||
self.target = self._data[data_formatted[choice.value]]
|
||||
|
||||
# Possible enhancement. If run_actions returns false a message line indicating the failure
|
||||
self.run_actions(choice.value)
|
||||
else: # an entry of the existing selection was choosen
|
||||
selected_entry = data_formatted[choice.value]
|
||||
self._run_actions_on_entry(selected_entry)
|
||||
|
||||
if choice.value == self._cancel_action:
|
||||
return self._original_data # return the original list
|
||||
|
|
@ -217,16 +91,14 @@ class ListManager:
|
|||
if len(options) > 0:
|
||||
options.append(self._separator)
|
||||
|
||||
if self._default_action:
|
||||
# done only for mypy -> todo fix the self._default_action declaration
|
||||
options += [action for action in self._default_action if action]
|
||||
options += self._base_actions
|
||||
options += self._terminate_actions
|
||||
|
||||
options += self._bottom_list
|
||||
return options, header
|
||||
|
||||
def run_actions(self,prompt_data=''):
|
||||
options = self.action_list() + self._bottom_item
|
||||
display_value = self.selected_action_display(self.target) if self.target else prompt_data
|
||||
def _run_actions_on_entry(self, entry: Any):
|
||||
options = self._sub_menu_actions + [self._cancel_action]
|
||||
display_value = self.selected_action_display(entry)
|
||||
|
||||
prompt = _("Select an action for '{}'").format(display_value)
|
||||
|
||||
|
|
@ -236,14 +108,11 @@ class ListManager:
|
|||
sort=False,
|
||||
clear_screen=False,
|
||||
clear_menu_on_exit=False,
|
||||
preset_values=self._bottom_item,
|
||||
show_search_hint=False
|
||||
).run()
|
||||
|
||||
self.action = choice.value
|
||||
|
||||
if self.action and self.action != self._cancel_action:
|
||||
self._data = self.exec_action(self._data)
|
||||
if choice.value and choice.value != self._cancel_action:
|
||||
self._data = self.handle_action(choice.value, entry, self._data)
|
||||
|
||||
def selected_action_display(self, selection: Any) -> str:
|
||||
# this will return the value to be displayed in the
|
||||
|
|
@ -256,64 +125,7 @@ class ListManager:
|
|||
# in the header value (useful when displaying tables)
|
||||
raise NotImplementedError('Please implement me in the child class')
|
||||
|
||||
def action_list(self):
|
||||
"""
|
||||
can define alternate action list or customize the list for each item.
|
||||
Executed after any item is selected, contained in self.target
|
||||
"""
|
||||
active_entry = self.target if self.target else None
|
||||
|
||||
if active_entry is None:
|
||||
return [self._base_actions[0]]
|
||||
else:
|
||||
return self._base_actions[1:]
|
||||
|
||||
def exec_action(self, data: Any):
|
||||
"""
|
||||
what's executed one an item (self.target) and one action (self.action) is selected.
|
||||
Should be overwritten by the user
|
||||
The result is expected to update self._data in this routine, else it is ignored
|
||||
The basic code is useful for simple lists and dictionaries (key:value pairs, both strings)
|
||||
"""
|
||||
# TODO guarantee unicity
|
||||
if isinstance(self._data,list):
|
||||
if self.action == str(_('Add')):
|
||||
self.target = TextInput(_('Add: '),None).run()
|
||||
self._data.append(self.target)
|
||||
if self.action == str(_('Copy')):
|
||||
while True:
|
||||
target = TextInput(_('Copy to: '),self.target).run()
|
||||
if target != self.target:
|
||||
self._data.append(self.target)
|
||||
break
|
||||
elif self.action == str(_('Edit')):
|
||||
tgt = self.target
|
||||
idx = self._data.index(self.target)
|
||||
result = TextInput(_('Edit: '),tgt).run()
|
||||
self._data[idx] = result
|
||||
elif self.action == str(_('Delete')):
|
||||
del self._data[self._data.index(self.target)]
|
||||
elif isinstance(self._data,dict):
|
||||
# allows overwrites
|
||||
if self.target:
|
||||
origkey,origval = list(self.target.items())[0]
|
||||
else:
|
||||
origkey = None
|
||||
origval = None
|
||||
if self.action == str(_('Add')):
|
||||
key = TextInput(_('Key: '),None).run()
|
||||
value = TextInput(_('Value: '),None).run()
|
||||
self._data[key] = value
|
||||
if self.action == str(_('Copy')):
|
||||
while True:
|
||||
key = TextInput(_('Copy to new key:'),origkey).run()
|
||||
if key != origkey:
|
||||
self._data[key] = origval
|
||||
break
|
||||
elif self.action == str(_('Edit')):
|
||||
value = TextInput(_('Edit {}: ').format(origkey), origval).run()
|
||||
self._data[origkey] = value
|
||||
elif self.action == str(_('Delete')):
|
||||
del self._data[origkey]
|
||||
|
||||
return self._data
|
||||
def handle_action(self, action: Any, entry: Optional[Any], data: List[Any]) -> List[Any]:
|
||||
# this function is called when a base action or
|
||||
# a specific action for an entry is triggered
|
||||
raise NotImplementedError('Please implement me in the child class')
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class UserList(ListManager):
|
|||
str(_('Promote/Demote user')),
|
||||
str(_('Delete User'))
|
||||
]
|
||||
super().__init__(prompt, lusers, self._actions, self._actions[0])
|
||||
super().__init__(prompt, lusers, [self._actions[0]], self._actions[1:])
|
||||
|
||||
def reformat(self, data: List[User]) -> Dict[str, User]:
|
||||
table = FormattedOutput.as_table(data)
|
||||
|
|
@ -45,27 +45,25 @@ class UserList(ListManager):
|
|||
def selected_action_display(self, user: User) -> str:
|
||||
return user.username
|
||||
|
||||
def exec_action(self, data: List[User]) -> List[User]:
|
||||
active_user = self.target if self.target else None
|
||||
|
||||
if self.action == self._actions[0]: # add
|
||||
def handle_action(self, action: str, entry: Optional[User], data: List[User]) -> List[User]:
|
||||
if action == self._actions[0]: # add
|
||||
new_user = self._add_user()
|
||||
if new_user 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.username != new_user.username]
|
||||
data += [new_user]
|
||||
elif self.action == self._actions[1]: # change password
|
||||
prompt = str(_('Password for user "{}": ').format(active_user.username))
|
||||
elif action == self._actions[1]: # change password
|
||||
prompt = str(_('Password for user "{}": ').format(entry.username))
|
||||
new_password = get_password(prompt=prompt)
|
||||
if new_password:
|
||||
user = next(filter(lambda x: x == active_user, data), 1)
|
||||
user = next(filter(lambda x: x == entry, data), 1)
|
||||
user.password = new_password
|
||||
elif self.action == self._actions[2]: # promote/demote
|
||||
user = next(filter(lambda x: x == active_user, data), 1)
|
||||
elif action == self._actions[2]: # promote/demote
|
||||
user = next(filter(lambda x: x == entry, data), 1)
|
||||
user.sudo = False if user.sudo else True
|
||||
elif self.action == self._actions[3]: # delete
|
||||
data = [d for d in data if d != active_user]
|
||||
elif action == self._actions[3]: # delete
|
||||
data = [d for d in data if d != entry]
|
||||
|
||||
return data
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class ManualNetworkConfig(ListManager):
|
|||
str(_('Delete interface'))
|
||||
]
|
||||
|
||||
super().__init__(prompt, ifaces, self._actions, self._actions[0])
|
||||
super().__init__(prompt, ifaces, [self._actions[0]], self._actions[1:])
|
||||
|
||||
def reformat(self, data: List[NetworkConfiguration]) -> Dict[str, Optional[NetworkConfiguration]]:
|
||||
table = FormattedOutput.as_table(data)
|
||||
|
|
@ -49,21 +49,19 @@ class ManualNetworkConfig(ListManager):
|
|||
def selected_action_display(self, iface: NetworkConfiguration) -> str:
|
||||
return iface.iface if iface.iface else ''
|
||||
|
||||
def exec_action(self, data: List[NetworkConfiguration]):
|
||||
active_iface: Optional[NetworkConfiguration] = self.target if self.target else None
|
||||
|
||||
if self.action == self._actions[0]: # add
|
||||
def handle_action(self, action: str, entry: Optional[NetworkConfiguration], data: List[NetworkConfiguration]):
|
||||
if action == self._actions[0]: # add
|
||||
iface_name = self._select_iface(data)
|
||||
if iface_name:
|
||||
iface = NetworkConfiguration(NicType.MANUAL, iface=iface_name)
|
||||
iface = self._edit_iface(iface)
|
||||
data += [iface]
|
||||
elif active_iface:
|
||||
if self.action == self._actions[1]: # edit interface
|
||||
data = [d for d in data if d.iface != active_iface.iface]
|
||||
data.append(self._edit_iface(active_iface))
|
||||
elif self.action == self._actions[2]: # delete
|
||||
data = [d for d in data if d != active_iface]
|
||||
elif entry:
|
||||
if action == self._actions[1]: # edit interface
|
||||
data = [d for d in data if d.iface != entry.iface]
|
||||
data.append(self._edit_iface(entry))
|
||||
elif action == self._actions[2]: # delete
|
||||
data = [d for d in data if d != entry]
|
||||
|
||||
return data
|
||||
|
||||
|
|
|
|||
|
|
@ -154,9 +154,6 @@ def manage_new_and_existing_partitions(block_device: 'BlockDevice') -> Dict[str,
|
|||
block_device_struct = {"partitions": [partition.__dump__() for partition in block_device.partitions.values()]}
|
||||
original_layout = copy.deepcopy(block_device_struct)
|
||||
|
||||
# Test code: [part.__dump__() for part in block_device.partitions.values()]
|
||||
# TODO: Squeeze in BTRFS subvolumes here
|
||||
|
||||
new_partition = str(_('Create a new partition'))
|
||||
suggest_partition_layout = str(_('Suggest partition layout'))
|
||||
delete_partition = str(_('Delete a partition'))
|
||||
|
|
@ -209,6 +206,7 @@ def manage_new_and_existing_partitions(block_device: 'BlockDevice') -> Dict[str,
|
|||
return original_layout
|
||||
elif task == save_and_exit:
|
||||
break
|
||||
|
||||
if task == new_partition:
|
||||
from ..disk import valid_parted_position
|
||||
|
||||
|
|
@ -222,8 +220,9 @@ def manage_new_and_existing_partitions(block_device: 'BlockDevice') -> Dict[str,
|
|||
if fs_choice.type_ == MenuSelectionType.Esc:
|
||||
continue
|
||||
|
||||
prompt = _('Enter the start sector (percentage or block number, default: {}): ').format(
|
||||
block_device.first_free_sector)
|
||||
prompt = str(_('Enter the start sector (percentage or block number, default: {}): ')).format(
|
||||
block_device.first_free_sector
|
||||
)
|
||||
start = input(prompt).strip()
|
||||
|
||||
if not start.strip():
|
||||
|
|
@ -232,8 +231,9 @@ def manage_new_and_existing_partitions(block_device: 'BlockDevice') -> Dict[str,
|
|||
else:
|
||||
end_suggested = '100%'
|
||||
|
||||
prompt = _('Enter the end sector of the partition (percentage or block number, ex: {}): ').format(
|
||||
end_suggested)
|
||||
prompt = str(_('Enter the end sector of the partition (percentage or block number, ex: {}): ')).format(
|
||||
end_suggested
|
||||
)
|
||||
end = input(prompt).strip()
|
||||
|
||||
if not end.strip():
|
||||
|
|
|
|||
|
|
@ -12,13 +12,13 @@ if TYPE_CHECKING:
|
|||
|
||||
|
||||
class SubvolumeList(ListManager):
|
||||
def __init__(self, prompt: str, current_volumes: List[Subvolume]):
|
||||
def __init__(self, prompt: str, subvolumes: List[Subvolume]):
|
||||
self._actions = [
|
||||
str(_('Add subvolume')),
|
||||
str(_('Edit subvolume')),
|
||||
str(_('Delete subvolume'))
|
||||
]
|
||||
super().__init__(prompt, current_volumes, self._actions, self._actions[0])
|
||||
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)
|
||||
|
|
@ -75,13 +75,8 @@ class SubvolumeList(ListManager):
|
|||
|
||||
return subvolume
|
||||
|
||||
def exec_action(self, data: List[Subvolume]) -> List[Subvolume]:
|
||||
if self.target:
|
||||
active_subvolume = self.target
|
||||
else:
|
||||
active_subvolume = None
|
||||
|
||||
if self.action == self._actions[0]: # add
|
||||
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:
|
||||
|
|
@ -89,14 +84,15 @@ class SubvolumeList(ListManager):
|
|||
# was created we'll replace the existing one
|
||||
data = [d for d in data if d.name != new_subvolume.name]
|
||||
data += [new_subvolume]
|
||||
elif self.action == self._actions[1]: # edit subvolume
|
||||
new_subvolume = self._add_subvolume(active_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 != active_subvolume.name and d.name != new_subvolume.name]
|
||||
data += [new_subvolume]
|
||||
elif self.action == self._actions[2]: # delete
|
||||
data = [d for d in data if d != active_subvolume]
|
||||
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
|
||||
|
|
|
|||
Loading…
Reference in New Issue