One more fix

This commit is contained in:
AuroraWright
2025-10-13 10:24:00 +02:00
parent b7c366137b
commit c666af2ed0

View File

@@ -296,7 +296,6 @@ class TextFiltering:
self.frame_stabilization = 0 if config.get_general('screen_capture_delay_secs') == -1 else config.get_general('screen_capture_frame_stabilization') self.frame_stabilization = 0 if config.get_general('screen_capture_delay_secs') == -1 else config.get_general('screen_capture_frame_stabilization')
self.line_recovery = config.get_general('screen_capture_line_recovery') self.line_recovery = config.get_general('screen_capture_line_recovery')
self.furigana_filter = config.get_general('screen_capture_furigana_filter') self.furigana_filter = config.get_general('screen_capture_furigana_filter')
self.recovered_lines_count = 0
self.last_frame_data = [None, None] self.last_frame_data = [None, None]
self.last_last_frame_data = [None, None] self.last_last_frame_data = [None, None]
self.stable_frame_data = None self.stable_frame_data = None
@@ -381,21 +380,21 @@ class TextFiltering:
if self.frame_stabilization == 0: if self.frame_stabilization == 0:
changed_lines = self._find_changed_lines_impl(current_result, self.last_frame_data[1]) changed_lines = self._find_changed_lines_impl(current_result, self.last_frame_data[1])
if changed_lines == None: if changed_lines == None:
return 0, None return 0, 0, None
changed_lines_total = len(changed_lines) changed_lines_count = len(changed_lines)
self.last_frame_data = (pil_image, copy.deepcopy(current_result)) self.last_frame_data = (pil_image, copy.deepcopy(current_result))
if changed_lines_total and config.get_general('output_format') != 'json': if changed_lines_count and config.get_general('output_format') != 'json':
changed_regions_image = self._create_changed_regions_image(pil_image, changed_lines, None, None) changed_regions_image = self._create_changed_regions_image(pil_image, changed_lines, None, None)
if not changed_regions_image: if not changed_regions_image:
logger.warning('Error occurred while creating the differential image.') logger.warning('Error occurred while creating the differential image.')
return 0, None return 0, 0, None
return changed_lines_total, changed_regions_image return changed_lines_count, 0, changed_regions_image
else: else:
return changed_lines_total, None return changed_lines_count, 0, None
changed_lines_stabilization = self._find_changed_lines_impl(current_result, self.last_frame_data[1]) changed_lines_stabilization = self._find_changed_lines_impl(current_result, self.last_frame_data[1])
if changed_lines_stabilization == None: if changed_lines_stabilization == None:
return 0, None return 0, 0, None
frames_match = len(changed_lines_stabilization) == 0 frames_match = len(changed_lines_stabilization) == 0
@@ -403,21 +402,21 @@ class TextFiltering:
if frames_match: if frames_match:
if self.processed_stable_frame: if self.processed_stable_frame:
return 0, None return 0, 0, None
if time.time() - self.frame_stabilization_timestamp < self.frame_stabilization: if time.time() - self.frame_stabilization_timestamp < self.frame_stabilization:
return 0, None return 0, 0, None
changed_lines = self._find_changed_lines_impl(current_result, self.stable_frame_data) changed_lines = self._find_changed_lines_impl(current_result, self.stable_frame_data)
if self.line_recovery and self.last_last_frame_data: if self.line_recovery and self.last_last_frame_data:
logger.debug(f'Checking for missed lines') logger.debug(f'Checking for missed lines')
recovered_lines = self._find_changed_lines_impl(self.last_last_frame_data[1], self.stable_frame_data, current_result) recovered_lines = self._find_changed_lines_impl(self.last_last_frame_data[1], self.stable_frame_data, current_result)
self.recovered_lines_count = len(recovered_lines) if recovered_lines else 0 recovered_lines_count = len(recovered_lines) if recovered_lines else 0
else: else:
self.recovered_lines_count = 0 recovered_lines_count = 0
recovered_lines = [] recovered_lines = []
self.processed_stable_frame = True self.processed_stable_frame = True
self.stable_frame_data = copy.deepcopy(current_result) self.stable_frame_data = copy.deepcopy(current_result)
changed_lines_total = len(changed_lines) + self.recovered_lines_count changed_lines_count = len(changed_lines)
if changed_lines_total and config.get_general('output_format') != 'json': if (changed_lines_count or recovered_lines_count) and config.get_general('output_format') != 'json':
if recovered_lines: if recovered_lines:
changed_regions_image = self._create_changed_regions_image(pil_image, changed_lines, self.last_last_frame_data[0], recovered_lines) changed_regions_image = self._create_changed_regions_image(pil_image, changed_lines, self.last_last_frame_data[0], recovered_lines)
else: else:
@@ -425,17 +424,16 @@ class TextFiltering:
if not changed_regions_image: if not changed_regions_image:
logger.warning('Error occurred while creating the differential image.') logger.warning('Error occurred while creating the differential image.')
return 0, None return 0, 0, None
return changed_lines_total, changed_regions_image return changed_lines_count, recovered_lines_count, changed_regions_image
else: else:
return changed_lines_total, None return changed_lines_count, recovered_lines_count, None
else: else:
self.last_last_frame_data = self.last_frame_data self.last_last_frame_data = self.last_frame_data
self.last_frame_data = (pil_image, copy.deepcopy(current_result)) self.last_frame_data = (pil_image, copy.deepcopy(current_result))
self.recovered_lines_count = 0
self.processed_stable_frame = False self.processed_stable_frame = False
self.frame_stabilization_timestamp = time.time() self.frame_stabilization_timestamp = time.time()
return 0, None return 0, 0, None
def _find_changed_lines_impl(self, current_result, previous_result, next_result=None): def _find_changed_lines_impl(self, current_result, previous_result, next_result=None):
if not current_result: if not current_result:
@@ -486,16 +484,16 @@ class TextFiltering:
if not text_similar: if not text_similar:
if next_result != None: if next_result != None:
logger.opt(ansi=True).debug(f"<red>Recovered line: '{current_text}'</red>") logger.opt(colors=True).debug(f"<red>Recovered line: '{current_text}'</red>")
changed_lines.append(current_line) changed_lines.append(current_line)
return changed_lines if processed_valid_line else None return changed_lines if processed_valid_line else None
def _find_changed_lines_text(self, current_result, current_result_ocr, two_pass_processing_active): def _find_changed_lines_text(self, current_result, current_result_ocr, two_pass_processing_active, recovered_lines_count):
frame_stabilization_active = self.frame_stabilization != 0 frame_stabilization_active = self.frame_stabilization != 0
if (not frame_stabilization_active) or two_pass_processing_active: if (not frame_stabilization_active) or two_pass_processing_active:
changed_lines = self._find_changed_lines_text_impl(current_result, current_result_ocr, self.last_frame_text, None, True, frame_stabilization_active) changed_lines = self._find_changed_lines_text_impl(current_result, current_result_ocr, self.last_frame_text, None, True, recovered_lines_count)
self.last_frame_text = current_result self.last_frame_text = current_result
return changed_lines return changed_lines
@@ -515,12 +513,12 @@ class TextFiltering:
if self.line_recovery and self.last_last_frame_text: if self.line_recovery and self.last_last_frame_text:
logger.debug(f'Checking for missed lines') logger.debug(f'Checking for missed lines')
recovered_lines = self._find_changed_lines_text_impl(self.last_last_frame_text, None, self.stable_frame_text, current_result, True, False) recovered_lines = self._find_changed_lines_text_impl(self.last_last_frame_text, None, self.stable_frame_text, current_result, True, False)
self.recovered_lines_count = len(recovered_lines) if recovered_lines else 0 recovered_lines_count = len(recovered_lines) if recovered_lines else 0
else: else:
self.recovered_lines_count = 0 recovered_lines_count = 0
recovered_lines = [] recovered_lines = []
recovered_lines.extend(current_result) recovered_lines.extend(current_result)
changed_lines = self._find_changed_lines_text_impl(recovered_lines, current_result_ocr, self.stable_frame_text, None, True, frame_stabilization_active) changed_lines = self._find_changed_lines_text_impl(recovered_lines, current_result_ocr, self.stable_frame_text, None, True, recovered_lines_count)
self.processed_stable_frame = True self.processed_stable_frame = True
self.stable_frame_text = current_result self.stable_frame_text = current_result
return changed_lines return changed_lines
@@ -531,7 +529,7 @@ class TextFiltering:
self.frame_stabilization_timestamp = time.time() self.frame_stabilization_timestamp = time.time()
return [] return []
def _find_changed_lines_text_impl(self, current_result, current_result_ocr, previous_result, next_result, filtering, skip_recovered_lines): def _find_changed_lines_text_impl(self, current_result, current_result_ocr, previous_result, next_result, filtering, recovered_lines_count):
if len(current_result) == 0: if len(current_result) == 0:
return [] return []
@@ -557,7 +555,7 @@ class TextFiltering:
all_previous_text = ''.join(all_previous_text_spliced) all_previous_text = ''.join(all_previous_text_spliced)
logger.debug(f"Previous text: '{all_previous_text_spliced}'") logger.opt(colors=True).debug(f"<magenta>Previous text: '{all_previous_text_spliced}'</magenta>")
first = True first = True
processed_valid_line = False processed_valid_line = False
@@ -573,22 +571,21 @@ class TextFiltering:
else: else:
text_similar = current_text in all_previous_text text_similar = current_text in all_previous_text
logger.debug(f"Current line: '{current_text}' Similar: '{text_similar}'") logger.opt(colors=True).debug(f"<magenta>Current line: '{current_text}' Similar: '{text_similar}'</magenta>")
if text_similar: if text_similar:
continue continue
if skip_recovered_lines and self.recovered_lines_count > 0: if recovered_lines_count > 0:
# Check if any subsequent lines start with current_text if any(line.startswith(current_text) for line in current_lines):
if any(line.startswith(current_text) for line in current_lines[i+1:]): logger.opt(colors=True).debug(f"<magenta>Skipping recovered line: '{current_text}'</magenta>")
logger.debug(f"Skipping recovered line: '{current_text}'") recovered_lines_count -= 1
self.recovered_lines_count -= 1
continue continue
changed_line = current_result[i] changed_line = current_result[i]
if next_result != None: if next_result != None:
logger.opt(ansi=True).debug(f"<red>Recovered line: '{changed_line}'</red>") logger.opt(colors=True).debug(f"<red>Recovered line: '{changed_line}'</red>")
if current_lines_ocr: if current_lines_ocr:
current_line_bbox = current_lines_ocr[i].bounding_box current_line_bbox = current_lines_ocr[i].bounding_box
@@ -605,12 +602,12 @@ class TextFiltering:
below_line_bbox = current_lines_ocr[j].bounding_box below_line_bbox = current_lines_ocr[j].bounding_box
below_line_text = current_lines[j] below_line_text = current_lines[j]
logger.debug(f"Furigana check against line: '{below_line_text}'") logger.opt(colors=True).debug(f"<magenta>Furigana check against line: '{below_line_text}'</magenta>")
# Check if the line is taller # Check if the line is taller
height_threshold = below_line_bbox.height * 0.6 height_threshold = below_line_bbox.height * 0.7
is_smaller = current_line_bbox.height < height_threshold is_smaller = current_line_bbox.height < height_threshold
logger.debug(f"Furigana check height: '{height_threshold}' '{current_line_bbox.height}'") logger.opt(colors=True).debug(f"<magenta>Furigana check height: '{below_line_bbox.height}' '{current_line_bbox.height}'</magenta>")
if not is_smaller: if not is_smaller:
continue continue
@@ -619,16 +616,16 @@ class TextFiltering:
if not below_has_kanji: if not below_has_kanji:
continue continue
vertical_threshold = below_line_bbox.height * 0.8 vertical_threshold = below_line_bbox.height + current_line_bbox.height
vertical_distance = below_line_bbox.center_y - current_line_bbox.center_y vertical_distance = below_line_bbox.center_y - current_line_bbox.center_y
horizontal_overlap = self._check_horizontal_overlap(current_line_bbox, below_line_bbox) horizontal_overlap = self._check_horizontal_overlap(current_line_bbox, below_line_bbox)
logger.debug(f"Furigana check position: '{vertical_threshold}' '{vertical_distance}' '{horizontal_overlap}'") logger.opt(colors=True).debug(f"<magenta>Furigana check position: '{vertical_threshold}' '{vertical_distance}' '{horizontal_overlap}'</magenta>")
# If vertically close and horizontally aligned, it's likely furigana # If vertically close and horizontally aligned, it's likely furigana
if (0 < vertical_distance < vertical_threshold * 2 and horizontal_overlap > 0.3): # At least 30% horizontal overlap if (0 < vertical_distance < vertical_threshold and horizontal_overlap > 0.5):
is_furigana = True is_furigana = True
logger.debug(f"Skipping furigana line: '{current_text}' above line: '{below_line_text}'") logger.opt(colors=True).debug(f"<magenta>Skipping furigana line: '{current_text}' above line: '{below_line_text}'</magenta>")
break break
if is_furigana: if is_furigana:
@@ -640,9 +637,9 @@ class TextFiltering:
if filtering and all_previous_text: if filtering and all_previous_text:
overlap = self._find_overlap(all_previous_text, current_text) overlap = self._find_overlap(all_previous_text, current_text)
if overlap and len(current_text) > len(overlap): if overlap and len(current_text) > len(overlap):
logger.debug(f"Found overlap: '{overlap}'") logger.opt(colors=True).debug(f"<magenta>Found overlap: '{overlap}'</magenta>")
changed_line = self._cut_at_overlap(changed_line, overlap) changed_line = self._cut_at_overlap(changed_line, overlap)
logger.debug(f"After cutting: '{changed_line}'") logger.opt(colors=True).debug(f"<magenta>After cutting: '{changed_line}'</magenta>")
changed_lines.append(changed_line) changed_lines.append(changed_line)
return changed_lines if processed_valid_line else [] return changed_lines if processed_valid_line else []
@@ -672,7 +669,7 @@ class TextFiltering:
overlap_pattern = r'.*?'.join(pattern_parts) overlap_pattern = r'.*?'.join(pattern_parts)
full_pattern = r'^.*?' + overlap_pattern full_pattern = r'^.*?' + overlap_pattern
logger.debug(f"Cut regex: '{full_pattern}'") logger.opt(colors=True).debug(f"<magenta>Cut regex: '{full_pattern}'</magenta>")
match = re.search(full_pattern, current_line) match = re.search(full_pattern, current_line)
if match: if match:
@@ -813,7 +810,7 @@ class ScreenshotThread(threading.Thread):
if self.screencapture_mode != 0: if self.screencapture_mode != 0:
self.sct_params = {'top': coord_top, 'left': coord_left, 'width': coord_width, 'height': coord_height} self.sct_params = {'top': coord_top, 'left': coord_left, 'width': coord_width, 'height': coord_height}
logger.opt(ansi=True).info(f'Selected coordinates: {coord_left},{coord_top},{coord_width},{coord_height}') logger.info(f'Selected coordinates: {coord_left},{coord_top},{coord_width},{coord_height}')
else: else:
self.screen_capture_only_active_windows = config.get_general('screen_capture_only_active_windows') self.screen_capture_only_active_windows = config.get_general('screen_capture_only_active_windows')
self.window_area_coordinates = None self.window_area_coordinates = None
@@ -853,7 +850,7 @@ class ScreenshotThread(threading.Thread):
if self.screen_capture_only_active_windows: if self.screen_capture_only_active_windows:
self.macos_window_tracker_instance = threading.Thread(target=self.macos_window_tracker) self.macos_window_tracker_instance = threading.Thread(target=self.macos_window_tracker)
self.macos_window_tracker_instance.start() self.macos_window_tracker_instance.start()
logger.opt(ansi=True).info(f'Selected window: {window_title}') logger.info(f'Selected window: {window_title}')
elif sys.platform == 'win32': elif sys.platform == 'win32':
self.window_handle, window_title = self.get_windows_window_handle(screen_capture_area) self.window_handle, window_title = self.get_windows_window_handle(screen_capture_area)
@@ -864,7 +861,7 @@ class ScreenshotThread(threading.Thread):
self.windows_window_tracker_instance = threading.Thread(target=self.windows_window_tracker) self.windows_window_tracker_instance = threading.Thread(target=self.windows_window_tracker)
self.windows_window_tracker_instance.start() self.windows_window_tracker_instance.start()
logger.opt(ansi=True).info(f'Selected window: {window_title}') logger.info(f'Selected window: {window_title}')
else: else:
raise ValueError('Window capture is only currently supported on Windows and macOS') raise ValueError('Window capture is only currently supported on Windows and macOS')
@@ -872,7 +869,7 @@ class ScreenshotThread(threading.Thread):
if screen_capture_window_area != 'window': if screen_capture_window_area != 'window':
if len(screen_capture_window_area.split(',')) == 4: if len(screen_capture_window_area.split(',')) == 4:
x, y, x2, y2 = [int(c.strip()) for c in screen_capture_window_area.split(',')] x, y, x2, y2 = [int(c.strip()) for c in screen_capture_window_area.split(',')]
logger.opt(ansi=True).info(f'Selected window coordinates: {x},{y},{x2},{y2}') logger.info(f'Selected window coordinates: {x},{y},{x2},{y2}')
self.window_area_coordinates = (img.size, (x, y, x2, y2)) self.window_area_coordinates = (img.size, (x, y, x2, y2))
elif screen_capture_window_area == '': elif screen_capture_window_area == '':
self.launch_coordinate_picker(False, False) self.launch_coordinate_picker(False, False)
@@ -1043,7 +1040,7 @@ class ScreenshotThread(threading.Thread):
if self.window_area_coordinates: if self.window_area_coordinates:
if img.size != self.window_area_coordinates[0]: if img.size != self.window_area_coordinates[0]:
self.window_area_coordinates = None self.window_area_coordinates = None
logger.opt(ansi=True).warning('Window size changed, discarding area selection') logger.warning('Window size changed, discarding area selection')
else: else:
img = img.crop(self.window_area_coordinates[1]) img = img.crop(self.window_area_coordinates[1])
else: else:
@@ -1061,17 +1058,17 @@ class ScreenshotThread(threading.Thread):
def launch_coordinate_picker(self, init, must_return): def launch_coordinate_picker(self, init, must_return):
if init: if init:
logger.opt(ansi=True).info('Preloading screen coordinate picker') logger.info('Preloading screen coordinate picker')
get_screen_selection(True, True) get_screen_selection(True, True)
return return
if self.screencapture_mode != 2: if self.screencapture_mode != 2:
logger.opt(ansi=True).info('Launching screen coordinate picker') logger.info('Launching screen coordinate picker')
screen_selection = get_screen_selection(None, self.coordinate_selector_combo_enabled) screen_selection = get_screen_selection(None, self.coordinate_selector_combo_enabled)
if not screen_selection: if not screen_selection:
if on_init: if on_init:
raise ValueError('Picker window was closed or an error occurred') raise ValueError('Picker window was closed or an error occurred')
else: else:
logger.opt(ansi=True).warning('Picker window was closed or an error occurred, leaving settings unchanged') logger.warning('Picker window was closed or an error occurred, leaving settings unchanged')
return return
screen_capture_monitor = screen_selection['monitor'] screen_capture_monitor = screen_selection['monitor']
x, y, coord_width, coord_height = screen_selection['coordinates'] x, y, coord_width, coord_height = screen_selection['coordinates']
@@ -1079,29 +1076,29 @@ class ScreenshotThread(threading.Thread):
coord_top = screen_capture_monitor['top'] + y coord_top = screen_capture_monitor['top'] + y
coord_left = screen_capture_monitor['left'] + x coord_left = screen_capture_monitor['left'] + x
else: else:
logger.opt(ansi=True).info('Selection is empty, selecting whole screen') logger.info('Selection is empty, selecting whole screen')
coord_left = screen_capture_monitor['left'] coord_left = screen_capture_monitor['left']
coord_top = screen_capture_monitor['top'] coord_top = screen_capture_monitor['top']
coord_width = screen_capture_monitor['width'] coord_width = screen_capture_monitor['width']
coord_height = screen_capture_monitor['height'] coord_height = screen_capture_monitor['height']
self.sct_params = {'top': coord_top, 'left': coord_left, 'width': coord_width, 'height': coord_height} self.sct_params = {'top': coord_top, 'left': coord_left, 'width': coord_width, 'height': coord_height}
logger.opt(ansi=True).info(f'Selected coordinates: {coord_left},{coord_top},{coord_width},{coord_height}') logger.info(f'Selected coordinates: {coord_left},{coord_top},{coord_width},{coord_height}')
else: else:
self.window_area_coordinates = None self.window_area_coordinates = None
img = self.take_screenshot() img = self.take_screenshot()
logger.opt(ansi=True).info('Launching window coordinate picker') logger.info('Launching window coordinate picker')
window_selection = get_screen_selection(img, self.coordinate_selector_combo_enabled) window_selection = get_screen_selection(img, self.coordinate_selector_combo_enabled)
if not window_selection: if not window_selection:
logger.opt(ansi=True).warning('Picker window was closed or an error occurred, selecting whole window') logger.warning('Picker window was closed or an error occurred, selecting whole window')
else: else:
x, y, coord_width, coord_height = window_selection['coordinates'] x, y, coord_width, coord_height = window_selection['coordinates']
if coord_width > 0 and coord_height > 0: if coord_width > 0 and coord_height > 0:
x2 = x + coord_width x2 = x + coord_width
y2 = y + coord_height y2 = y + coord_height
logger.opt(ansi=True).info(f'Selected window coordinates: {x},{y},{x2},{y2}') logger.info(f'Selected window coordinates: {x},{y},{x2},{y2}')
self.window_area_coordinates = (img.size, (x, y, x2, y2)) self.window_area_coordinates = (img.size, (x, y, x2, y2))
else: else:
logger.opt(ansi=True).info('Selection is empty, selecting whole window') logger.info('Selection is empty, selecting whole window')
def run(self): def run(self):
if self.screencapture_mode != 2: if self.screencapture_mode != 2:
@@ -1186,18 +1183,18 @@ class SecondPassThread:
def _process_ocr(self): def _process_ocr(self):
while self.running and not terminated: while self.running and not terminated:
try: try:
img, engine_instance = self.input_queue.get(timeout=0.1) img, engine_instance, recovered_lines_count = self.input_queue.get(timeout=30)
start_time = time.time() start_time = time.time()
res, result_data = engine_instance(img) res, result_data = engine_instance(img)
end_time = time.time() end_time = time.time()
self.output_queue.put((engine_instance.readable_name, res, result_data, end_time - start_time)) self.output_queue.put((engine_instance.readable_name, res, result_data, end_time - start_time, recovered_lines_count))
except queue.Empty: except queue.Empty:
continue continue
def submit_task(self, img, engine_instance): def submit_task(self, img, engine_instance, recovered_lines_count):
self.input_queue.put((img, engine_instance)) self.input_queue.put((img, engine_instance, recovered_lines_count))
def get_result(self): def get_result(self):
try: try:
@@ -1251,23 +1248,23 @@ class OutputResult:
end_time = time.time() end_time = time.time()
if not res2: if not res2:
logger.opt(ansi=True).warning(f'<{engine_color}>{engine_instance_2.readable_name}</{engine_color}> reported an error after {end_time - start_time:0.03f}s: {result_data_2}') logger.opt(colors=True).warning(f'<{engine_color}>{engine_instance_2.readable_name}</{engine_color}> reported an error after {end_time - start_time:0.03f}s: {result_data_2}')
else: else:
changed_lines_count, changed_regions_image = self.filtering._find_changed_lines(img_or_path, result_data_2) changed_lines_count, recovered_lines_count, changed_regions_image = self.filtering._find_changed_lines(img_or_path, result_data_2)
if changed_lines_count: if changed_lines_count or recovered_lines_count:
logger.opt(ansi=True).info(f"<{engine_color}>{engine_instance_2.readable_name}</{engine_color}> found {changed_lines_count} changed line(s) in {end_time - start_time:0.03f}s, re-OCRing with <{engine_color}>{engine_instance.readable_name}</{engine_color}>") logger.opt(colors=True).info(f"<{engine_color}>{engine_instance_2.readable_name}</{engine_color}> found {changed_lines_count + recovered_lines_count} changed line(s) in {end_time - start_time:0.03f}s, re-OCRing with <{engine_color}>{engine_instance.readable_name}</{engine_color}>")
if output_format != 'json': if output_format != 'json':
if changed_regions_image: if changed_regions_image:
img_or_path = changed_regions_image img_or_path = changed_regions_image
self.second_pass_thread.start() self.second_pass_thread.start()
self.second_pass_thread.submit_task(img_or_path, engine_instance) self.second_pass_thread.submit_task(img_or_path, engine_instance, recovered_lines_count)
second_pass_result = self.second_pass_thread.get_result() second_pass_result = self.second_pass_thread.get_result()
if second_pass_result: if second_pass_result:
engine_name, res, result_data, processing_time = second_pass_result engine_name, res, result_data, processing_time, recovered_lines_count = second_pass_result
else: else:
return return
else: else:
@@ -1279,9 +1276,10 @@ class OutputResult:
end_time = time.time() end_time = time.time()
processing_time = end_time - start_time processing_time = end_time - start_time
engine_name = engine_instance.readable_name engine_name = engine_instance.readable_name
recovered_lines_count = 0
if not res: if not res:
logger.opt(ansi=True).warning(f'<{engine_color}>{engine_name}</{engine_color}> reported an error after {processing_time:0.03f}s: {result_data}') logger.opt(colors=True).warning(f'<{engine_color}>{engine_name}</{engine_color}> reported an error after {processing_time:0.03f}s: {result_data}')
return return
verbosity = config.get_general('verbosity') verbosity = config.get_general('verbosity')
@@ -1303,7 +1301,7 @@ class OutputResult:
if result_data_text != None: if result_data_text != None:
if filter_text: if filter_text:
text_to_process = self.filtering._find_changed_lines_text(result_data_text, result_data, two_pass_processing_active) text_to_process = self.filtering._find_changed_lines_text(result_data_text, result_data, two_pass_processing_active, recovered_lines_count)
if self.screen_capture_periodic and len(text_to_process) == 0: if self.screen_capture_periodic and len(text_to_process) == 0:
return return
output_string = self._post_process(text_to_process, True) output_string = self._post_process(text_to_process, True)
@@ -1311,7 +1309,7 @@ class OutputResult:
output_string = self._post_process(result_data_text, False) output_string = self._post_process(result_data_text, False)
log_message = output_string log_message = output_string
if output_format == 'json': if output_format == 'json':
logger.warning(f"Engine '{engine_instance.name}' does not support JSON output. Falling back to text.") logger.opt(colors=True).warning(f"<{engine_color}>{engine_name}</{engine_color}> does not support JSON output. Falling back to text.")
if verbosity != 0: if verbosity != 0:
if verbosity < -1: if verbosity < -1:
@@ -1321,7 +1319,7 @@ class OutputResult:
else: else:
log_message_terminal = ': ' + (log_message if len(log_message) <= verbosity else log_message[:verbosity] + '[...]') log_message_terminal = ': ' + (log_message if len(log_message) <= verbosity else log_message[:verbosity] + '[...]')
logger.opt(ansi=True).info(f'Text recognized in {processing_time:0.03f}s using <{engine_color}>{engine_name}</{engine_color}>{log_message_terminal}') logger.opt(colors=True).info(f'Text recognized in {processing_time:0.03f}s using <{engine_color}>{engine_name}</{engine_color}>{log_message_terminal}')
if notify and config.get_general('notifications'): if notify and config.get_general('notifications'):
notifier.send(title='owocr', message='Text recognized: ' + log_message, urgency=get_notification_urgency()) notifier.send(title='owocr', message='Text recognized: ' + log_message, urgency=get_notification_urgency())
@@ -1373,7 +1371,7 @@ def engine_change_handler(user_input='s', is_combo=True):
if is_combo: if is_combo:
notifier.send(title='owocr', message=f'Switched to {new_engine_name}', urgency=get_notification_urgency()) notifier.send(title='owocr', message=f'Switched to {new_engine_name}', urgency=get_notification_urgency())
engine_color = config.get_general('engine_color') engine_color = config.get_general('engine_color')
logger.opt(ansi=True).info(f'Switched to <{engine_color}>{new_engine_name}</{engine_color}>!') logger.opt(colors=True).info(f'Switched to <{engine_color}>{new_engine_name}</{engine_color}>!')
def user_input_thread_run(): def user_input_thread_run():
@@ -1621,7 +1619,7 @@ def run():
logger.error(f"Please choose one of: {', '.join(supported_engines)}") logger.error(f"Please choose one of: {', '.join(supported_engines)}")
sys.exit(1) sys.exit(1)
logger.opt(ansi=True).info(f"Reading from {' and '.join(read_from_readable)}, writing to {write_to_readable} using <{engine_color}>{engine_instances[engine_index].readable_name}</{engine_color}>{' (paused)' if paused else ''}") logger.opt(colors=True).info(f"Reading from {' and '.join(read_from_readable)}, writing to {write_to_readable} using <{engine_color}>{engine_instances[engine_index].readable_name}</{engine_color}>{' (paused)' if paused else ''}")
while not terminated: while not terminated:
start_time = time.time() start_time = time.time()