Add "Fresh start" menu entry to ddrescue-tui

Addresses issue #15
This commit is contained in:
2Shirt 2022-02-20 20:22:25 -07:00
parent abd1855bc9
commit 0e4ee42f28
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C

View file

@ -82,6 +82,7 @@ MENU_ACTIONS = (
'Add Tech Note',
f'Change settings {std.color_string("(experts only)", "YELLOW")}',
f'Detect drives {std.color_string("(experts only)", "YELLOW")}',
f'Fresh start {std.color_string("(experts only)", "YELLOW")}',
'Quit')
MENU_TOGGLES = {
'Auto continue (if recovery % over threshold)': True,
@ -254,6 +255,22 @@ class BlockPair():
# Done
return complete
def reset_progress(self):
"""Reset progress to start fresh recovery."""
self.map_data = {}
self.status = OrderedDict({
'read': 'Pending',
'trim': 'Pending',
'scrape': 'Pending',
})
if 'DISPLAY' in os.environ or 'WAYLAND_DISPLAY' in os.environ:
# Enable opening ddrescueview during recovery
self.view_proc = None
self.map_path.touch()
# Set initial status
self.set_initial_status()
def safety_check(self):
"""Run safety check and abort if necessary."""
dest_size = -1
@ -742,7 +759,7 @@ class State():
# Start fresh if requested
if docopt_args['--start-fresh']:
clean_working_dir(self.working_dir)
clean_working_dir(self)
# Add block pairs
if self.mode == 'Clone':
@ -1527,23 +1544,46 @@ def check_destination_health(destination):
return result
def clean_working_dir(working_dir):
def clean_working_dir(state, confirm=False):
"""Clean working directory to ensure a fresh recovery session.
NOTE: Data from previous sessions will be preserved
in a backup directory.
"""
backup_dir = pathlib.Path(f'{working_dir}/prev')
backup_dir = pathlib.Path(f'{state.working_dir}/prev')
backup_dir = io.non_clobber_path(backup_dir)
backup_dir.mkdir()
# Confirm
if confirm:
std.print_error(
'This will reset all progress and create new map file(s).',
)
std.print_warning(
"Please only proceed if you understand what you're doing!",
)
std.print_warning(
'NOTE: This will keep the current partition selection(s).',
)
if not std.ask('Continue?'):
return
# Move settings, maps, etc to backup_dir
for entry in os.scandir(working_dir):
backup_dir.mkdir()
for entry in os.scandir(state.working_dir):
if entry.name.endswith(('.dd', '.json', '.map')):
if confirm and entry.name.endswith('.json'):
# Keep JSON settings if using the menu option
continue
new_path = f'{backup_dir}/{entry.name}'
new_path = io.non_clobber_path(new_path)
shutil.move(entry.path, new_path)
# Update block pairs (if using the menu option)
if confirm:
for block_pair in state.block_pairs:
block_pair.reset_progress()
state.update_progress_pane('Idle')
def detect_drives(state):
"""Detect connected drives and check source/dest selections."""
@ -1932,6 +1972,10 @@ def main():
)
state.update_top_panes()
# Start over
if 'Fresh start' in selection[0]:
clean_working_dir(state, confirm=True)
# Start recovery
if 'Start' in selection:
std.clear_screen()