From 045d2b25714d84c81e41244ee4fb2f8bdbd15c12 Mon Sep 17 00:00:00 2001 From: 2Shirt <2xShirt@gmail.com> Date: Thu, 12 Dec 2019 16:39:42 -0700 Subject: [PATCH] Updates ddrescue-tui tmux sections --- scripts/wk/cfg/__init__.py | 1 + scripts/wk/cfg/ddrescue.py | 8 ++--- scripts/wk/hw/__init__.py | 1 + scripts/wk/hw/ddrescue.py | 72 +++++++++++++++++++++++++++++++------- 4 files changed, 66 insertions(+), 16 deletions(-) diff --git a/scripts/wk/cfg/__init__.py b/scripts/wk/cfg/__init__.py index fc63cf2d..d86f7245 100644 --- a/scripts/wk/cfg/__init__.py +++ b/scripts/wk/cfg/__init__.py @@ -1,5 +1,6 @@ """WizardKit: cfg module init""" +from wk.cfg import ddrescue from wk.cfg import hw from wk.cfg import log from wk.cfg import main diff --git a/scripts/wk/cfg/ddrescue.py b/scripts/wk/cfg/ddrescue.py index ee9cb72a..482b683c 100644 --- a/scripts/wk/cfg/ddrescue.py +++ b/scripts/wk/cfg/ddrescue.py @@ -13,11 +13,11 @@ RECOMMENDED_FSTYPES = ['ext3', 'ext4', 'xfs'] RECOMMENDED_MAP_FSTYPES = ['cifs', 'ext2', 'ext3', 'ext4', 'vfat', 'xfs'] # Layout -SIDE_PANE_WIDTH = 21 +TMUX_SIDE_WIDTH = 21 TMUX_LAYOUT = OrderedDict({ - 'Source': {'y': 2, 'Check': True}, - 'Started': {'x': SIDE_PANE_WIDTH, 'Check': True}, - 'Progress': {'x': SIDE_PANE_WIDTH, 'Check': True}, + 'Source': {'height': 2, 'Check': True}, + 'Started': {'width': TMUX_SIDE_WIDTH, 'Check': True}, + 'Progress': {'width': TMUX_SIDE_WIDTH, 'Check': True}, }) # ddrescue diff --git a/scripts/wk/hw/__init__.py b/scripts/wk/hw/__init__.py index 17b6df35..ad2b04cb 100644 --- a/scripts/wk/hw/__init__.py +++ b/scripts/wk/hw/__init__.py @@ -1,5 +1,6 @@ """WizardKit: hw module init""" +from wk.hw import ddrescue from wk.hw import diags from wk.hw import obj from wk.hw import sensors diff --git a/scripts/wk/hw/ddrescue.py b/scripts/wk/hw/ddrescue.py index 51759035..dba4b74f 100644 --- a/scripts/wk/hw/ddrescue.py +++ b/scripts/wk/hw/ddrescue.py @@ -41,6 +41,11 @@ MENU_TOGGLES = { 'Retry (mark non-rescued sectors "non-tried")': False, 'Reverse direction': False, } +PANE_RATIOS = ( + 12, # SMART + 22, # ddrescue progress + 4, # Journal (kernel messages) + ) STATUS_COLORS = { 'Passed': 'GREEN', 'Aborted': 'YELLOW', @@ -54,12 +59,13 @@ STATUS_COLORS = { class State(): """Object for tracking hardware diagnostic data.""" def __init__(self): - #TODO self.block_pairs = [] + self.destination = None self.disks = [] self.layout = cfg.ddrescue.TMUX_LAYOUT.copy() self.log_dir = None self.panes = {} + self.source = None # Init tmux and start a background process to maintain layout self.init_tmux() @@ -68,12 +74,28 @@ class State(): def fix_tmux_layout(self, forced=True): # pylint: disable=unused-argument """Fix tmux layout based on cfg.ddrescue.TMUX_LAYOUT.""" + needs_fixed = tmux.layout_needs_fixed(self.panes, self.layout) + + # Main layout fix try: tmux.fix_layout(self.panes, self.layout, forced=forced) except RuntimeError: # Assuming self.panes changed while running pass + # Source/Destination + if forced or needs_fixed: + self.update_top_panes() + + # SMART/Journal + height = tmux.get_pane_size(self.panes['Progress'])[1] - 2 + p_ratios = [int((x/sum(PANE_RATIOS)) * height) for x in PANE_RATIOS] + if 'SMART' in self.panes: + tmux.resize_pane(self.panes['SMART'], height=p_ratios[0]) + tmux.resize_pane(height=p_ratios[1]) + if 'Journal' in self.panes: + tmux.resize_pane(self.panes['Journal'], height=p_ratios[2]) + def fix_tmux_layout_loop(self): """Fix tmux layout on a loop. @@ -87,13 +109,18 @@ class State(): """Initialize tmux layout.""" tmux.kill_all_panes() - # Source / Dest - self.update_top_panes() + # Source (placeholder) + self.panes['Source'] = tmux.split_window( + behind=True, + lines=2, + text=' ', + vertical=True, + ) # Started self.panes['Started'] = tmux.split_window( lines=cfg.ddrescue.TMUX_SIDE_WIDTH, - target_id=self.panes['Top'], + target_id=self.panes['Source'], text=std.color_string( ['Started', time.strftime("%Y-%m-%d %H:%M %Z")], ['BLUE', None], @@ -101,6 +128,9 @@ class State(): ), ) + # Source / Dest + self.update_top_panes() + # Progress self.panes['Progress'] = tmux.split_window( lines=cfg.ddrescue.TMUX_SIDE_WIDTH, @@ -135,27 +165,45 @@ class State(): with open(out_path, 'w') as _f: _f.write('\n'.join(report)) - def update_top_panes(self, text): + def update_top_panes(self): """(Re)create top source/destination panes.""" - #TODO - self.panes['Source'] = tmux.split_window( - behind=True, - lines=2, - vertical=True, + width = tmux.get_pane_size()[0] + width = int(width / 2) - 1 + + # Kill destination pane + if 'Destination' in self.panes: + tmux.kill_pane(self.panes.pop('Destination')) + + # Source + source_str = ' ' + if self.source: + source_str = f'{self.source.path} {self.source.description}' + if len(source_str) > width: + source_str = f'{source_str[:width-3]}...' + tmux.respawn_pane( + self.panes['Source'], text=std.color_string( - ['Source', f'TODO'], + ['Source', source_str], ['BLUE', None], sep='\n', ), ) # Destination + dest_str = '' + if self.destination: + dest_str = f'{self.destination.path} {self.destination.description}' + if len(dest_str) > width: + if self.destination.path.is_dir(): + dest_str = f'...{dest_str[-width+3:]}' + else: + dest_str = f'{dest_str[:width-3]}...' self.panes['Destination'] = tmux.split_window( percent=50, vertical=False, target_id=self.panes['Source'], text=std.color_string( - ['Destination', f'TODO'], + ['Destination', dest_str], ['BLUE', None], sep='\n', ),