Improved ddrescue map parsing
* Get data recovered instead of percentage, should be more acurate
This commit is contained in:
parent
73ca03da8e
commit
f2adf6f5c0
2 changed files with 28 additions and 20 deletions
|
|
@ -107,19 +107,19 @@ class BlockPair():
|
|||
def load_map_data(self):
|
||||
"""Load data from map file and set progress."""
|
||||
map_data = read_map_file(self.map_path)
|
||||
self.rescued_percent = map_data['rescued']
|
||||
self.rescued = (self.rescued_percent * self.size) / 100
|
||||
self.rescued = map_data.get('rescued', 0)
|
||||
self.rescued_percent = (self.rescued / self.size) * 100
|
||||
if map_data['full recovery']:
|
||||
self.pass_done = [True, True, True]
|
||||
self.rescued = self.size
|
||||
self.status = ['Skipped', 'Skipped', 'Skipped']
|
||||
elif map_data['non-tried'] > 0:
|
||||
elif map_data.get('non-tried', 0) > 0:
|
||||
# Initial pass incomplete
|
||||
pass
|
||||
elif map_data['non-trimmed'] > 0:
|
||||
elif map_data.get('non-trimmed', 0) > 0:
|
||||
self.pass_done = [True, False, False]
|
||||
self.status = ['Skipped', 'Pending', 'Pending']
|
||||
elif map_data['non-scraped'] > 0:
|
||||
elif map_data.get('non-scraped', 0) > 0:
|
||||
self.pass_done = [True, True, False]
|
||||
self.status = ['Skipped', 'Skipped', 'Pending']
|
||||
else:
|
||||
|
|
@ -147,8 +147,8 @@ class BlockPair():
|
|||
"""Update progress using map file."""
|
||||
if os.path.exists(self.map_path):
|
||||
map_data = read_map_file(self.map_path)
|
||||
self.rescued_percent = map_data.get('rescued', 0)
|
||||
self.rescued = (self.rescued_percent * self.size) / 100
|
||||
self.rescued = map_data.get('rescued', 0)
|
||||
self.rescued_percent = (self.rescued / self.size) * 100
|
||||
self.status[pass_num] = get_formatted_status(
|
||||
label='Pass {}'.format(pass_num+1),
|
||||
data=(self.rescued/self.size)*100)
|
||||
|
|
@ -1022,25 +1022,27 @@ def menu_settings(state):
|
|||
|
||||
def read_map_file(map_path):
|
||||
"""Read map file with ddrescuelog and return data as dict."""
|
||||
map_data = {'full recovery': False}
|
||||
cmd = [
|
||||
'ddrescuelog',
|
||||
'--binary-prefixes',
|
||||
'--show-status',
|
||||
map_path,
|
||||
]
|
||||
map_data = {'full recovery': False, 'pass completed': False}
|
||||
try:
|
||||
result = run_program(['ddrescuelog', '-t', map_path])
|
||||
result = run_program(cmd, encoding='utf-8', errors='ignore')
|
||||
except CalledProcessError:
|
||||
# (Grossly) assuming map_data hasn't been saved yet, return empty dict
|
||||
return map_data
|
||||
|
||||
# Parse output
|
||||
for line in result.stdout.decode().splitlines():
|
||||
data = re.match(
|
||||
r'^\s*(?P<key>\S+):.*\(\s*(?P<value>\d+\.?\d*)%.*', line.strip())
|
||||
if data:
|
||||
try:
|
||||
map_data[data.group('key')] = float(data.group('value'))
|
||||
except ValueError:
|
||||
raise GenericError('Failed to read map data')
|
||||
data = re.match(r'.*current status:\s+(?P<status>.*)', line.strip())
|
||||
if data:
|
||||
map_data['pass completed'] = bool(data.group('status') == 'finished')
|
||||
for line in result.stdout.splitlines():
|
||||
line = line.strip()
|
||||
_r = REGEX_DDRESCUE_LOG.search(line)
|
||||
if _r:
|
||||
map_data[_r.group('key')] = convert_to_bytes('{size} {unit}B'.format(
|
||||
**_r.groupdict()))
|
||||
map_data['pass completed'] = 'current status: finished' in line
|
||||
|
||||
# Check if 100% done
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -38,6 +38,12 @@ DDRESCUE_SETTINGS = {
|
|||
'-vvvv': {'Enabled': True, 'Hidden': True, },
|
||||
}
|
||||
ETOC_REFRESH_RATE = 30 # in seconds
|
||||
REGEX_DDRESCUE_LOG = re.compile(
|
||||
r'^\s*(?P<key>\S+):\s+'
|
||||
r'(?P<size>\d+)\s+'
|
||||
r'(?P<unit>[PTGMKB])i?B?',
|
||||
re.IGNORECASE,
|
||||
)
|
||||
REGEX_REMAINING_TIME = re.compile(
|
||||
r'remaining time:'
|
||||
r'\s*((?P<days>\d+)d)?'
|
||||
|
|
|
|||
Loading…
Reference in a new issue