Consolidated device selection code
* Common code moved to select_device() * Existing select_device() renamed menu_select_device() * Fixed skip_device code * Refactored source/dest vars into dicts * Added confirmation after source/dest are selected
This commit is contained in:
parent
b2fc7ea860
commit
e56296d8b0
1 changed files with 69 additions and 60 deletions
|
|
@ -75,69 +75,35 @@ def menu_clone(source_path, dest_path):
|
||||||
source_is_image = False
|
source_is_image = False
|
||||||
source_dev_path = None
|
source_dev_path = None
|
||||||
print_success('GNU ddrescue: Cloning Menu')
|
print_success('GNU ddrescue: Cloning Menu')
|
||||||
|
|
||||||
# Select source if not preselected
|
# Set devices
|
||||||
if not source_path:
|
source = select_device('source', source_path)
|
||||||
source_path = select_device('Please select a source device')
|
dest = select_device('destination', dest_path,
|
||||||
|
skip_device = source['Details'], allow_image_file = False)
|
||||||
# Check source
|
|
||||||
source_path = os.path.realpath(source_path)
|
|
||||||
if pathlib.Path(source_path).is_block_device():
|
|
||||||
source_dev_path = source_path
|
|
||||||
elif pathlib.Path(source_path).is_file():
|
|
||||||
source_dev_path = setup_loopback_device(source_path)
|
|
||||||
source_is_image = True
|
|
||||||
else:
|
|
||||||
print_error('Invalid source "{}".'.format(source_path))
|
|
||||||
abort()
|
|
||||||
source_details = get_device_details(source_dev_path)
|
|
||||||
|
|
||||||
# Check source type
|
|
||||||
if source_details['pkname']:
|
|
||||||
print_warning('Source "{}" is a child device.'.format(source_dev_path))
|
|
||||||
if ask('Use parent device "{}" instead?'.format(
|
|
||||||
source_details['pkname'])):
|
|
||||||
source_dev_path = source_details['pkname']
|
|
||||||
source_details = get_device_details(source_dev_path)
|
|
||||||
print_standard(' ')
|
|
||||||
|
|
||||||
# Select destination if not preselected
|
|
||||||
if not dest_path:
|
|
||||||
dest_path = select_device(
|
|
||||||
'Please select a destination device',
|
|
||||||
skip_device=source_details)
|
|
||||||
|
|
||||||
# Check destination
|
|
||||||
dest_path = os.path.realpath(dest_path)
|
|
||||||
if pathlib.Path(dest_path).is_block_device():
|
|
||||||
dest_dev_path = dest_path
|
|
||||||
else:
|
|
||||||
print_error('Invalid destination "{}".'.format(dest_path))
|
|
||||||
abort()
|
|
||||||
dest_details = get_device_details(dest_dev_path)
|
|
||||||
|
|
||||||
# Check destination type
|
|
||||||
if dest_details['pkname']:
|
|
||||||
print_warning('Destination "{}" is a child device.'.format(dest_dev_path))
|
|
||||||
if ask('Use parent device "{}" instead?'.format(
|
|
||||||
dest_details['pkname'])):
|
|
||||||
dest_dev_path = dest_details['pkname']
|
|
||||||
dest_details = get_device_details(dest_dev_path)
|
|
||||||
print_standard(' ')
|
|
||||||
|
|
||||||
# Show selection details
|
# Show selection details
|
||||||
|
clear_screen()
|
||||||
print_success('Source device')
|
print_success('Source device')
|
||||||
if source_is_image:
|
if source['Is Image']:
|
||||||
print_standard('Using image file: {}'.format(source_path))
|
print_standard('Using image file: {}'.format(source['Path']))
|
||||||
print_standard(' (via loopback device: {})'.format(
|
print_standard(' (via loopback device: {})'.format(
|
||||||
source_dev_path))
|
source['Dev Path']))
|
||||||
show_device_details(source_dev_path)
|
show_device_details(source['Dev Path'])
|
||||||
print_standard(' ')
|
print_standard(' ')
|
||||||
|
|
||||||
print_success('Destination device')
|
print_success('Destination device ', end='')
|
||||||
show_device_details(dest_dev_path)
|
print_error('(ALL DATA WILL BE DELETED)', timestamp=False)
|
||||||
|
show_device_details(dest['Dev Path'])
|
||||||
print_standard(' ')
|
print_standard(' ')
|
||||||
|
|
||||||
|
# Confirm
|
||||||
|
if not ask('Proceed with clone?'):
|
||||||
|
abort()
|
||||||
|
|
||||||
|
# Build outer panes
|
||||||
|
clear_screen()
|
||||||
|
#TODO
|
||||||
|
|
||||||
def menu_ddrescue(*args):
|
def menu_ddrescue(*args):
|
||||||
"""Main ddrescue loop/menu."""
|
"""Main ddrescue loop/menu."""
|
||||||
args = list(args)
|
args = list(args)
|
||||||
|
|
@ -171,8 +137,53 @@ def menu_image(source_path, dest_path):
|
||||||
print_success('GNU ddrescue: Imaging Menu')
|
print_success('GNU ddrescue: Imaging Menu')
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def select_device(title='Which device?', skip_device={}):
|
def select_device(description='device', provided_path=None,
|
||||||
|
skip_device={}, allow_image_file=True):
|
||||||
|
"""Select device via provided path or menu, return dev as dict."""
|
||||||
|
dev = {'Is Image': False}
|
||||||
|
|
||||||
|
# Set path
|
||||||
|
if provided_path:
|
||||||
|
dev['Path'] = provided_path
|
||||||
|
else:
|
||||||
|
dev['Path'] = menu_select_device(
|
||||||
|
title='Please select a {}'.format(description),
|
||||||
|
skip_device=skip_device)
|
||||||
|
dev['Path'] = os.path.realpath(dev['Path'])
|
||||||
|
|
||||||
|
# Check path
|
||||||
|
if pathlib.Path(dev['Path']).is_block_device():
|
||||||
|
dev['Dev Path'] = dev['Path']
|
||||||
|
elif allow_image_file and pathlib.Path(dev['Path']).is_file():
|
||||||
|
dev['Dev Path'] = setup_loopback_device(dev['Path'])
|
||||||
|
dev['Is Image'] = True
|
||||||
|
else:
|
||||||
|
print_error('Invalid {} "{}".'.format(description, dev['Path']))
|
||||||
|
abort()
|
||||||
|
|
||||||
|
# Get device details
|
||||||
|
dev['Details'] = get_device_details(dev['Dev Path'])
|
||||||
|
|
||||||
|
# Check for parent device(s)
|
||||||
|
while dev['Details']['pkname']:
|
||||||
|
print_warning('{} "{}" is a child device.'.format(
|
||||||
|
description.title(), dev['Dev Path']))
|
||||||
|
if ask('Use parent device "{}" instead?'.format(
|
||||||
|
dev['Details']['pkname'])):
|
||||||
|
# Update dev with parent info
|
||||||
|
dev['Dev Path'] = dev['Details']['pkname']
|
||||||
|
dev['Details'] = get_device_details(dev['Dev Path'])
|
||||||
|
else:
|
||||||
|
# Leave alone
|
||||||
|
break
|
||||||
|
|
||||||
|
return dev
|
||||||
|
|
||||||
|
def menu_select_device(title='Which device?', skip_device={}):
|
||||||
"""Select block device via a menu, returns dev_path as str."""
|
"""Select block device via a menu, returns dev_path as str."""
|
||||||
|
skip_names = [
|
||||||
|
skip_device.get('name', None), skip_device.get('pkname', None)]
|
||||||
|
skip_names = [n for n in skip_names if n]
|
||||||
try:
|
try:
|
||||||
cmd = (
|
cmd = (
|
||||||
'lsblk',
|
'lsblk',
|
||||||
|
|
@ -189,10 +200,8 @@ def select_device(title='Which device?', skip_device={}):
|
||||||
# Build menu
|
# Build menu
|
||||||
dev_options = []
|
dev_options = []
|
||||||
for dev in json_data['blockdevices']:
|
for dev in json_data['blockdevices']:
|
||||||
# Skip if dev in skip_device
|
# Skip if dev is in skip_names
|
||||||
dev_names = [dev['name'], dev['pkname']]
|
if dev['name'] in skip_names or dev['pkname'] in skip_names:
|
||||||
dev_names = [n for n in dev_names if n]
|
|
||||||
if skip_device and skip_device.get('name', None) in dev_names:
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Append non-matching devices
|
# Append non-matching devices
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue