GameSentenceMiner 2.12.9__py3-none-any.whl → 2.12.11__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
GameSentenceMiner/gsm.py CHANGED
@@ -1,3 +1,4 @@
1
+ import time
1
2
  import asyncio
2
3
  import subprocess
3
4
  import sys
@@ -7,12 +8,6 @@ import warnings
7
8
 
8
9
  os.environ.pop('TCL_LIBRARY', None)
9
10
 
10
- from GameSentenceMiner.util.gsm_utils import wait_for_stable_file, make_unique_file_name, run_new_thread
11
- from GameSentenceMiner.util.communication.send import send_restart_signal
12
- from GameSentenceMiner.util.downloader.download_tools import download_obs_if_needed, download_ffmpeg_if_needed
13
- from GameSentenceMiner.vad import vad_processor
14
- from GameSentenceMiner.util.model import VADResult
15
- import time
16
11
 
17
12
  try:
18
13
  import os.path
@@ -27,7 +22,11 @@ try:
27
22
  from watchdog.observers import Observer
28
23
  import psutil
29
24
 
30
-
25
+ from GameSentenceMiner.util.model import VADResult
26
+ from GameSentenceMiner.vad import vad_processor
27
+ from GameSentenceMiner.util.downloader.download_tools import download_obs_if_needed, download_ffmpeg_if_needed
28
+ from GameSentenceMiner.util.communication.send import send_restart_signal
29
+ from GameSentenceMiner.util.gsm_utils import wait_for_stable_file, make_unique_file_name, run_new_thread
31
30
  from GameSentenceMiner import anki
32
31
  from GameSentenceMiner import config_gui
33
32
  from GameSentenceMiner.util import configuration, notification, ffmpeg
@@ -46,7 +45,8 @@ try:
46
45
  from GameSentenceMiner.web.texthooking_page import run_text_hooker_page
47
46
  except Exception as e:
48
47
  from GameSentenceMiner.util.configuration import logger, is_linux, is_windows
49
- logger.info("Something bad happened during import/initialization, closing in 5 seconds")
48
+ logger.info(
49
+ "Something bad happened during import/initialization, closing in 5 seconds")
50
50
  logger.exception(e)
51
51
  time.sleep(5)
52
52
  sys.exit(1)
@@ -67,11 +67,11 @@ class VideoToAudioHandler(FileSystemEventHandler):
67
67
  def __init__(self):
68
68
  super().__init__()
69
69
 
70
-
71
70
  def on_created(self, event):
72
71
  if event.is_directory or ("Replay" not in event.src_path and "GSM" not in event.src_path):
73
72
  return
74
- if event.src_path.endswith(".mkv") or event.src_path.endswith(".mp4"): # Adjust based on your OBS output format
73
+ # Adjust based on your OBS output format
74
+ if event.src_path.endswith(".mkv") or event.src_path.endswith(".mp4"):
75
75
  logger.info(f"MKV {event.src_path} FOUND, RUNNING LOGIC")
76
76
  wait_for_stable_file(event.src_path)
77
77
  self.process_replay(event.src_path)
@@ -85,15 +85,19 @@ class VideoToAudioHandler(FileSystemEventHandler):
85
85
  mined_line = None
86
86
  gsm_state.previous_replay = video_path
87
87
  if gsm_state.line_for_audio or gsm_state.line_for_screenshot:
88
- handle_texthooker_button(video_path, get_audio_from_video=VideoToAudioHandler.get_audio)
88
+ handle_texthooker_button(
89
+ video_path, get_audio_from_video=VideoToAudioHandler.get_audio)
89
90
  return
90
91
  try:
91
92
  if anki.card_queue and len(anki.card_queue) > 0:
92
- last_note, anki_card_creation_time, selected_lines = anki.card_queue.pop(0)
93
+ last_note, anki_card_creation_time, selected_lines = anki.card_queue.pop(
94
+ 0)
93
95
  elif get_config().features.backfill_audio:
94
- last_note = anki.get_cards_by_sentence(gametext.current_line_after_regex)
96
+ last_note = anki.get_cards_by_sentence(
97
+ gametext.current_line_after_regex)
95
98
  else:
96
- logger.info("Replay buffer initiated externally. Skipping processing.")
99
+ logger.info(
100
+ "Replay buffer initiated externally. Skipping processing.")
97
101
  skip_delete = True
