Update ddrescue-tui to use new Disk object vars
This commit is contained in:
parent
2585ed584c
commit
6642aad2c8
2 changed files with 41 additions and 41 deletions
|
|
@ -133,12 +133,12 @@ class BlockPair():
|
|||
NOTE: source should be a wk.hw.obj.Disk() object
|
||||
and destination should be a pathlib.Path() object.
|
||||
"""
|
||||
self.sector_size = source.details.get('phy-sec', 512)
|
||||
self.sector_size = source.phy_sec
|
||||
self.source = source.path
|
||||
self.destination = destination
|
||||
self.map_data = {}
|
||||
self.map_path = None
|
||||
self.size = source.details['size']
|
||||
self.size = source.size
|
||||
self.status = OrderedDict({
|
||||
'read-skip': 'Pending',
|
||||
'read-full': 'Pending',
|
||||
|
|
@ -150,9 +150,9 @@ class BlockPair():
|
|||
# Set map path
|
||||
# e.g. '(Clone|Image)_Model[_p#]_Size[_Label].map'
|
||||
map_name = model if model else 'None'
|
||||
if source.details['bus'] == 'Image':
|
||||
if source.bus == 'Image':
|
||||
map_name = 'Image'
|
||||
if source.details['parent']:
|
||||
if source.parent:
|
||||
part_num = re.sub(r"^.*?(\d+)$", r"\1", source.path.name)
|
||||
map_name += f'_p{part_num}'
|
||||
size_str = std.bytes_to_string(
|
||||
|
|
@ -160,8 +160,8 @@ class BlockPair():
|
|||
use_binary=False,
|
||||
)
|
||||
map_name += f'_{size_str.replace(" ", "")}'
|
||||
if source.details.get('label', ''):
|
||||
map_name += f'_{source.details["label"]}'
|
||||
if source.raw_details.get('label', ''):
|
||||
map_name += f'_{source.raw_details["label"]}'
|
||||
map_name = map_name.replace(' ', '_')
|
||||
map_name = map_name.replace('/', '_')
|
||||
if destination.is_dir():
|
||||
|
|
@ -316,8 +316,8 @@ class BlockPair():
|
|||
# Mark future passes as skipped if applicable
|
||||
if percent == 100:
|
||||
status_keys = list(self.status.keys())
|
||||
for i in status_keys[status_keys.index(pass_name)+1:]:
|
||||
self.status[status_keys[i]] = 'Skipped'
|
||||
for pass_n in status_keys[status_keys.index(pass_name)+1:]:
|
||||
self.status[pass_n] = 'Skipped'
|
||||
|
||||
|
||||
class State():
|
||||
|
|
@ -342,13 +342,13 @@ class State():
|
|||
BlockPair(
|
||||
source=source,
|
||||
destination=destination,
|
||||
model=self.source.details['model'],
|
||||
model=self.source.model,
|
||||
working_dir=self.working_dir,
|
||||
))
|
||||
|
||||
def _get_clone_settings_path(self):
|
||||
"""get Clone settings file path, returns pathlib.Path obj."""
|
||||
description = self.source.details['model']
|
||||
description = self.source.model
|
||||
if not description:
|
||||
description = self.source.path.name
|
||||
return pathlib.Path(f'{self.working_dir}/Clone_{description}.json')
|
||||
|
|
@ -441,10 +441,10 @@ class State():
|
|||
else:
|
||||
bail = False
|
||||
for key in ('model', 'serial'):
|
||||
if settings['Source'][key] != self.source.details[key]:
|
||||
if settings['Source'][key] != getattr(self.source, key):
|
||||
std.print_error(f"Clone settings don't match source {key}")
|
||||
bail = True
|
||||
if settings['Destination'][key] != self.destination.details[key]:
|
||||
if settings['Destination'][key] != getattr(self.destination, key):
|
||||
std.print_error(f"Clone settings don't match destination {key}")
|
||||
bail = True
|
||||
if bail:
|
||||
|
|
@ -455,13 +455,13 @@ class State():
|
|||
settings = CLONE_SETTINGS.copy()
|
||||
if not settings['Source']:
|
||||
settings['Source'] = {
|
||||
'model': self.source.details['model'],
|
||||
'serial': self.source.details['serial'],
|
||||
'model': self.source.model,
|
||||
'serial': self.source.serial,
|
||||
}
|
||||
if not settings['Destination']:
|
||||
settings['Destination'] = {
|
||||
'model': self.destination.details['model'],
|
||||
'serial': self.destination.details['serial'],
|
||||
'model': self.destination.model,
|
||||
'serial': self.destination.serial,
|
||||
}
|
||||
|
||||
# Done
|
||||
|
|
@ -621,7 +621,7 @@ class State():
|
|||
for part in source_parts:
|
||||
report.append(
|
||||
f'{part.path.name:<9} '
|
||||
f'{std.bytes_to_string(part.details["size"], use_binary=False)}'
|
||||
f'{std.bytes_to_string(part.size, use_binary=False)}'
|
||||
)
|
||||
report.append(' ')
|
||||
|
||||
|
|
@ -880,7 +880,7 @@ class State():
|
|||
|
||||
# Add selected partition(s)
|
||||
for part in source_parts:
|
||||
num_sectors = part.details['size'] / self.destination.details['log-sec']
|
||||
num_sectors = part.size / self.destination.log_sec
|
||||
num_sectors = math.ceil(num_sectors)
|
||||
part_num += 1
|
||||
sfdisk_script.append(
|
||||
|
|
@ -888,7 +888,7 @@ class State():
|
|||
table_type=settings['Table Type'],
|
||||
dev_path=f'{dest_prefix}{part_num}',
|
||||
size=num_sectors,
|
||||
details=part.details,
|
||||
details=part.raw_details,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -981,7 +981,7 @@ class State():
|
|||
# 1 LBA for the protective MBR
|
||||
# 33 LBAs each for the primary and backup GPT tables
|
||||
# Source: https://en.wikipedia.org/wiki/GUID_Partition_Table
|
||||
required_size += (1 + 33 + 33) * self.destination.details['phy-sec']
|
||||
required_size += (1 + 33 + 33) * self.destination.phy_sec
|
||||
if settings['Create Boot Partition']:
|
||||
# 384MiB EFI System Partition and a 16MiB MS Reserved partition
|
||||
required_size += (384 + 16) * 1024**2
|
||||
|
|
@ -1004,7 +1004,7 @@ class State():
|
|||
|
||||
# Check destination size
|
||||
if self.mode == 'Clone':
|
||||
destination_size = self.destination.details['size']
|
||||
destination_size = self.destination.size
|
||||
error_msg = 'A larger destination disk is required'
|
||||
else:
|
||||
# NOTE: Adding an extra 5% here to better ensure it will fit
|
||||
|
|
@ -1311,13 +1311,13 @@ def build_directory_report(path):
|
|||
|
||||
def build_disk_report(dev):
|
||||
"""Build device report, returns list."""
|
||||
children = dev.details.get('children', [])
|
||||
children = dev.raw_details.get('children', [])
|
||||
report = []
|
||||
|
||||
# Get widths
|
||||
widths = {
|
||||
'fstype': max(6, len(str(dev.details.get('fstype', '')))),
|
||||
'label': max(5, len(str(dev.details.get('label', '')))),
|
||||
'fstype': max(6, len(str(dev.filesystem))),
|
||||
'label': max(5, len(str(dev.raw_details.get('label', '')))),
|
||||
'name': max(4, len(dev.path.name)),
|
||||
}
|
||||
for child in children:
|
||||
|
|
@ -1332,10 +1332,10 @@ def build_disk_report(dev):
|
|||
# Disk details
|
||||
report.append(f'{dev.path.name} {dev.description}')
|
||||
report.append(' ')
|
||||
dev_fstype = dev.details.get('fstype', '')
|
||||
dev_label = dev.details.get('label', '')
|
||||
dev_fstype = dev.filesystem
|
||||
dev_label = dev.raw_details.get('label', '')
|
||||
dev_name = dev.path.name
|
||||
dev_size = std.bytes_to_string(dev.details["size"], use_binary=False)
|
||||
dev_size = std.bytes_to_string(dev.size, use_binary=False)
|
||||
|
||||
# Partition details
|
||||
report.append(
|
||||
|
|
@ -1684,11 +1684,10 @@ def get_object(path):
|
|||
obj = hw_disk.Disk(path)
|
||||
|
||||
# Child/Parent check
|
||||
parent = obj.raw_details['parent']
|
||||
if parent:
|
||||
if obj.parent:
|
||||
std.print_warning(f'"{obj.path}" is a child device')
|
||||
if std.ask(f'Use parent device "{parent}" instead?'):
|
||||
obj = hw_disk.Disk(parent)
|
||||
if std.ask(f'Use parent device "{obj.parent}" instead?'):
|
||||
obj = hw_disk.Disk(obj.parent)
|
||||
elif path.is_dir():
|
||||
obj = path
|
||||
elif path.is_file():
|
||||
|
|
@ -1736,7 +1735,7 @@ def get_table_type(disk):
|
|||
NOTE: If resulting table type is not GPT or MBR
|
||||
then an exception is raised.
|
||||
"""
|
||||
table_type = str(disk.details.get('pttype', '')).upper()
|
||||
table_type = str(disk.raw_details.get('pttype', '')).upper()
|
||||
table_type = table_type.replace('DOS', 'MBR')
|
||||
|
||||
# Check type
|
||||
|
|
@ -2239,23 +2238,22 @@ def select_disk(prompt, skip_disk=None):
|
|||
menu.add_action('Quit')
|
||||
for disk in disks:
|
||||
disable_option = False
|
||||
size = disk.details["size"]
|
||||
size = disk.size
|
||||
|
||||
# Check if option should be disabled
|
||||
if skip_disk:
|
||||
parent = skip_disk.details.get('parent', None)
|
||||
if (disk.path.samefile(skip_disk.path)
|
||||
or (parent and disk.path.samefile(parent))):
|
||||
or (skip_disk.parent and disk.path.samefile(skip_disk.parent))):
|
||||
disable_option = True
|
||||
|
||||
# Add to menu
|
||||
menu.add_option(
|
||||
name=(
|
||||
f'{str(disk.path):<12} '
|
||||
f'{disk.details["bus"]:<5} '
|
||||
f'{disk.bus:<5} '
|
||||
f'{std.bytes_to_string(size, decimals=1, use_binary=False):<8} '
|
||||
f'{disk.details["model"]} '
|
||||
f'{disk.details["serial"]}'
|
||||
f'{disk.model} '
|
||||
f'{disk.serial}'
|
||||
),
|
||||
details={'Disabled': disable_option, 'Object': disk},
|
||||
)
|
||||
|
|
@ -2305,12 +2303,12 @@ def select_disk_parts(prompt, disk):
|
|||
return [disk]
|
||||
|
||||
# Bail early if child device selected
|
||||
if disk.details.get('parent', False):
|
||||
if disk.parent:
|
||||
return [disk]
|
||||
|
||||
# Add parts
|
||||
whole_disk_str = f'{str(disk.path):<14} (Whole device)'
|
||||
for part in disk.details.get('children', []):
|
||||
for part in disk.raw_details.get('children', []):
|
||||
size = part["size"]
|
||||
name = (
|
||||
f'{str(part["path"]):<14} '
|
||||
|
|
@ -2333,7 +2331,7 @@ def select_disk_parts(prompt, disk):
|
|||
object_list.append(option['Path'])
|
||||
|
||||
# Check if whole disk selected
|
||||
if len(object_list) == len(disk.details.get('children', [])):
|
||||
if len(object_list) == len(disk.raw_details.get('children', [])):
|
||||
# NOTE: This is not true if the disk has no partitions
|
||||
msg = f'Preserve partition table and unused space in {prompt.lower()}?'
|
||||
if std.ask(msg):
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ class Disk:
|
|||
name: str = field(init=False)
|
||||
notes: list[str] = field(init=False, default_factory=list)
|
||||
path: Union[pathlib.Path, str]
|
||||
parent: str = field(init=False)
|
||||
phy_sec: int = field(init=False)
|
||||
raw_details: dict[str, Any] = field(init=False)
|
||||
raw_smartctl: dict[str, Any] = field(init=False)
|
||||
|
|
@ -127,6 +128,7 @@ class Disk:
|
|||
self.log_sec = self.raw_details.get('log-sec', 512)
|
||||
self.model = self.raw_details.get('model', 'Unknown Model')
|
||||
self.name = self.raw_details.get('name', self.path)
|
||||
self.parent = self.raw_details.get('parent', None)
|
||||
self.phy_sec = self.raw_details.get('phy-sec', 512)
|
||||
self.serial = self.raw_details.get('serial', 'Unknown Serial')
|
||||
self.size = self.raw_details.get('size', -1)
|
||||
|
|
|
|||
Loading…
Reference in a new issue