From 1f63f911447a5397c2d41478222fa7db31f9d703 Mon Sep 17 00:00:00 2001 From: Alan Mason <2xShirt@gmail.com> Date: Sun, 22 Jul 2018 16:27:34 -0600 Subject: [PATCH] PEP8 Cleanup --- .bin/Scripts/functions/ddrescue.py | 297 ++++++++++++++++------------- 1 file changed, 169 insertions(+), 128 deletions(-) diff --git a/.bin/Scripts/functions/ddrescue.py b/.bin/Scripts/functions/ddrescue.py index 5656c212..ca0d94a3 100644 --- a/.bin/Scripts/functions/ddrescue.py +++ b/.bin/Scripts/functions/ddrescue.py @@ -13,7 +13,7 @@ from functions.data import * from operator import itemgetter # STATIC VARIABLES -AUTHORIZED_DEST_FSTYPES = ['ext3', 'ext4', 'xfs'] +RECOMMENDED_FSTYPES = ['ext3', 'ext4', 'xfs'] AUTO_NEXT_PASS_1_THRESHOLD = 85 AUTO_NEXT_PASS_2_THRESHOLD = 98 DDRESCUE_SETTINGS = { @@ -36,41 +36,45 @@ USAGE = """ {script_name} clone [source [destination]] (e.g. {script_name} clone /dev/sda /dev/sdb) """ + # Functions def abort_ddrescue_tui(): run_program(['losetup', '-D']) abort() + def build_outer_panes(source, dest): """Build top and side panes.""" clear_screen() - + # Top panes source_pane = tmux_splitw( '-bdvl', '2', '-PF', '#D', 'echo-and-hold "{BLUE}Source{CLEAR}\n{text}"'.format( - text = source['Display Name'], + text=source['Display Name'], **COLORS)) tmux_splitw( '-t', source_pane, '-dhl', '21', 'echo-and-hold "{BLUE}Started{CLEAR}\n{text}"'.format( - text = time.strftime("%Y-%m-%d %H:%M %Z"), + text=time.strftime("%Y-%m-%d %H:%M %Z"), **COLORS)) tmux_splitw( '-t', source_pane, '-dhp', '50', 'echo-and-hold "{BLUE}Destination{CLEAR}\n{text}"'.format( - text = dest['Display Name'], + text=dest['Display Name'], **COLORS)) - + # Side pane update_progress(source) - tmux_splitw('-dhl', '21', + tmux_splitw( + '-dhl', '21', 'watch', '--color', '--no-title', '--interval', '1', 'cat', source['Progress Out']) + def check_dest_paths(source): """Check for image and/or map file and alert user about details.""" dd_image_exists = os.path.exists(source['Dest Paths']['Image']) @@ -112,11 +116,13 @@ def check_dest_paths(source): if abort_imaging or (resume_files_exist and not ask(p)): abort_ddrescue_tui() + def dest_safety_check(source, dest): """Verify the destination is appropriate for the source.""" source_size = source['Details']['size'] if dest['Is Dir']: - cmd = ['findmnt', '-J', + cmd = [ + 'findmnt', '-J', '-o', 'SOURCE,TARGET,FSTYPE,OPTIONS,SIZE,AVAIL,USED', '-T', dest['Path']] result = run_program(cmd) @@ -141,27 +147,29 @@ def dest_safety_check(source, dest): # Imaging: ensure 120% of source size is available print_error( 'Not enough free space on destination, refusing to continue.') - print_standard(' Dest {d_size} < Required {s_size}'.format( - d_size = human_readable_size(dest_size), - s_size = human_readable_size(source_size * 1.2))) + print_standard( + ' Dest {d_size} < Required {s_size}'.format( + d_size=human_readable_size(dest_size), + s_size=human_readable_size(source_size * 1.2))) abort_ddrescue_tui() elif source['Type'] == 'Clone' and source_size > dest_size: # Cloning: ensure dest >= size print_error('Destination is too small, refusing to continue.') - print_standard(' Dest {d_size} < Source {s_size}'.format( - d_size = human_readable_size(dest_size), - s_size = human_readable_size(source_size))) + print_standard( + ' Dest {d_size} < Source {s_size}'.format( + d_size=human_readable_size(dest_size), + s_size=human_readable_size(source_size))) abort_ddrescue_tui() # Imaging specific checks if source['Type'] == 'Image': # Filesystem Type - if dest['Filesystem'] not in AUTHORIZED_DEST_FSTYPES: + if dest['Filesystem'] not in RECOMMENDED_FSTYPES: print_error( - 'Destination filesystem "{}" is not a recommended type.'.format( - dest['Filesystem'])) - print_info('Authorized types are: {}'.format( - ' / '.join(AUTHORIZED_DEST_FSTYPES).upper())) + 'Destination filesystem "{}" is not recommended.'.format( + dest['Filesystem'])) + print_info('Recommended types are: {}'.format( + ' / '.join(RECOMMENDED_FSTYPES).upper())) print_standard(' ') if not ask('Proceed anyways? (Strongly discouraged)'): abort_ddrescue_tui() @@ -174,13 +182,14 @@ def dest_safety_check(source, dest): if not dest_ok: print_error('Destination is not writable, refusing to continue.') abort_ddrescue_tui() - + # Mount options check if 'rw' not in dest['Mount options'].split(','): print_error( 'Destination is not mounted read-write, refusing to continue.') abort_ddrescue_tui() + def get_device_details(dev_path): """Get device details via lsblk, returns JSON dict.""" try: @@ -199,11 +208,13 @@ def get_device_details(dev_path): # Just return the first device (there should only be one) return json_data['blockdevices'][0] + def get_device_size_in_bytes(s): """Convert size string from lsblk string to bytes, returns int.""" s = re.sub(r'(\d+\.?\d*)\s*([KMGTB])B?', r'\1 \2B', s, re.IGNORECASE) return convert_to_bytes(s) + def get_recovery_scope_size(source): """Calculate total size of selected dev(s).""" source['Total Size'] = 0 @@ -216,6 +227,7 @@ def get_recovery_scope_size(source): source['Size'] = get_device_size_in_bytes(source['Details']['size']) source['Total Size'] = source['Size'] + def get_status_color(s, t_success=99, t_warn=90): """Get color based on status, returns str.""" color = COLORS['CLEAR'] @@ -225,7 +237,7 @@ def get_status_color(s, t_success=99, t_warn=90): except ValueError: # Status is either in lists below or will default to red pass - + if s in ('Pending',): color = COLORS['CLEAR'] elif s in ('Skipped', 'Unknown', 'Working'): @@ -238,6 +250,7 @@ def get_status_color(s, t_success=99, t_warn=90): color = COLORS['RED'] return color + def mark_all_passes_pending(source): """Mark all devs and passes as pending in preparation for retry.""" source['Current Pass'] = 'Pass 1' @@ -248,9 +261,10 @@ def mark_all_passes_pending(source): child[p_num]['Status'] = 'Pending' child[p_num]['Done'] = False + def menu_clone(source_path, dest_path): """ddrescue cloning menu.""" - + # Set devices source = select_device('source', source_path) source['Current Pass'] = 'Pass 1' @@ -260,21 +274,22 @@ def menu_clone(source_path, dest_path): source['Recovered Size'] = 0, source['Total Size'] = 0, source['Type'] = 'Clone' - dest = select_device('destination', dest_path, - skip_device = source['Details'], allow_image_file = False) + dest = select_device( + 'destination', dest_path, + skip_device=source['Details'], allow_image_file=False) dest_safety_check(source, dest) - + # Show selection details show_selection_details(source, dest) set_dest_image_paths(source, dest) check_dest_paths(source) get_recovery_scope_size(source) - + # Confirm if not ask('Proceed with clone?'): abort_ddrescue_tui() show_safety_check() - + # Main menu build_outer_panes(source, dest) menu_main(source, dest) @@ -284,6 +299,7 @@ def menu_clone(source_path, dest_path): run_program(['tmux', 'kill-window']) exit_script() + def menu_ddrescue(*args): """Main ddrescue loop/menu.""" args = list(args) @@ -312,11 +328,12 @@ def menu_ddrescue(*args): show_usage(script_name) exit_script() + def menu_image(source_path, dest_path): """ddrescue imaging menu.""" - + # Set devices - source = select_device('source', source_path, allow_image_file = False) + source = select_device('source', source_path, allow_image_file=False) source['Current Pass'] = 'Pass 1' source['Pass 1'] = {'Status': 'Pending', 'Done': False} source['Pass 2'] = {'Status': 'Pending', 'Done': False} @@ -332,14 +349,14 @@ def menu_image(source_path, dest_path): set_dest_image_paths(source, dest) check_dest_paths(source) get_recovery_scope_size(source) - + # Show selection details show_selection_details(source, dest) - + # Confirm if not ask('Proceed with imaging?'): abort_ddrescue_tui() - + # Main menu build_outer_panes(source, dest) menu_main(source, dest) @@ -349,6 +366,7 @@ def menu_image(source_path, dest_path): run_program(['tmux', 'kill-window']) exit_script() + def menu_main(source, dest): """Main menu is used to set ddrescue settings.""" title = '{GREEN}ddrescue TUI: Main Menu{CLEAR}\n\n'.format(**COLORS) @@ -364,7 +382,7 @@ def menu_main(source, dest): 'Enabled': False}, {'Base Name': 'Reverse direction', 'Enabled': False}, ] - actions =[ + actions = [ {'Name': 'Start', 'Letter': 'S'}, {'Name': 'Change settings {YELLOW}(experts only){CLEAR}'.format( **COLORS), @@ -387,11 +405,11 @@ def menu_main(source, dest): opt['Name'] = '{} {}'.format( '[✓]' if opt['Enabled'] else '[ ]', opt['Base Name']) - + selection = menu_select( - title = title + display_pass, - main_entries = main_options, - action_entries = actions) + title=title+display_pass, + main_entries=main_options, + action_entries=actions) if selection.isnumeric(): # Toggle selection @@ -435,20 +453,21 @@ def menu_main(source, dest): break if source[current_pass]['Done']: min_status = source[current_pass]['Min Status'] - if (current_pass == 'Pass 1' - and min_status < AUTO_NEXT_PASS_1_THRESHOLD): + if (current_pass == 'Pass 1' and + min_status < AUTO_NEXT_PASS_1_THRESHOLD): auto_run = False - elif (current_pass == 'Pass 2' - and min_status < AUTO_NEXT_PASS_2_THRESHOLD): + elif (current_pass == 'Pass 2' and + min_status < AUTO_NEXT_PASS_2_THRESHOLD): auto_run = False # Update current pass for next iteration current_pass = source['Current Pass'] - + elif selection == 'C': menu_settings(source) elif selection == 'Q': break + def menu_select_children(source): """Select child device(s) or whole disk, returns list.""" dev_options = [{ @@ -467,7 +486,7 @@ def menu_select_children(source): actions = [ {'Name': 'Proceed', 'Letter': 'P'}, {'Name': 'Quit', 'Letter': 'Q'}] - + # Skip Menu if there's no children if len(dev_options) == 1: return [] @@ -481,9 +500,9 @@ def menu_select_children(source): dev['Base Name']) selection = menu_select( - title = 'Please select part(s) to image', - main_entries = dev_options, - action_entries = actions) + title='Please select part(s) to image', + main_entries=dev_options, + action_entries=actions) if selection.isnumeric(): # Toggle selection @@ -513,6 +532,7 @@ def menu_select_children(source): if d['Selected'] and 'Whole device' not in d['Base Name']] return selected_children + def menu_select_device(title='Which device?', skip_device={}): """Select block device via a menu, returns dev_path as str.""" skip_names = [ @@ -540,11 +560,11 @@ def menu_select_device(title='Which device?', skip_device={}): # Append non-matching devices dev_options.append({ 'Name': '{name:12} {tran:5} {size:6} {model} {serial}'.format( - name = dev['name'], - tran = dev['tran'] if dev['tran'] else '', - size = dev['size'] if dev['size'] else '', - model = dev['model'] if dev['model'] else '', - serial = dev['serial'] if dev['serial'] else ''), + name=dev['name'], + tran=dev['tran'] if dev['tran'] else '', + size=dev['size'] if dev['size'] else '', + model=dev['model'] if dev['model'] else '', + serial=dev['serial'] if dev['serial'] else ''), 'Path': dev['name'], 'Disabled': disable_dev}) dev_options = sorted(dev_options, key=itemgetter('Name')) @@ -555,16 +575,17 @@ def menu_select_device(title='Which device?', skip_device={}): # Show Menu actions = [{'Name': 'Quit', 'Letter': 'Q'}] selection = menu_select( - title = title, - main_entries = dev_options, - action_entries = actions, - disabled_label = 'SOURCE DEVICE') + title=title, + main_entries=dev_options, + action_entries=actions, + disabled_label='SOURCE DEVICE') if selection.isnumeric(): return dev_options[int(selection)-1]['Path'] elif selection == 'Q': abort_ddrescue_tui() + def menu_select_path(skip_device={}): """Select path via menu, returns path as str.""" pwd = os.path.realpath(global_vars['Env']['PWD']) @@ -579,9 +600,9 @@ def menu_select_path(skip_device={}): # Show Menu selection = menu_select( - title = 'Please make a selection', - main_entries = path_options, - action_entries = actions) + title='Please make a selection', + main_entries=path_options, + action_entries=actions) if selection == 'Q': abort_ddrescue_tui() @@ -594,14 +615,14 @@ def menu_select_path(skip_device={}): elif path_options[index]['Name'] == 'Local device': # Local device local_device = select_device( - skip_device = skip_device, - allow_image_file = False) + skip_device=skip_device, + allow_image_file=False) # Mount device volume(s) report = mount_volumes( - all_devices = False, - device_path = local_device['Dev Path'], - read_write = True) + all_devices=False, + device_path=local_device['Dev Path'], + read_write=True) # Select volume vol_options = [] @@ -616,9 +637,9 @@ def menu_select_path(skip_device={}): 'Path': v['mount_point'], 'Disabled': disabled}) selection = menu_select( - title = 'Please select a volume', - main_entries = vol_options, - action_entries = actions) + title='Please select a volume', + main_entries=vol_options, + action_entries=actions) if selection.isnumeric(): s_path = vol_options[int(selection)-1]['Path'] elif selection == 'Q': @@ -636,6 +657,7 @@ def menu_select_path(skip_device={}): print_error('Invalid path "{}"'.format(m_path)) return s_path + def menu_settings(source): """Change advanced ddrescue settings.""" title = '{GREEN}ddrescue TUI: Expert Settings{CLEAR}\n\n'.format(**COLORS) @@ -660,32 +682,33 @@ def menu_settings(source): source['Settings'][s['Flag']].get('Value', '')) if not source['Settings'][s['Flag']]['Enabled']: s['Name'] = '{YELLOW}{name} (Disabled){CLEAR}'.format( - name = s['Name'], + name=s['Name'], **COLORS) selection = menu_select( - title = title, - main_entries = settings, - action_entries = actions) + title=title, + main_entries=settings, + action_entries=actions) if selection.isnumeric(): index = int(selection) - 1 flag = settings[index]['Flag'] enabled = source['Settings'][flag]['Enabled'] if 'Value' in source['Settings'][flag]: answer = choice( - choices = ['T', 'C'], - prompt = 'Toggle or change value for "{}"'.format(flag)) + choices=['T', 'C'], + prompt='Toggle or change value for "{}"'.format(flag)) if answer == 'T': # Toggle source['Settings'][flag]['Enabled'] = not enabled else: # Update value source['Settings'][flag]['Value'] = get_simple_string( - prompt = 'Enter new value') + prompt='Enter new value') else: source['Settings'][flag]['Enabled'] = not enabled elif selection == 'M': break + def read_map_file(map_path): """Read map file with ddrescuelog and return data as dict.""" map_data = {} @@ -694,7 +717,7 @@ def read_map_file(map_path): except subprocess.CalledProcessError: print_error('Failed to read map data') abort_ddrescue_tui() - + # Parse output for line in result.stdout.decode().splitlines(): m = REGEX_MAP_DATA.match(line.strip()) @@ -718,6 +741,7 @@ def read_map_file(map_path): return map_data + def run_ddrescue(source, dest, settings): """Run ddrescue pass.""" current_pass = source['Current Pass'] @@ -739,28 +763,28 @@ def run_ddrescue(source, dest, settings): return else: raise GenericError("This shouldn't happen?") - + # Set device(s) to clone/image source[current_pass]['Status'] = 'Working' source_devs = [source] if source['Children']: # Use only selected child devices source_devs = source['Children'] - + # Set heights - ## NOTE: 12/33 is based on min heights for SMART/ddrescue panes (12+22+1sep) + # NOTE: 12/33 is based on min heights for SMART/ddrescue panes (12+22+1sep) result = run_program(['tput', 'lines']) height = int(result.stdout.decode().strip()) height_smart = int(height * (12 / 33)) height_ddrescue = height - height_smart - + # Show SMART status smart_pane = tmux_splitw( '-bdvl', str(height_smart), '-PF', '#D', 'watch', '--color', '--no-title', '--interval', '300', 'ddrescue-tui-smart-display', source['Dev Path']) - + # Start pass for each selected device for s_dev in source_devs: if s_dev[current_pass]['Done']: @@ -769,23 +793,24 @@ def run_ddrescue(source, dest, settings): source['Current Device'] = s_dev['Dev Path'] s_dev[current_pass]['Status'] = 'Working' update_progress(source) - + # Set ddrescue cmd if source['Type'] == 'Clone': - cmd = ['ddrescue', *settings, '--force', - s_dev['Dev Path'], dest['Dev Path'], s_dev['Dest Paths']['Map']] + cmd = [ + 'ddrescue', *settings, '--force', s_dev['Dev Path'], + dest['Dev Path'], s_dev['Dest Paths']['Map']] else: - cmd = ['ddrescue', *settings, - s_dev['Dev Path'], s_dev['Dest Paths']['Image'], - s_dev['Dest Paths']['Map']] + cmd = [ + 'ddrescue', *settings, s_dev['Dev Path'], + s_dev['Dest Paths']['Image'], s_dev['Dest Paths']['Map']] # Start ddrescue try: clear_screen() print_info('Current dev: {}'.format(s_dev['Dev Path'])) ddrescue_proc = popen_program(['./__choose_exit', *cmd]) - #ddrescue_proc = popen_program(['./__exit_ok', *cmd]) - #ddrescue_proc = popen_program(cmd) + # ddrescue_proc = popen_program(['./__exit_ok', *cmd]) + # ddrescue_proc = popen_program(cmd) while True: try: ddrescue_proc.wait(timeout=30) @@ -814,6 +839,7 @@ def run_ddrescue(source, dest, settings): pause('Press Enter to return to main menu... ') run_program(['tmux', 'kill-pane', '-t', smart_pane]) + def select_dest_path(provided_path=None, skip_device={}): dest = {'Is Dir': True, 'Is Image': False} @@ -851,11 +877,12 @@ def select_dest_path(provided_path=None, skip_device={}): return dest + def select_device(description='device', provided_path=None, - skip_device={}, allow_image_file=True): + skip_device={}, allow_image_file=True): """Select device via provided path or menu, return dev as dict.""" dev = {'Is Dir': False, 'Is Image': False} - + # Set path if provided_path: dev['Path'] = provided_path @@ -864,7 +891,7 @@ def select_device(description='device', provided_path=None, 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'] @@ -879,13 +906,13 @@ def select_device(description='device', provided_path=None, dev['Details'] = get_device_details(dev['Dev Path']) if 'Children' not in dev: dev['Children'] = [] - + # 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'])): + dev['Details']['pkname'])): # Update dev with parent info dev['Dev Path'] = dev['Details']['pkname'] dev['Details'] = get_device_details(dev['Dev Path']) @@ -903,25 +930,28 @@ def select_device(description='device', provided_path=None, width = int((int(result.stdout.decode().strip()) - 21) / 2) - 2 if len(dev['Display Name']) > width: if dev['Is Image']: - dev['Display Name'] = '...{}'.format(dev['Display Name'][-(width-3):]) + dev['Display Name'] = '...{}'.format( + dev['Display Name'][-(width-3):]) else: - dev['Display Name'] = '{}...'.format(dev['Display Name'][:(width-3)]) + dev['Display Name'] = '{}...'.format( + dev['Display Name'][:(width-3)]) else: dev['Display Name'] = dev['Display Name'] return dev + def set_dest_image_paths(source, dest): """Set destination image path for source and any child devices.""" if source['Type'] == 'Clone': base = '{pwd}/Clone_{size}_{model}'.format( - pwd = os.path.realpath(global_vars['Env']['PWD']), - size = source['Details']['size'], - model = source['Details'].get('model', 'Unknown')) + pwd=os.path.realpath(global_vars['Env']['PWD']), + size=source['Details']['size'], + model=source['Details'].get('model', 'Unknown')) else: base = '{Path}/{size}_{model}'.format( - size = source['Details']['size'], - model = source['Details'].get('model', 'Unknown'), + size=source['Details']['size'], + model=source['Details'].get('model', 'Unknown'), **dest) source['Dest Paths'] = { 'Image': '{}.dd'.format(base), @@ -933,17 +963,18 @@ def set_dest_image_paths(source, dest): if child['Details']['label']: p_label = '_{}'.format(child['Details']['label']) base = '{Path}/{size}_{model}_{p_num}_{p_size}{p_label}'.format( - size = source['Details']['size'], - model = source['Details'].get('model', 'Unknown'), - p_num = child['Details']['name'].replace( + size=source['Details']['size'], + model=source['Details'].get('model', 'Unknown'), + p_num=child['Details']['name'].replace( child['Details']['pkname'], ''), - p_size = child['Details']['size'], - p_label = p_label, + p_size=child['Details']['size'], + p_label=p_label, **dest) child['Dest Paths'] = { 'Image': '{}.dd'.format(base), 'Map': '{}.map'.format(base)} + def setup_loopback_device(source_path): """Setup a loopback device for source_path, returns dev_path as str.""" cmd = ( @@ -962,6 +993,7 @@ def setup_loopback_device(source_path): else: return dev_path + def show_device_details(dev_path): """Display device details on screen.""" cmd = ( @@ -982,6 +1014,7 @@ def show_device_details(dev_path): for line in output: print_standard(line) + def show_safety_check(): """Display safety check message and get confirmation from user.""" print_standard('\nSAFETY CHECK') @@ -992,9 +1025,10 @@ def show_safety_check(): if not ask('Asking again to confirm, is this correct?'): abort_ddrescue_tui() + def show_selection_details(source, dest): clear_screen() - + # Source print_success('Source device') if source['Is Image']: @@ -1003,7 +1037,7 @@ def show_selection_details(source, dest): source['Dev Path'])) show_device_details(source['Dev Path']) print_standard(' ') - + # Destination if source['Type'] == 'Clone': print_success('Destination device ', end='') @@ -1017,17 +1051,20 @@ def show_selection_details(source, dest): dest['Free Space'], dest['Filesystem'])) print_standard(' ') + def show_usage(script_name): print_info('Usage:') print_standard(USAGE.format(script_name=script_name)) pause() + def tmux_splitw(*args): """Run tmux split-window command and return output as str.""" cmd = ['tmux', 'split-window', *args] result = run_program(cmd) return result.stdout.decode().strip() + def update_progress(source, end_run=False): """Update progress file.""" current_pass = source['Current Pass'] @@ -1047,9 +1084,10 @@ def update_progress(source, end_run=False): next_pass = 'Pass {}'.format(next_pass_num) else: next_pass = 'Done' - + if 'Progress Out' not in source: - source['Progress Out'] = '{}/progress.out'.format(global_vars['LogDir']) + source['Progress Out'] = '{}/progress.out'.format( + global_vars['LogDir']) output = [] if source['Type'] == 'Clone': output.append(' {BLUE}Cloning Status{CLEAR}'.format(**COLORS)) @@ -1067,7 +1105,7 @@ def update_progress(source, end_run=False): child[current_pass]['Done'] = map_data['pass completed'] child[current_pass]['Status'] = map_data['rescued'] child['Recovered Size'] = r_size - + # All child devices pass_complete_for_all_devs &= child[current_pass]['Done'] total_recovery &= map_data['full recovery'] @@ -1083,7 +1121,7 @@ def update_progress(source, end_run=False): # Map missing, assuming this pass hasn't run for this dev yet pass_complete_for_all_devs = False total_recovery = False - + # Update source progress if len(source['Children']) > 0: # Imaging parts, skip updating source progress @@ -1107,7 +1145,7 @@ def update_progress(source, end_run=False): # Cloning/Imaging whole device and map missing pass_complete_for_all_devs = False total_recovery = False - + # End of pass updates if end_run: if total_recovery: @@ -1124,11 +1162,11 @@ def update_progress(source, end_run=False): # Ready for next pass? source['Current Pass'] = next_pass source[current_pass]['Done'] = True - + # Main device if source['Type'] == 'Clone': output.append('{BLUE}{dev}{CLEAR}'.format( - dev = 'Image File' if source['Is Image'] else source['Dev Path'], + dev='Image File' if source['Is Image'] else source['Dev Path'], **COLORS)) for x in (1, 2, 3): p_num = 'Pass {}'.format(x) @@ -1141,9 +1179,9 @@ def update_progress(source, end_run=False): else: s_display = '{:0.2f} %'.format(s_display) output.append('{p_num}{s_color}{s_display:>15}{CLEAR}'.format( - p_num = p_num, - s_color = get_status_color(source[p_num]['Status']), - s_display = s_display, + p_num=p_num, + s_color=get_status_color(source[p_num]['Status']), + s_display=s_display, **COLORS)) else: # Image mode @@ -1151,7 +1189,7 @@ def update_progress(source, end_run=False): # Just parts for child in source['Children']: output.append('{BLUE}{dev}{CLEAR}'.format( - dev = child['Dev Path'], + dev=child['Dev Path'], **COLORS)) for x in (1, 2, 3): p_num = 'Pass {}'.format(x) @@ -1163,16 +1201,17 @@ def update_progress(source, end_run=False): pass else: s_display = '{:0.2f} %'.format(s_display) - output.append('{p_num}{s_color}{s_display:>15}{CLEAR}'.format( - p_num = p_num, - s_color = get_status_color(child[p_num]['Status']), - s_display = s_display, - **COLORS)) + output.append( + '{p_num}{s_color}{s_display:>15}{CLEAR}'.format( + p_num=p_num, + s_color=get_status_color(child[p_num]['Status']), + s_display=s_display, + **COLORS)) output.append(' ') else: # Whole device output.append('{BLUE}{dev}{CLEAR} {YELLOW}(Whole){CLEAR}'.format( - dev = source['Dev Path'], + dev=source['Dev Path'], **COLORS)) for x in (1, 2, 3): p_num = 'Pass {}'.format(x) @@ -1184,11 +1223,12 @@ def update_progress(source, end_run=False): pass else: s_display = '{:0.2f} %'.format(s_display) - output.append('{p_num}{s_color}{s_display:>15}{CLEAR}'.format( - p_num = p_num, - s_color = get_status_color(source[p_num]['Status']), - s_display = s_display, - **COLORS)) + output.append( + '{p_num}{s_color}{s_display:>15}{CLEAR}'.format( + p_num=p_num, + s_color=get_status_color(source[p_num]['Status']), + s_display=s_display, + **COLORS)) # Add line-endings output = ['{}\n'.format(line) for line in output] @@ -1196,6 +1236,7 @@ def update_progress(source, end_run=False): with open(source['Progress Out'], 'w') as f: f.writelines(output) + if __name__ == '__main__': print("This file is not meant to be called directly.")