98
102
  return
99
103
 
@@ -102,7 +106,8 @@ class VideoToAudioHandler(FileSystemEventHandler):
102
106
  if get_config().anki.update_anki:
103
107
  last_note = anki.get_last_anki_card()
104
108
  if get_config().features.backfill_audio:
105
- last_note = anki.get_cards_by_sentence(gametext.current_line_after_regex)
109
+ last_note = anki.get_cards_by_sentence(
110
+ gametext.current_line_after_regex)
106
111
 
107
112
  # Get Info of line mined
108
113
  line_cutoff = None
@@ -124,7 +129,8 @@ class VideoToAudioHandler(FileSystemEventHandler):
124
129
  if get_config().obs.minimum_replay_size and not ffmpeg.is_video_big_enough(video_path,
125
130
  get_config().obs.minimum_replay_size):
126
131
  logger.debug("Checking if video is big enough")
127
- notification.send_check_obs_notification(reason="Video may be empty, check scene in OBS.")
132
+ notification.send_check_obs_notification(
133
+ reason="Video may be empty, check scene in OBS.")
128
134
  logger.error(
129
135
  f"Video was unusually small, potentially empty! Check OBS for Correct Scene Settings! Path: {video_path}")
130
136
  return
@@ -132,7 +138,8 @@ class VideoToAudioHandler(FileSystemEventHandler):
132
138
  if last_note:
133
139
  logger.debug(last_note.to_json())
134
140
  note = anki.get_initial_card_info(last_note, selected_lines)
135
- tango = last_note.get_field(get_config().anki.word_field) if last_note else ''
141
+ tango = last_note.get_field(
142
+ get_config().anki.word_field) if last_note else ''
136
143
 
137
144
  if get_config().anki.sentence_audio_field and get_config().audio.enabled:
138
145
  logger.debug("Attempting to get audio from video")
@@ -147,11 +154,14 @@ class VideoToAudioHandler(FileSystemEventHandler):
147
154
  vad_result = VADResult(True, 0, 0, '')
148
155
  vad_trimmed_audio = ""
149
156
  if not get_config().audio.enabled:
150
- logger.info("Audio is disabled in config, skipping audio processing!")
157
+ logger.info(
158
+ "Audio is disabled in config, skipping audio processing!")
151
159
  elif not get_config().anki.sentence_audio_field:
152
- logger.info("No SentenceAudio Field in config, skipping audio processing!")
160
+ logger.info(
161
+ "No SentenceAudio Field in config, skipping audio processing!")
153
162
 
154
- ss_timing = ffmpeg.get_screenshot_time(video_path, mined_line, vad_result=vad_result, doing_multi_line=bool(selected_lines), anki_card_creation_time=anki_card_creation_time)
163
+ ss_timing = ffmpeg.get_screenshot_time(video_path, mined_line, vad_result=vad_result, doing_multi_line=bool(
164
+ selected_lines), anki_card_creation_time=anki_card_creation_time)
155
165
  # prev_ss_timing = 0
156
166
  # if get_config().anki.previous_image_field and get_config().vad.do_vad_postprocessing:
157
167
  # prev_ss_timing = ffmpeg.get_screenshot_time(video_path, mined_line.prev,
@@ -164,19 +174,22 @@ class VideoToAudioHandler(FileSystemEventHandler):
164
174
  if get_config().anki.update_anki and last_note:
165
175
  anki.update_anki_card(
166
176
  last_note, note, audio_path=final_audio_output, video_path=video_path,
167
- tango=tango,
168
- should_update_audio=vad_result.success,
169
- ss_time=ss_timing,
170
- game_line=mined_line,
177
+ tango=tango,
178
+ should_update_audio=vad_result.success,
179
+ ss_time=ss_timing,
180
+ game_line=mined_line,
171
181
  selected_lines=selected_lines
172
182
  )
173
183
  elif get_config().features.notify_on_update and vad_result.success:
174
- notification.send_audio_generated_notification(vad_trimmed_audio)
184
+ notification.send_audio_generated_notification(
185
+ vad_trimmed_audio)
175
186
  except Exception as e:
176
187
  if mined_line:
177
188
  anki_results[mined_line.id] = AnkiUpdateResult.failure()
