diff --git a/scripts/wk/hw/diags.py b/scripts/wk/hw/diags.py index 1df65cb7..bb11f6a8 100644 --- a/scripts/wk/hw/diags.py +++ b/scripts/wk/hw/diags.py @@ -76,7 +76,12 @@ MENU_TOGGLES = ( 'osTicket Note (optional)', 'Skip USB Benchmarks', ) +NUM_DISK_TESTS = sum([s for s in MENU_OPTIONS if s.startswith('Disk')]) PLATFORM = std.PLATFORM +REGEX_BLOCK_GRAPH = re.compile(r'(▁|▂|▃|▄|▅|▆|▇|█)') +REGEX_SMART_ATTRIBUTES = re.compile( + r'^\s*(?P\d+) / (?P\w\w): (?P.*)$', + ) STATUS_COLORS = { 'Passed': 'GREEN', 'Aborted': 'YELLOW', @@ -1203,6 +1208,106 @@ def network_test(): std.pause('Press Enter to return to main menu...') +def ost_build_report(dev, dev_type): + """Build report for posting to osTicket, returns str.""" + report = [] + + # Combined result + if dev_type == 'CPU' or len(dev.tests) == NUM_DISK_TESTS: + result = 'UNKNOWN' + if dev.any_test_failed(): + result = 'FAILED' + elif dev.all_tests_passed(): + result = 'PASSED' + report.append(f'{dev_type} hardware diagnostic tests: {result}') + report.append('') + + # Description + report.append(dev.description) + if hasattr(dev, 'ram_total'): + report.append(f'{dev.ram_total} ({", ".join(dev.ramm_dimms)})') + report.append('') + + # Notes + if hasattr(dev, 'notes') and dev.notes: + report.append('Notes') + report.extend([f'... {note}' for note in dev.notes]) + report.append('') + + # Tests + for name, test in dev.tests.items(): + # Name and result + result = 'UNKNOWN' + if test.failed: + result = 'FAILED' + elif test.passed: + result = 'PASSED' + report.append(f'{name} ({result})') + + # Report + if name == 'Disk Attributes' and dev.attributes: + report.extend( + ost_convert_report(dev.generate_attribute_report(), start_index=0), + ) + else: + report.extend(ost_convert_report(dev.report), start_index=1) + + # Spacer + report.append('') + + # Remove last line if empty + if not report[-1].strip(): + report.pop(-1) + + # Done + return std.strip_colors('\n'.join(report)) + + +def ost_convert_report(original_report, start_index): + """Convert report to an osTicket compatible type, returns list.""" + report = [] + + # Convert report + for line in original_report[start_index:]: + # Remove colors and leading spaces + line = std.strip_colors(line) + line = re.sub(r'^\s+', '', line) + + # Disk I/O Benchmark + if REGEX_BLOCK_GRAPH.search(line): + line = REGEX_BLOCK_GRAPH.sub('', line) + line = line.strip() + + # SMART attributes + match = REGEX_SMART_ATTRIBUTES.search(line) + if match: + # Switch decimal and hex labels + _dec = f'{match.group("decimal"):>3}' + _dec = osticket.pad_with_dots(_dec) + _hex = match.group('hex') + _data = match.group('data') + line = f'{_hex}/{_dec}: {_data}' + + # Skip empty lines + if not line.strip(): + continue + + # Fix inner spacing + for spacing in re.findall(r'\s\s+', line): + new_padding = osticket.pad_with_dots(spacing) + new_padding += ' ' + line = line.replace(spacing, new_padding) + + # Indent line + line = f'... {line}' + + # Add to (converted) report + report.append(line) + + # Done + return report + + def print_countdown(proc, seconds): """Print countdown to screen while proc is alive.""" for i in range(seconds):