Coverage for laskea/api/excel.py: 98.78%

45 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-10 22:19:18 +00:00

1import hashlib 

2import pathlib 

3from typing import no_type_check 

4 

5from openpyxl import load_workbook # type: ignore 

6 

7from laskea import BASE_LF_ONLY 

8 

9CHUNK_SIZE = 2 << 15 

10 

11 

12def hash_file(path: pathlib.Path) -> str: 

13 """Return the SHA512 hex digest of the data from file.""" 

14 hash = hashlib.sha512() 

15 with open(path, 'rb') as handle: 

16 while chunk := handle.read(CHUNK_SIZE): 

17 hash.update(chunk) 

18 return hash.hexdigest() 

19 

20 

21@no_type_check 

22def mbom_table(filename: str): 

23 """Import MBOM per convention from office table file.""" 

24 wb = load_workbook(filename=filename, data_only=True, read_only=True) 

25 ws = wb.worksheets[0] 

26 

27 table_headers = [ws[address].value for address in ('A1', 'B1', 'C1', 'D1')] 

28 

29 table_caption_data = [ws[address].value for address in ('A2', 'B2', 'C2', 'D2')] 

30 

31 max_row = 1000 

32 table_rows = [] 

33 for row in range(3, max_row): 

34 data = [ws[address].value for address in (f'A{row}', f'B{row}', f'C{row}', f'D{row}')] 

35 if [x for x in data if x]: 

36 table_rows.append(data) 

37 

38 # print(table_headers) 

39 # ['Level', 'P/N', 'Item Name', 'SW Version'] 

40 

41 # print(table_caption_data) 

42 # [0, '123', 'SW, PRODUCT, CUST', None] 

43 

44 # for row in table_rows: 

45 # print(row) 

46 

47 # [1, '124', 'THAT, DEF, LINUX', 'v1.2'] 

48 # [1, '125', 'THAT, EFG, ABA8000, LINUX', 'Rev.24'] 

49 # [1, '126', 'THAT, ABC, CUST', 'v7_R2427'] 

50 # [2, '127', 'THAT, MNMNM, LINUX', 'v6.204.70'] 

51 # [2, '128', 'THAT, WHAT, XXXX4, LINUX', 'v4.2'] 

52 # [3, '129', 'SIMULATION, ABC v7.0', 'v7.0'] 

53 # [4, '130', 'ORGA v7.0 IJK', 'v7.0'] 

54 # [3, '222', 'ABC Config XML - CUST', 'v7.0'] 

55 # [3, '223', 'ABC Default Trip XML', 'v7.0'] 

56 # [3, '224', 'ABC Default Patching XML - LD Smoke', 'v7.0'] 

57 # [3, '227', 'ABC Default EFK Config Files - MNO12', 'v6.204.70'] 

58 # [2, '132', 'LIBRARY, FUNNY HEART, 1.0', 'v1.0'] 

59 # [2, '131', 'XYZ RUNTIME, LINUX', 'v3.3.0'] 

60 # [1, '141', 'THAT, UVW', 'Core 2.0.1, Adapter 2.0.4'] 

61 

62 header_widths = [len(label) for label in table_headers] # noqa 

63 widths = header_widths[:] 

64 selection = table_rows[:] 

65 for record in selection: 

66 for i, s in enumerate(record): 

67 if s is not None: 67 ↛ 66line 67 didn't jump to line 66, because the condition on line 67 was never false

68 widths[i] = max(widths[i], len(str(s))) 

69 

70 header_cells = [table_headers[key].ljust(widths[key]) for key in range(len(table_headers))] # noqa # noqa 

71 header = f'| {" | ".join(header_cells)} |' 

72 

73 separator_cells = ['-' * (widths[key] + 1) for key in range(len(table_headers))] # noqa 

74 separator = [f':{v}' for v in separator_cells] 

75 separator_display = f'|{"|".join(separator)}|' 

76 

77 dows = [] 

78 for dow in selection: 

79 dows.append([str(v).ljust(widths[k]) for k, v in enumerate(dow)]) 

80 

81 rows_display = [f'| {" | ".join(v for v in row)} |' for row in dows] 

82 

83 semantics = f'<!-- anchor: {tuple(str(e) if e is not None else "" for e in table_caption_data)}-->' 

84 source = f'<!-- source: {pathlib.Path(filename)}-->' 

85 checksum = f'<!-- s-hash: sha512:{hash_file(pathlib.Path(filename))}-->' 

86 the_table = '\n'.join([semantics] + [header] + [separator_display] + rows_display + [source] + [checksum]) 

87 

88 return the_table.replace('\r', '') if BASE_LF_ONLY else the_table