178
- logger.error(f"Failed Processing and/or adding to Anki: Reason {e}", exc_info=True)
179
- logger.debug(f"Some error was hit catching to allow further work to be done: {e}", exc_info=True)
189
+ logger.error(
190
+ f"Failed Processing and/or adding to Anki: Reason {e}", exc_info=True)
191
+ logger.debug(
192
+ f"Some error was hit catching to allow further work to be done: {e}", exc_info=True)
180
193
  notification.send_error_no_anki_update()
181
194
  finally:
182
195
  if not skip_delete:
@@ -189,7 +202,8 @@ class VideoToAudioHandler(FileSystemEventHandler):
189
202
 
190
203
  @staticmethod
191
204
  def get_audio(game_line, next_line_time, video_path, anki_card_creation_time=None, temporary=False, timing_only=False, mined_line=None):
192
- trimmed_audio = get_audio_and_trim(video_path, game_line, next_line_time, anki_card_creation_time)
205
+ trimmed_audio = get_audio_and_trim(
206
+ video_path, game_line, next_line_time, anki_card_creation_time)
193
207
  if temporary:
194
208
  return ffmpeg.convert_audio_to_wav_lossless(trimmed_audio)
195
209
  vad_trimmed_audio = make_unique_file_name(
@@ -197,7 +211,8 @@ class VideoToAudioHandler(FileSystemEventHandler):
197
211
  final_audio_output = make_unique_file_name(os.path.join(get_config().paths.audio_destination,
198
212
  f"{obs.get_current_game(sanitize=True)}.{get_config().audio.extension}"))
199
213
 
200
- vad_result = vad_processor.trim_audio_with_vad(trimmed_audio, vad_trimmed_audio, game_line)
214
+ vad_result = vad_processor.trim_audio_with_vad(
215
+ trimmed_audio, vad_trimmed_audio, game_line)
201
216
  if timing_only:
202
217
  return vad_result
203
218
  if vad_result.output_audio:
@@ -215,17 +230,21 @@ def initial_checks():
215
230
  subprocess.run(ffmpeg.ffmpeg_base_command_list)
216
231
  logger.debug("FFMPEG is installed and accessible.")
217
232
  except FileNotFoundError:
218
- logger.error("FFmpeg not found, please install it and add it to your PATH.")
233
+ logger.error(
234
+ "FFmpeg not found, please install it and add it to your PATH.")
219
235
  raise
220
236
 
221
237
 
222
238
  def register_hotkeys():
223
239
  if get_config().hotkeys.reset_line:
224
- keyboard.add_hotkey(get_config().hotkeys.reset_line, gametext.reset_line_hotkey_pressed)
240
+ keyboard.add_hotkey(get_config().hotkeys.reset_line,
241
+ gametext.reset_line_hotkey_pressed)
225
242
  if get_config().hotkeys.take_screenshot:
226
- keyboard.add_hotkey(get_config().hotkeys.take_screenshot, get_screenshot)
243
+ keyboard.add_hotkey(
244
+ get_config().hotkeys.take_screenshot, get_screenshot)
227
245
  if get_config().hotkeys.play_latest_audio:
228
- keyboard.add_hotkey(get_config().hotkeys.play_latest_audio, play_most_recent_audio)
246
+ keyboard.add_hotkey(
247
+ get_config().hotkeys.play_latest_audio, play_most_recent_audio)
229
248
 
230
249
 
231
250
  def get_screenshot():
@@ -273,7 +292,8 @@ def get_screenshot():
273
292
  # return image
274
293
 
275
294
  def create_image():
276
- image_path = os.path.join(os.path.dirname(__file__), "assets", "pickaxe.png")
295
+ image_path = os.path.join(os.path.dirname(
296
+ __file__), "assets", "pickaxe.png")
277
297
  return Image.open(image_path)
278
298
 
279
299
 
@@ -288,7 +308,8 @@ def play_most_recent_audio():
288
308
  gsm_state.line_for_audio = get_all_lines()[-1]
289
309
  obs.save_replay_buffer()
290
310
  else:
291
- logger.error("Feature Disabled. No audio or video player path set in config!")
311
+ logger.error(
312
+ "Feature Disabled. No audio or video player path set in config!")
292
313
 
293
314
 
294
315
  def open_log():
@@ -411,7 +432,8 @@ def close_obs():
411
432
  obs.disconnect_from_obs()
412
433
  if obs.obs_process_pid:
413
434
  try:
414
- subprocess.run(["taskkill", "/PID", str(obs.obs_process_pid), "/F"], check=True, capture_output=True, text=True)
435
+ subprocess.run(["taskkill", "/PID", str(obs.obs_process_pid),
436
+ "/F"], check=True, capture_output=True, text=True)
415
437
  print(f"OBS (PID {obs.obs_process_pid}) has been terminated.")
416
438
  if os.path.exists(obs.OBS_PID_FILE):
417
439
  os.remove(obs.OBS_PID_FILE)
@@ -476,6 +498,7 @@ def handle_exit():
476
498
 
477
499
  return _handle_exit
478
500
 
501
+
479
502
  def initialize(reloading=False):
480
503
  global obs_process
481
504
  if not reloading:
@@ -483,7 +506,8 @@ def initialize(reloading=False):
483
506
  download_obs_if_needed()
484
507
  download_ffmpeg_if_needed()
485
508
  if shutil.which("ffmpeg") is None:
486
- os.environ["PATH"] += os.pathsep + os.path.dirname(get_ffmpeg_path())
509
+ os.environ["PATH"] += os.pathsep + \
510
+ os.path.dirname(get_ffmpeg_path())
487
511
  if get_config().obs.enabled:
488
512
  if get_config().obs.open_obs:
489
513
  obs_process = obs.start_obs()
@@ -501,6 +525,7 @@ def initialize(reloading=False):
501
525
  # if WHISPER in (get_config().vad.backup_vad_model, get_config().vad.selected_vad_model):
502
526
  # whisper_helper.initialize_whisper_model()
503
527
 
528
+
504
529
  def initialize_async():
505
530
  tasks = [connect_websocket, run_tray]
506
531
  threads = []
@@ -509,6 +534,7 @@ def initialize_async():
509
534
  threads.append(run_new_thread(task))
510
535
  return threads
511
536
 
537
+
512
538
  def handle_websocket_message(message: Message):
513
539
  match FunctionName(message.function):
514
540
  case FunctionName.QUIT:
@@ -531,7 +557,9 @@ def handle_websocket_message(message: Message):
531
557
  case FunctionName.EXIT:
532
558
  exit_program(None, None)
533
559
  case _:
534
- logger.debug(f"unknown message from electron websocket: {message.to_json()}")
560
+ logger.debug(
561
+ f"unknown message from electron websocket: {message.to_json()}")
562
+
535
563
 
536
564
  def post_init2():
537
565
  asyncio.run(gametext.start_text_monitor())
@@ -546,7 +574,7 @@ def async_loop():
546
574
  logger.info("Post-Initialization started.")
547
575
  vad_processor.init()
548
576
  # if is_beangate:
549
- # await run_test_code()
577
+ # await run_test_code()
550
578
 
551
579
  asyncio.run(loop())
552
580
 
@@ -555,13 +583,16 @@ async def register_scene_switcher_callback():
555
583
  def scene_switcher_callback(scene):
556
584
  logger.info(f"Scene changed to: {scene}")
557
585
  gsm_state.current_game = obs.get_current_game(sanitize=True)
558
- all_configured_scenes = [config.scenes for config in get_master_config().configs.values()]
586
+ all_configured_scenes = [
587
+ config.scenes for config in get_master_config().configs.values()]
559
588
  print(all_configured_scenes)
560
- matching_configs = [name.strip() for name, config in config_instance.configs.items() if scene.strip() in config.scenes]
589
+ matching_configs = [name.strip() for name, config in config_instance.configs.items(
590
+ ) if scene.strip() in config.scenes]
561
591
  switch_to = None
562
592
 
563
593
  if len(matching_configs) > 1:
564
- selected_scene = settings_window.show_scene_selection(matched_configs=matching_configs)
594
+ selected_scene = settings_window.show_scene_selection(
595
+ matched_configs=matching_configs)
565
596
  if selected_scene:
566
597
  switch_to = selected_scene
567
598
  else:
@@ -579,7 +610,8 @@ async def register_scene_switcher_callback():
579
610
  update_icon()
580
611
 
581
612
  await obs.register_scene_change_callback(scene_switcher_callback)
582
-
613
+
614
+
583
615
  async def run_test_code():
584
616
  if get_config().wip.overlay_websocket_port and get_config().wip.overlay_websocket_send:
585
617
  boxes = await gametext.find_box_for_sentence("ちぇっ少しなの?")
@@ -587,48 +619,66 @@ async def run_test_code():
587
619
  await texthooking_page.send_word_coordinates_to_overlay(boxes)
588
620
  await asyncio.sleep(2)
589
621
 
622
+
590
623
  async def async_main(reloading=False):
591
- global root, settings_window
592
- initialize(reloading)
593
- logger.info("Script started.")
594
- root = ttk.Window(themename='darkly')
595
- settings_window = config_gui.ConfigApp(root)
596
- initialize_async()
597
- observer = Observer()
598
- observer.schedule(VideoToAudioHandler(), get_config().paths.folder_to_watch, recursive=False)
599
- observer.start()
600
- if not is_windows():
601
- register_hotkeys()
602
-
603
- run_new_thread(post_init2)
604
- run_new_thread(run_text_hooker_page)
605
- run_new_thread(async_loop)
606
-
607
- # Register signal handlers for graceful shutdown
608
- signal.signal(signal.SIGTERM, handle_exit()) # Handle `kill` commands
609
- signal.signal(signal.SIGINT, handle_exit()) # Handle Ctrl+C
610
- if is_windows():
611
- win32api.SetConsoleCtrlHandler(handle_exit())
612
-
613
- gsm_status.ready = True
614
- gsm_status.status = "Ready"
615
624
  try:
616
- if get_config().general.open_config_on_startup:
617
- root.after(50, settings_window.show)
618
- settings_window.add_save_hook(update_icon)
619
- settings_window.on_exit = exit_program
620
- root.mainloop()
621
- except KeyboardInterrupt:
622
- cleanup()
625
+ global root, settings_window
626
+ initialize(reloading)
627
+ logger.info("Script started.")
628
+ root = ttk.Window(themename='darkly')
629
+ settings_window = config_gui.ConfigApp(root)
630
+ initialize_async()
631
+ observer = Observer()
632
+ observer.schedule(VideoToAudioHandler(),
633
+ get_config().paths.folder_to_watch, recursive=False)
634
+ observer.start()
635
+ if is_windows():
636
+ register_hotkeys()
623
637
 
624
- try:
625
- observer.stop()
626
- observer.join()
638
+ run_new_thread(post_init2)
639
+ run_new_thread(run_text_hooker_page)
640
+ run_new_thread(async_loop)
641
+
642
+ # Register signal handlers for graceful shutdown
643
+ signal.signal(signal.SIGTERM, handle_exit()) # Handle `kill` commands
644
+ signal.signal(signal.SIGINT, handle_exit()) # Handle Ctrl+C
645
+ if is_windows():
646
+ win32api.SetConsoleCtrlHandler(handle_exit())
647
+
648
+ gsm_status.ready = True
649
+ gsm_status.status = "Ready"
650
+ try:
651
+ if get_config().general.open_config_on_startup:
652
+ root.after(50, settings_window.show)
653
+ settings_window.add_save_hook(update_icon)
654
+ settings_window.on_exit = exit_program
655
+ root.mainloop()
656
+ except KeyboardInterrupt:
657
+ cleanup()
658
+
659
+ try:
660
+ observer.stop()
661
+ observer.join()
662
+ except Exception as e:
663
+ logger.error(f"Error stopping observer: {e}")
627
664
  except Exception as e:
628
- logger.error(f"Error stopping observer: {e}")
665
+ logger.error(f"An error occurred during initialization: {e}", exc_info=True)
666
+ notification.send_error_notification(
667
+ "An error occurred during initialization. Check the log for details.")
668
+ asyncio.sleep(5)
669
+ raise e
670
+
629
671
 
630
672
  def main():
631
- asyncio.run(async_main())
673
+ """Main function to run the Game Sentence Miner."""
674
+ logger.info("Starting GSM")
675
+ try:
676
+ asyncio.run(async_main())
677
+ except Exception as e:
678
+ logger.exception(e, exc_info=True)
679
+ logger.info(
680
+ "An error occurred during initialization, closing in 5 seconds")
681
+ time.sleep(5)
632
682
 
633
683
 
634
684
  if __name__ == "__main__":
@@ -636,4 +686,7 @@ if __name__ == "__main__":
636
686
  try:
637
687
  asyncio.run(async_main())
638
688
  except Exception as e:
639
- logger.exception(e)
689
+ logger.exception(e, exc_info=True)
690
+ logger.info(
691
+ "An error occurred during initialization, closing in 5 seconds")
692
+ time.sleep(5)
@@ -305,6 +305,7 @@ def text_callback(text, orig_text, time, img=None, came_from_ss=False, filtering
305
305
 
306
306
  line_start_time = time if time else datetime.now()
307
307
 
308
+
308
309
  if manual or not get_ocr_two_pass_ocr():
309
310
  if compare_ocr_results(last_sent_result, text, 80):
310
311
  if text:
@@ -320,8 +321,6 @@ def text_callback(text, orig_text, time, img=None, came_from_ss=False, filtering
320
321
  last_oneocr_time = None
321
322
  return
322
323
  if not text or force_stable:
323
- # or FUTURE ATTEMPT, I THINK THIS IS CLOSE?
324
- # (orig_text and previous_text and len(orig_text) == len(previous_text_list) and len(orig_text[0] < len(previous_text_list)))):
325
324
  force_stable = False
326
325
  if previous_text and text_stable_start_time:
327
326
  stable_time = text_stable_start_time
@@ -349,7 +348,7 @@ def text_callback(text, orig_text, time, img=None, came_from_ss=False, filtering
349
348
  # Make sure it's an actual new line before starting the timer
350
349
  if text and compare_ocr_results(orig_text_string, previous_orig_text):
351
350
  return
352
-
351
+
353
352
  if not text_stable_start_time:
354
353
  text_stable_start_time = line_start_time
355
354
  previous_text = text
@@ -1478,6 +1478,7 @@ def run(read_from=None,
1478
1478
  filter_img = True
1479
1479
  notify = False
1480
1480
  last_screenshot_time = time.time()
1481
+ ocr_start_time = datetime.now()
1481
1482
 
1482
1483
  if img == 0:
1483
1484
  on_window_closed(False)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GameSentenceMiner
3
- Version: 2.12.9
3
+ Version: 2.12.11
4
4
  Summary: A tool for mining sentences from games. Update: Overlay?
5
5
  Author-email: Beangate <bpwhelan95@gmail.com>
6
6
  License: MIT License
@@ -2,7 +2,7 @@ GameSentenceMiner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
2
2
  GameSentenceMiner/anki.py,sha256=FUwcWO0-arzfQjejQmDKP7pNNakhboo8InQ4s_jv6AY,19099
3
3
  GameSentenceMiner/config_gui.py,sha256=UCipZVAVupJeA8Kaa1tqTBsZpErNIIePJabqKh4SI7s,105693
4
4
  GameSentenceMiner/gametext.py,sha256=TYlkgM5-J2o8-WCKypSUitmKq_UcjOGpsZBINiR-mWk,10875
5
- GameSentenceMiner/gsm.py,sha256=XfoxdN31rNUF5xPdCSamBlqIX3MPdOyoYWTPKNhWttE,25343
5
+ GameSentenceMiner/gsm.py,sha256=bNZmHcZt_sLt-WDnYtRZsv5NYRbw_59V79eOggg_Ym0,26662
6
6
  GameSentenceMiner/obs.py,sha256=bMVWAPQ6QLf4celLiOsL9BUO8pTdMn9lpT9fQCNfm7Q,18718
7
7
  GameSentenceMiner/vad.py,sha256=-Q1KtDJnT8zRFeEc4LLyAECf07YOUM15UDRrnWkuDgo,18817
8
8
  GameSentenceMiner/ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -19,14 +19,14 @@ GameSentenceMiner/ocr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
19
19
  GameSentenceMiner/ocr/gsm_ocr_config.py,sha256=Ezj-0k6Wo-una91FvYhMp6KGkRhWYihXzLAoh_Wu2xY,5329
20
20
  GameSentenceMiner/ocr/ocrconfig.py,sha256=_tY8mjnzHMJrLS8E5pHqYXZjMuLoGKYgJwdhYgN-ny4,6466
21
21
  GameSentenceMiner/ocr/owocr_area_selector.py,sha256=seTO8kUCTW445qAUo4c7mvLtiv1SWeElpSUpP9DPDOA,26331
22
- GameSentenceMiner/ocr/owocr_helper.py,sha256=To_tIGPgj68QkEGasQuh5vK6Zg-BLqJmkVHusp-q4Bs,25427
22
+ GameSentenceMiner/ocr/owocr_helper.py,sha256=nyNCt6TtOFvcXddwaNXpkuYbCsfBG5Nvp6b8mU-6jlg,25236
23
23
  GameSentenceMiner/ocr/ss_picker.py,sha256=0IhxUdaKruFpZyBL-8SpxWg7bPrlGpy3lhTcMMZ5rwo,5224
24
24
  GameSentenceMiner/owocr/owocr/__init__.py,sha256=87hfN5u_PbL_onLfMACbc0F5j4KyIK9lKnRCj6oZgR0,49
25
25
  GameSentenceMiner/owocr/owocr/__main__.py,sha256=XQaqZY99EKoCpU-gWQjNbTs7Kg17HvBVE7JY8LqIE0o,157
26
26
  GameSentenceMiner/owocr/owocr/config.py,sha256=qM7kISHdUhuygGXOxmgU6Ef2nwBShrZtdqu4InDCViE,8103
27
27
  GameSentenceMiner/owocr/owocr/lens_betterproto.py,sha256=oNoISsPilVVRBBPVDtb4-roJtAhp8ZAuFTci3TGXtMc,39141
28
28
  GameSentenceMiner/owocr/owocr/ocr.py,sha256=jjm7TGIOaR-7JfoP_4B24uW7tLsxJL36s2kFndJy_SA,63025
29
- GameSentenceMiner/owocr/owocr/run.py,sha256=BvUmJAb1YboDn3FNS6jP92i3gmYjTE_uGJi-_qG_LdY,65962
29
+ GameSentenceMiner/owocr/owocr/run.py,sha256=Qm4srtzqj6tZhgicMME4SyjP6NP_2IQRN-AOzVzE828,66011
30
30
  GameSentenceMiner/owocr/owocr/screen_coordinate_picker.py,sha256=Na6XStbQBtpQUSdbN3QhEswtKuU1JjReFk_K8t5ezQE,3395
31
31
  GameSentenceMiner/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
32
  GameSentenceMiner/util/audio_offset_selector.py,sha256=8Stk3BP-XVIuzRv9nl9Eqd2D-1yD3JrgU-CamBywJmY,8542
@@ -64,9 +64,9 @@ GameSentenceMiner/web/templates/index.html,sha256=Gv3CJvNnhAzIVV_QxhNq4OD-pXDt1v
64
64
  GameSentenceMiner/web/templates/text_replacements.html,sha256=tV5c8mCaWSt_vKuUpbdbLAzXZ3ATZeDvQ9PnnAfqY0M,8598
65
65
  GameSentenceMiner/web/templates/utility.html,sha256=3flZinKNqUJ7pvrZk6xu__v67z44rXnaK7UTZ303R-8,16946
66
66
  GameSentenceMiner/wip/get_overlay_coords.py,sha256=_re9zfyuFryZAUKbMQ1LAfQBDIRUmq_1kniisN7J7xE,19793
67
- gamesentenceminer-2.12.9.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
68
- gamesentenceminer-2.12.9.dist-info/METADATA,sha256=hxe3hqm5pm3PUW6BKpAynDpz6lMOSIBMR3E0ndiIkng,7068
69
- gamesentenceminer-2.12.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
70
- gamesentenceminer-2.12.9.dist-info/entry_points.txt,sha256=2APEP25DbfjSxGeHtwBstMH8mulVhLkqF_b9bqzU6vQ,65
71
- gamesentenceminer-2.12.9.dist-info/top_level.txt,sha256=V1hUY6xVSyUEohb0uDoN4UIE6rUZ_JYx8yMyPGX4PgQ,18
72
- gamesentenceminer-2.12.9.dist-info/RECORD,,
67
+ gamesentenceminer-2.12.11.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
68
+ gamesentenceminer-2.12.11.dist-info/METADATA,sha256=nGANkSYsrLfHVpnRMqewYouhR7UzFJMfuB5xGOy2v3E,7069
69
+ gamesentenceminer-2.12.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
70
+ gamesentenceminer-2.12.11.dist-info/entry_points.txt,sha256=2APEP25DbfjSxGeHtwBstMH8mulVhLkqF_b9bqzU6vQ,65
71
+ gamesentenceminer-2.12.11.dist-info/top_level.txt,sha256=V1hUY6xVSyUEohb0uDoN4UIE6rUZ_JYx8yMyPGX4PgQ,18
72
+ gamesentenceminer-2.12.11.dist-info/RECORD,,