From 71f93394d3d8428d6722eed3bea325ea66df10f4 Mon Sep 17 00:00:00 2001 From: tadeubas Date: Sat, 25 Nov 2023 14:27:38 -0300 Subject: [PATCH 1/3] code review + one more test --- src/krux/qr.py | 9 +++------ tests/test_qr.py | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/krux/qr.py b/src/krux/qr.py index bac6053c3..3fdd3d865 100644 --- a/src/krux/qr.py +++ b/src/krux/qr.py @@ -185,10 +185,9 @@ def max_qr_bytes(max_width): max_width -= 2 # Subtract frame width qr_version = (max_width - 17) // 4 try: - capacity = QR_CAPACITY[qr_version - 1] + return QR_CAPACITY[qr_version - 1] except: - capacity = QR_CAPACITY[-1] - return capacity + return QR_CAPACITY[-1] def find_min_num_parts(data, max_width, qr_format): @@ -217,9 +216,7 @@ def find_min_num_parts(data, max_width, qr_format): num_parts = (data_length + qr_capacity - 1) // qr_capacity # For UR, part size will be the input for "max_fragment_len" part_size = len(data.cbor) // num_parts - part_size = max( - part_size, UR_MIN_FRAGMENT_LENGTH - ) + part_size = max(part_size, UR_MIN_FRAGMENT_LENGTH) else: raise ValueError("Invalid format type") return num_parts, part_size diff --git a/tests/test_qr.py b/tests/test_qr.py index aa8117a17..08e5ff8ee 100644 --- a/tests/test_qr.py +++ b/tests/test_qr.py @@ -135,7 +135,7 @@ def test_to_qr_codes(mocker, m5stickv, tdata): for case in cases: mocker.patch( "krux.display.lcd", - new=mocker.MagicMock(width=mocker.MagicMock(return_value=case[2])) + new=mocker.MagicMock(width=mocker.MagicMock(return_value=case[2])), ) display = Display() qr_data_width = display.qr_data_width() @@ -154,7 +154,7 @@ def test_to_qr_codes(mocker, m5stickv, tdata): if i == total - 1: break except Exception as e: - print("Error:",e) + print("Error:", e) break i += 1 assert len(codes) == expected_parts @@ -168,3 +168,13 @@ def test_detect_plaintext_qr(mocker, m5stickv): ) detect_format(PLAINTEXT_QR_DATA) + + +def test_find_min_num_parts(m5stickv): + from krux.qr import find_min_num_parts + + with pytest.raises(ValueError) as raised_ex: + find_min_num_parts("", 10, "format unknown") + + assert raised_ex.type is ValueError + assert raised_ex.value.args[0] == "Invalid format type" From fb18d2826bd3b5c8200e0b3f78b2b7ec791e89c8 Mon Sep 17 00:00:00 2001 From: tadeubas Date: Sat, 25 Nov 2023 21:48:54 -0300 Subject: [PATCH 2/3] Fixed rare bug when viewing large addresses on small devices --- src/krux/pages/addresses.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/krux/pages/addresses.py b/src/krux/pages/addresses.py index 8d6d6c1ec..6df02d139 100644 --- a/src/krux/pages/addresses.py +++ b/src/krux/pages/addresses.py @@ -91,7 +91,7 @@ def list_address_type(self, addr_type=0): self.ctx.display.clear() self.ctx.display.draw_centered_text(loading_txt % (num_checked + 1)) - pos_str = str(num_checked + 1) + ". " + pos_str = str(num_checked + 1) + "." + " " # thin space qr_title = pos_str + addr items.append( ( From be0be5bda648746ddd2f945f83ed05aec2b53773 Mon Sep 17 00:00:00 2001 From: tadeubas Date: Sun, 26 Nov 2023 23:09:15 -0300 Subject: [PATCH 3/3] Fixed multi-part UR progress indication --- src/krux/camera.py | 4 ++-- src/krux/qr.py | 11 +++++++++-- tests/shared_mocks.py | 3 +++ tests/test_qr.py | 14 ++++++++++++-- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/krux/camera.py b/src/krux/camera.py index 92cbf54e2..a900f55d6 100644 --- a/src/krux/camera.py +++ b/src/krux/camera.py @@ -205,8 +205,8 @@ def capture_qr_code_loop(self, callback): parser.parse(data) - if parser.parsed_count() > prev_parsed_count: - prev_parsed_count = parser.parsed_count() + if parser.processed_parts_count() > prev_parsed_count: + prev_parsed_count = parser.processed_parts_count() new_part = True if parser.is_complete(): diff --git a/src/krux/qr.py b/src/krux/qr.py index 3fdd3d865..8d4c81665 100644 --- a/src/krux/qr.py +++ b/src/krux/qr.py @@ -79,7 +79,14 @@ def parsed_count(self): if self.decoder.fountain_decoder.expected_part_indexes is None: return 1 if self.decoder.result is not None else 0 completion_pct = self.decoder.estimated_percent_complete() - return math.ceil(completion_pct * self.total_count()) + return math.ceil(completion_pct * self.total_count() / 2) + len( + self.decoder.fountain_decoder.received_part_indexes + ) + return len(self.parts) + + def processed_parts_count(self): + if self.format == FORMAT_UR: + return self.decoder.fountain_decoder.processed_parts_count return len(self.parts) def total_count(self): @@ -88,7 +95,7 @@ def total_count(self): # Single-part URs have no expected part indexes if self.decoder.fountain_decoder.expected_part_indexes is None: return 1 - return self.decoder.expected_part_count() + return self.decoder.expected_part_count() * 2 return self.total def parse(self, data): diff --git a/tests/shared_mocks.py b/tests/shared_mocks.py index 4b3ee1834..8eb78e42e 100644 --- a/tests/shared_mocks.py +++ b/tests/shared_mocks.py @@ -117,6 +117,9 @@ def total_count(self): def parsed_count(self): return len(self.parts) + def processed_parts_count(self): + return self.parsed_count() + def parse(self, part): if part not in self.parts: self.parts.append(part) diff --git a/tests/test_qr.py b/tests/test_qr.py index 08e5ff8ee..497009819 100644 --- a/tests/test_qr.py +++ b/tests/test_qr.py @@ -79,7 +79,10 @@ def test_parser(mocker, m5stickv, tdata): (FORMAT_UR, tdata.TEST_PARTS_FORMAT_SINGLEPART_UR), (FORMAT_UR, tdata.TEST_PARTS_FORMAT_MULTIPART_UR), ] + num = 0 for case in cases: + print("case: ", num) + num += 1 fmt = case[0] parts = case[1] @@ -89,7 +92,10 @@ def test_parser(mocker, m5stickv, tdata): assert parser.format == fmt - assert parser.total_count() == len(parts) + if num == 4: + assert parser.total_count() == len(parts) * 2 + else: + assert parser.total_count() == len(parts) if parser.format == FORMAT_UR: assert parser.parsed_count() > 0 else: @@ -103,7 +109,11 @@ def test_parser(mocker, m5stickv, tdata): # Re-parse the first part to test that redundant parts are ignored parser.parse(parts[0]) - assert parser.total_count() == len(parts) + if num == 4: + assert parser.total_count() == len(parts) * 2 + else: + assert parser.total_count() == len(parts) + if parser.format == FORMAT_UR: assert parser.parsed_count() > 0 else: