Updated ddrescue menu sections
* Support loading presets
This commit is contained in:
parent
045d2b2571
commit
3a8c052d5a
3 changed files with 72 additions and 26 deletions
|
|
@ -24,17 +24,32 @@ TMUX_LAYOUT = OrderedDict({
|
||||||
AUTO_PASS_1_THRESHOLD = 95
|
AUTO_PASS_1_THRESHOLD = 95
|
||||||
AUTO_PASS_2_THRESHOLD = 98
|
AUTO_PASS_2_THRESHOLD = 98
|
||||||
DDRESCUE_SETTINGS = {
|
DDRESCUE_SETTINGS = {
|
||||||
'--binary-prefixes': {'Enabled': True, 'Hidden': True, },
|
'Default': {
|
||||||
'--data-preview': {'Enabled': True, 'Value': '5', 'Hidden': True, },
|
'--binary-prefixes': {'Selected': True, 'Hidden': True, },
|
||||||
'--idirect': {'Enabled': True, },
|
'--data-preview': {'Selected': True, 'Value': '5', 'Hidden': True, },
|
||||||
'--odirect': {'Enabled': True, },
|
'--idirect': {'Selected': True, },
|
||||||
'--max-read-rate': {'Enabled': False, 'Value': '1MiB', },
|
'--odirect': {'Selected': True, },
|
||||||
'--min-read-rate': {'Enabled': True, 'Value': '64KiB', },
|
'--max-error-rate': {'Selected': True, 'Value': '100MiB', },
|
||||||
'--reopen-on-error': {'Enabled': True, },
|
'--max-read-rate': {'Selected': False, 'Value': '1MiB', },
|
||||||
'--retry-passes': {'Enabled': True, 'Value': '0', },
|
'--min-read-rate': {'Selected': True, 'Value': '64KiB', },
|
||||||
'--test-mode': {'Enabled': False, 'Value': 'test.map', },
|
'--reopen-on-error': {'Selected': True, },
|
||||||
'--timeout': {'Enabled': True, 'Value': '5m', },
|
'--retry-passes': {'Selected': True, 'Value': '0', },
|
||||||
'-vvvv': {'Enabled': True, 'Hidden': True, },
|
'--test-mode': {'Selected': False, 'Value': 'test.map', },
|
||||||
|
'--timeout': {'Selected': True, 'Value': '30m', },
|
||||||
|
'-vvvv': {'Selected': True, 'Hidden': True, },
|
||||||
|
},
|
||||||
|
'Fast': {
|
||||||
|
'--max-error-rate': {'Selected': True, 'Value': '32MiB', },
|
||||||
|
'--min-read-rate': {'Selected': True, 'Value': '1MiB', },
|
||||||
|
'--reopen-on-error': {'Selected': False, },
|
||||||
|
'--timeout': {'Selected': True, 'Value': '5m', },
|
||||||
|
},
|
||||||
|
'Safe': {
|
||||||
|
'--max-read-rate': {'Selected': True, 'Value': '64MiB', },
|
||||||
|
'--min-read-rate': {'Selected': True, 'Value': '1KiB', },
|
||||||
|
'--reopen-on-error': {'Selected': True, },
|
||||||
|
'--timeout': {'Selected': False, 'Value': '30m', },
|
||||||
|
},
|
||||||
}
|
}
|
||||||
ETOC_REFRESH_RATE = 30 # in seconds
|
ETOC_REFRESH_RATE = 30 # in seconds
|
||||||
REGEX_DDRESCUE_LOG = re.compile(
|
REGEX_DDRESCUE_LOG = re.compile(
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ Options:
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
MENU_ACTIONS = (
|
MENU_ACTIONS = (
|
||||||
'Start',
|
'Start',
|
||||||
std.color_string(['Change settings', '(experts only)'], [None, 'YELLOW']),
|
f'Change settings {std.color_string("(experts only)", "YELLOW")}',
|
||||||
'Quit')
|
'Quit')
|
||||||
MENU_TOGGLES = {
|
MENU_TOGGLES = {
|
||||||
'Auto continue (if recovery % over threshold)': True,
|
'Auto continue (if recovery % over threshold)': True,
|
||||||
|
|
@ -46,6 +46,11 @@ PANE_RATIOS = (
|
||||||
22, # ddrescue progress
|
22, # ddrescue progress
|
||||||
4, # Journal (kernel messages)
|
4, # Journal (kernel messages)
|
||||||
)
|
)
|
||||||
|
SETTING_PRESETS = (
|
||||||
|
'Default',
|
||||||
|
'Fast',
|
||||||
|
'Safe',
|
||||||
|
)
|
||||||
STATUS_COLORS = {
|
STATUS_COLORS = {
|
||||||
'Passed': 'GREEN',
|
'Passed': 'GREEN',
|
||||||
'Aborted': 'YELLOW',
|
'Aborted': 'YELLOW',
|
||||||
|
|
@ -214,21 +219,20 @@ class State():
|
||||||
def build_main_menu():
|
def build_main_menu():
|
||||||
"""Build main menu, returns wk.std.Menu."""
|
"""Build main menu, returns wk.std.Menu."""
|
||||||
menu = std.Menu(title=std.color_string('ddrescue TUI: Main Menu', 'GREEN'))
|
menu = std.Menu(title=std.color_string('ddrescue TUI: Main Menu', 'GREEN'))
|
||||||
|
menu.separator = ' '
|
||||||
|
|
||||||
# Add actions, options, etc
|
# Add actions, options, etc
|
||||||
for action in MENU_ACTIONS:
|
for action in MENU_ACTIONS:
|
||||||
menu.add_action(action)
|
menu.add_action(action)
|
||||||
for toggle, selected in MENU_TOGGLES.items():
|
for toggle, selected in MENU_TOGGLES.items():
|
||||||
menu.add_toggle(toggle, {'Selected': selected})
|
menu.add_toggle(toggle, {'Selected': selected})
|
||||||
menu.actions['Start']['Separator'] = True
|
|
||||||
|
|
||||||
# Done
|
# Done
|
||||||
return menu
|
return menu
|
||||||
|
|
||||||
|
|
||||||
def build_settings_menu():
|
def build_settings_menu(silent=True):
|
||||||
"""Build settings menu, returns wk.std.Menu."""
|
"""Build settings menu, returns wk.std.Menu."""
|
||||||
#TODO Fixme
|
|
||||||
title_text = [
|
title_text = [
|
||||||
std.color_string('ddrescue TUI: Exper Settings', 'GREEN'),
|
std.color_string('ddrescue TUI: Exper Settings', 'GREEN'),
|
||||||
' ',
|
' ',
|
||||||
|
|
@ -238,13 +242,29 @@ def build_settings_menu():
|
||||||
),
|
),
|
||||||
'Please read the manual before making changes',
|
'Please read the manual before making changes',
|
||||||
]
|
]
|
||||||
menu = std.Menu(title='\n'join(title_text))
|
menu = std.Menu(title='\n'.join(title_text))
|
||||||
|
menu.separator = ' '
|
||||||
|
preset = 'Default'
|
||||||
|
if not silent:
|
||||||
|
# Ask which preset to use
|
||||||
|
print(f'Available ddrescue presets: {" / ".join(SETTING_PRESETS)}')
|
||||||
|
preset = std.choice(SETTING_PRESETS, 'Please select a preset:')
|
||||||
|
|
||||||
# Add actions, options, etc
|
# Fix selection
|
||||||
|
for _p in SETTING_PRESETS:
|
||||||
|
if _p.startswith(preset):
|
||||||
|
preset = _p
|
||||||
|
|
||||||
|
# Add default settings
|
||||||
menu.add_action('Main Menu')
|
menu.add_action('Main Menu')
|
||||||
for name, details in cfg.ddrescue.DDRESCUE_SETTINGS.items():
|
menu.add_action('Load Preset')
|
||||||
menu.add_option(name, details)
|
for name, details in cfg.ddrescue.DDRESCUE_SETTINGS['Default'].items():
|
||||||
menu.actions['Main Menu']['Separator'] = True
|
menu.add_option(name, details.copy())
|
||||||
|
|
||||||
|
# Update settings using preset
|
||||||
|
if preset != 'Default':
|
||||||
|
for name, details in cfg.ddrescue.DDRESCUE_SETTINGS[preset].items():
|
||||||
|
menu.options[name].update(details.copy())
|
||||||
|
|
||||||
# Done
|
# Done
|
||||||
return menu
|
return menu
|
||||||
|
|
@ -270,11 +290,21 @@ def main():
|
||||||
# Show menu
|
# Show menu
|
||||||
while True:
|
while True:
|
||||||
action = None
|
action = None
|
||||||
selection = menu.advanced_select()
|
selection = main_menu.advanced_select()
|
||||||
|
|
||||||
# Start diagnostics
|
# Change settings
|
||||||
|
if 'Change settings' in selection[0]:
|
||||||
|
while True:
|
||||||
|
selection = settings_menu.settings_select()
|
||||||
|
if 'Load Preset' in selection:
|
||||||
|
# Rebuild settings menu using preset
|
||||||
|
settings_menu = build_settings_menu(silent=False)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
# Start recovery
|
||||||
if 'Start' in selection:
|
if 'Start' in selection:
|
||||||
run_diags(state, menu, quick_mode=False)
|
run_recovery(state, main_menu, settings_menu)
|
||||||
|
|
||||||
# Quit
|
# Quit
|
||||||
if 'Quit' in selection:
|
if 'Quit' in selection:
|
||||||
|
|
|
||||||
|
|
@ -128,9 +128,10 @@ class Menu():
|
||||||
menu_lines = [str(line) for line in menu_lines]
|
menu_lines = [str(line) for line in menu_lines]
|
||||||
return '\n'.join(menu_lines)
|
return '\n'.join(menu_lines)
|
||||||
|
|
||||||
def _get_display_name(self, name, details,
|
def _get_display_name(
|
||||||
|
self, name, details,
|
||||||
index=None, no_checkboxes=True, setting_item=False):
|
index=None, no_checkboxes=True, setting_item=False):
|
||||||
# pylint: disable=no-self-use
|
# pylint: disable=no-self-use,too-many-arguments
|
||||||
"""Format display name based on details and args, returns str."""
|
"""Format display name based on details and args, returns str."""
|
||||||
disabled = details.get('Disabled', False)
|
disabled = details.get('Disabled', False)
|
||||||
if setting_item and not details['Selected']:
|
if setting_item and not details['Selected']:
|
||||||
|
|
@ -372,7 +373,7 @@ class Menu():
|
||||||
if user_selection.isnumeric():
|
if user_selection.isnumeric():
|
||||||
if 'Value' in selected_entry[-1] and choice(**choice_kwargs) == 'C':
|
if 'Value' in selected_entry[-1] and choice(**choice_kwargs) == 'C':
|
||||||
# Change
|
# Change
|
||||||
selected_entry[-1[-1]]['Value'] = input_text('Enter new value: ')
|
selected_entry[-1]['Value'] = input_text('Enter new value: ')
|
||||||
else:
|
else:
|
||||||
# Toggle
|
# Toggle
|
||||||
self._update_entry_selection_status(selected_entry[0])
|
self._update_entry_selection_status(selected_entry[0])
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue