GameSentenceMiner 2.12.3__tar.gz → 2.12.4__tar.gz

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.
Files changed (78) hide show
  1. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/obs.py +40 -19
  2. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/owocr/owocr/ocr.py +28 -31
  3. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/owocr/owocr/run.py +25 -64
  4. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/util/downloader/oneocr_dl.py +9 -8
  5. gamesentenceminer-2.12.4/GameSentenceMiner/wip/get_overlay_coords.py +519 -0
  6. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner.egg-info/PKG-INFO +3 -1
  7. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/PKG-INFO +3 -1
  8. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/README.md +2 -0
  9. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/pyproject.toml +1 -1
  10. gamesentenceminer-2.12.3/GameSentenceMiner/wip/get_overlay_coords.py +0 -257
  11. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/__init__.py +0 -0
  12. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/ai/__init__.py +0 -0
  13. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/ai/ai_prompting.py +0 -0
  14. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/anki.py +0 -0
  15. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/assets/__init__.py +0 -0
  16. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/assets/icon.png +0 -0
  17. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/assets/icon128.png +0 -0
  18. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/assets/icon256.png +0 -0
  19. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/assets/icon32.png +0 -0
  20. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/assets/icon512.png +0 -0
  21. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/assets/icon64.png +0 -0
  22. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/assets/pickaxe.png +0 -0
  23. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/config_gui.py +0 -0
  24. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/gametext.py +0 -0
  25. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/gsm.py +0 -0
  26. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/ocr/__init__.py +0 -0
  27. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/ocr/gsm_ocr_config.py +0 -0
  28. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/ocr/ocrconfig.py +0 -0
  29. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/ocr/owocr_area_selector.py +0 -0
  30. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/ocr/owocr_helper.py +0 -0
  31. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/ocr/ss_picker.py +0 -0
  32. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/owocr/owocr/__init__.py +0 -0
  33. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/owocr/owocr/__main__.py +0 -0
  34. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/owocr/owocr/config.py +0 -0
  35. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/owocr/owocr/lens_betterproto.py +0 -0
  36. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/owocr/owocr/screen_coordinate_picker.py +0 -0
  37. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/util/__init__.py +0 -0
  38. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/util/audio_offset_selector.py +0 -0
  39. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/util/communication/__init__.py +0 -0
  40. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/util/communication/send.py +0 -0
  41. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/util/communication/websocket.py +0 -0
  42. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/util/configuration.py +0 -0
  43. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/util/downloader/Untitled_json.py +0 -0
  44. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/util/downloader/__init__.py +0 -0
  45. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/util/downloader/download_tools.py +0 -0
  46. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/util/electron_config.py +0 -0
  47. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/util/ffmpeg.py +0 -0
  48. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/util/gsm_utils.py +0 -0
  49. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/util/model.py +0 -0
  50. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/util/notification.py +0 -0
  51. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/util/package.py +0 -0
  52. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/util/ss_selector.py +0 -0
  53. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/util/text_log.py +0 -0
  54. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/util/window_transparency.py +0 -0
  55. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/vad.py +0 -0
  56. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/web/__init__.py +0 -0
  57. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/web/service.py +0 -0
  58. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/web/static/__init__.py +0 -0
  59. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/web/static/apple-touch-icon.png +0 -0
  60. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/web/static/favicon-96x96.png +0 -0
  61. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/web/static/favicon.ico +0 -0
  62. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/web/static/favicon.svg +0 -0
  63. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/web/static/site.webmanifest +0 -0
  64. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/web/static/style.css +0 -0
  65. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/web/static/web-app-manifest-192x192.png +0 -0
  66. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/web/static/web-app-manifest-512x512.png +0 -0
  67. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/web/templates/__init__.py +0 -0
  68. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/web/templates/index.html +0 -0
  69. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/web/templates/text_replacements.html +0 -0
  70. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/web/templates/utility.html +0 -0
  71. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner/web/texthooking_page.py +0 -0
  72. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner.egg-info/SOURCES.txt +0 -0
  73. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner.egg-info/dependency_links.txt +0 -0
  74. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner.egg-info/entry_points.txt +0 -0
  75. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner.egg-info/requires.txt +0 -0
  76. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/GameSentenceMiner.egg-info/top_level.txt +0 -0
  77. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/LICENSE +0 -0
  78. {gamesentenceminer-2.12.3 → gamesentenceminer-2.12.4}/setup.cfg +0 -0
@@ -385,12 +385,17 @@ def get_screenshot_base64(compression=75, width=None, height=None):
385
385
  return None
386
386
 
387
387
 
388
- def get_screenshot_PIL(compression=75, img_format='png', width=None, height=None, retry=3):
388
+ def get_screenshot_PIL(source_name=None, compression=75, img_format='png', width=None, height=None, retry=3):
389
389
  import io
390
390
  import base64
391
391
  from PIL import Image
392
+ if not source_name:
393
+ source_name = get_active_source().get('sourceName', None)
394
+ if not source_name:
395
+ logger.error("No active source found in the current scene.")
396
+ return None
392
397
  while True:
393
- response = client.get_source_screenshot(name=get_current_game(), img_format=img_format, quality=compression, width=width, height=height)
398
+ response = client.get_source_screenshot(name=source_name, img_format=img_format, quality=compression, width=width, height=height)
394
399
  try:
395
400
  response.image_data = response.image_data.split(',', 1)[-1] # Remove data:image/png;base64, prefix if present
396
401
  except AttributeError:
@@ -463,26 +468,42 @@ if __name__ == '__main__':
463
468
  logging.basicConfig(level=logging.INFO)
464
469
  # main()
465
470
  connect_to_obs_sync()
466
- i = 100
471
+ # i = 100
472
+ # for i in range(1, 100):
473
+ # print(f"Getting screenshot {i}")
474
+ # start = time.time()
475
+ # # get_screenshot(compression=95)
476
+ # # get_screenshot_base64(compression=95, width=1280, height=720)
477
+
478
+ # img = get_screenshot_PIL(compression=i, img_format='jpg', width=1280, height=720)
479
+ # end = time.time()
480
+ # print(f"Time taken to get screenshot with compression {i}: {end - start} seconds")
481
+
467
482
  # for i in range(1, 100):
468
- print(f"Getting screenshot {i}")
469
- start = time.time()
470
- # get_screenshot(compression=95)
471
- # get_screenshot_base64(compression=95, width=1280, height=720)
472
- img = get_screenshot_PIL(compression=i, img_format='png')
473
- end = time.time()
474
- print(f"Time taken to get screenshot with compression {i}: {end - start} seconds")
475
- img.show()
483
+ # print(f"Getting screenshot {i}")
484
+ # start = time.time()
485
+ # # get_screenshot(compression=95)
486
+ # # get_screenshot_base64(compression=95, width=1280, height=720)
476
487
 
488
+ # img = get_screenshot_PIL(compression=i, img_format='jpg', width=2560, height=1440)
489
+ # end = time.time()
490
+ # print(f"Time taken to get screenshot full sized jpg with compression {i}: {end - start} seconds")
491
+
492
+ # png_img = get_screenshot_PIL(compression=75, img_format='png', width=1280, height=720)
493
+
494
+ # jpg_img = get_screenshot_PIL(compression=100, img_format='jpg', width=2560, height=1440)
495
+
496
+ # png_img.show()
497
+ # jpg_img.show()
477
498
 
478
- start = time.time()
479
- with mss() as sct:
480
- monitor = sct.monitors[1]
481
- sct_img = sct.grab(monitor)
482
- img = Image.frombytes('RGB', sct_img.size, sct_img.bgra, 'raw', 'BGRX')
483
- img.show()
484
- end = time.time()
485
- print(f"Time taken to get screenshot with mss: {end - start} seconds")
499
+ # start = time.time()
500
+ # with mss() as sct:
501
+ # monitor = sct.monitors[1]
502
+ # sct_img = sct.grab(monitor)
503
+ # img = Image.frombytes('RGB', sct_img.size, sct_img.bgra, 'raw', 'BGRX')
504
+ # img.show()
505
+ # end = time.time()
506
+ # print(f"Time taken to get screenshot with mss: {end - start} seconds")
486
507
 
487
508
 
488
509
  # print(get_screenshot_base64(compression=75, width=1280, height=720))
@@ -436,7 +436,7 @@ class GoogleLens:
436
436
  # res += '\n'
437
437
 
438
438
  if return_coords:
439
- x = (True, res, lines)
439
+ x = (True, res, response_dict)
440
440
  else:
441
441
  x = (True, res)
442
442
 
@@ -887,7 +887,28 @@ class OneOCR:
887
887
  except:
888
888
  logger.warning('Error reading URL from config, OneOCR will not work!')
889
889
 
890
- def __call__(self, img, furigana_filter_sensitivity=0, sentence_to_check=None, return_coords=False):
890
+ def get_regex(self, lang):
891
+ if lang == "ja":
892
+ self.regex = re.compile(r'[\u3041-\u3096\u30A1-\u30FA\u4E00-\u9FFF]')
893
+ elif lang == "zh":
894
+ self.regex = re.compile(r'[\u4E00-\u9FFF]')
895
+ elif lang == "ko":
896
+ self.regex = re.compile(r'[\uAC00-\uD7AF]')
897
+ elif lang == "ar":
898
+ self.regex = re.compile(r'[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]')
899
+ elif lang == "ru":
900
+ self.regex = re.compile(r'[\u0400-\u04FF\u0500-\u052F\u2DE0-\u2DFF\uA640-\uA69F\u1C80-\u1C8F]')
901
+ elif lang == "el":
902
+ self.regex = re.compile(r'[\u0370-\u03FF\u1F00-\u1FFF]')
903
+ elif lang == "he":
904
+ self.regex = re.compile(r'[\u0590-\u05FF\uFB1D-\uFB4F]')
905
+ elif lang == "th":
906
+ self.regex = re.compile(r'[\u0E00-\u0E7F]')
907
+ else:
908
+ self.regex = re.compile(
909
+ r'[a-zA-Z\u00C0-\u00FF\u0100-\u017F\u0180-\u024F\u0250-\u02AF\u1D00-\u1D7F\u1D80-\u1DBF\u1E00-\u1EFF\u2C60-\u2C7F\uA720-\uA7FF\uAB30-\uAB6F]')
910
+
911
+ def __call__(self, img, furigana_filter_sensitivity=0, return_coords=False):
891
912
  lang = get_ocr_language()
892
913
  if lang != self.initial_lang:
893
914
  self.initial_lang = lang
@@ -911,6 +932,10 @@ class OneOCR:
911
932
  json.dump(ocr_resp, f, indent=4, ensure_ascii=False)
912
933
  # print(json.dumps(ocr_resp))
913
934
  filtered_lines = [line for line in ocr_resp['lines'] if self.regex.search(line['text'])]
935
+ x_coords = [line['bounding_rect'][f'x{i}'] for line in filtered_lines for i in range(1, 5)]
936
+ y_coords = [line['bounding_rect'][f'y{i}'] for line in filtered_lines for i in range(1, 5)]
937
+ if x_coords and y_coords:
938
+ crop_coords = (min(x_coords) - 5, min(y_coords) - 5, max(x_coords) + 5, max(y_coords) + 5)
914
939
  # logger.info(filtered_lines)
915
940
  res = ''
916
941
  skipped = []
@@ -964,30 +989,6 @@ class OneOCR:
964
989
  # else:
965
990
  # continue
966
991
  # res += '\n'
967
- elif sentence_to_check:
968
- lines_to_build_area = []
969
- widths = []
970
- heights = []
971
- for line in ocr_resp['lines']:
972
- print(line['text'])
973
- if sentence_to_check in line['text'] or line['text'] in sentence_to_check or rapidfuzz.fuzz.partial_ratio(sentence_to_check, line['text']) > 50:
974
- lines_to_build_area.append(line)
975
- res += line['text']
976
- for word in line['words']:
977
- widths.append(word['bounding_rect']['x2'] - word['bounding_rect']['x1'])
978
- heights.append(word['bounding_rect']['y3'] - word['bounding_rect']['y1'])
979
-
980
- x_coords = [line['bounding_rect'][f'x{i}'] for line in lines_to_build_area for i in
981
- range(1, 5)]
982
- y_coords = [line['bounding_rect'][f'y{i}'] for line in lines_to_build_area for i in
983
- range(1, 5)]
984
- if widths:
985
- avg_width = sum(widths) / len(widths)
986
- if heights:
987
- avg_height = sum(heights) / len(heights)
988
- if x_coords and y_coords:
989
- crop_coords = (
990
- min(x_coords) - 5, min(y_coords) - 5, max(x_coords) + 5, max(y_coords) + 5)
991
992
  elif return_coords:
992
993
  for line in filtered_lines:
993
994
  for word in line['words']:
@@ -998,10 +999,6 @@ class OneOCR:
998
999
  boxes.append(box)
999
1000
  res = ocr_resp['text']
1000
1001
  else:
1001
- x_coords = [line['bounding_rect'][f'x{i}'] for line in filtered_lines for i in range(1, 5)]
1002
- y_coords = [line['bounding_rect'][f'y{i}'] for line in filtered_lines for i in range(1, 5)]
1003
- if x_coords and y_coords:
1004
- crop_coords = (min(x_coords) - 5, min(y_coords) - 5, max(x_coords) + 5, max(y_coords) + 5)
1005
1002
  res = ocr_resp['text']
1006
1003
 
1007
1004
  except RuntimeError as e:
@@ -1019,7 +1016,7 @@ class OneOCR:
1019
1016
 
1020
1017
  res = res.json()['text']
1021
1018
  if return_coords:
1022
- x = (True, res, boxes)
1019
+ x = (True, res, filtered_lines)
1023
1020
  else:
1024
1021
  x = (True, res, crop_coords)
1025
1022
  if is_path:
@@ -44,7 +44,6 @@ import queue
44
44
  from datetime import datetime
45
45
  from PIL import Image, ImageDraw, UnidentifiedImageError
46
46
  from loguru import logger
47
- from pynput import keyboard
48
47
  from desktop_notifier import DesktopNotifierSync
49
48
  import psutil
50
49
 
@@ -384,6 +383,7 @@ class TextFiltering:
384
383
  block_filtered = self.latin_extended_regex.findall(block)
385
384
  else:
386
385
  block_filtered = self.latin_extended_regex.findall(block)
386
+
387
387
  if block_filtered:
388
388
  orig_text_filtered.append(''.join(block_filtered))
389
389
  else:
@@ -547,39 +547,6 @@ class ScreenshotThread(threading.Thread):
547
547
  else:
548
548
  raise ValueError('Window capture is only currently supported on Windows and macOS')
549
549
 
550
- def __del__(self):
551
- if self.macos_window_tracker_instance:
552
- self.macos_window_tracker_instance.join()
553
- elif self.windows_window_tracker_instance:
554
- self.windows_window_tracker_instance.join()
555
-
556
- def setup_persistent_windows_window_tracker(self):
557
- global window_open
558
- window_open = False
559
- def setup_tracker():
560
- global window_open
561
- self.window_handle, window_title = self.get_windows_window_handle(self.screen_capture_window)
562
-
563
- if not self.window_handle:
564
- # print(f"Window '{screen_capture_window}' not found.")
565
- return
566
-
567
- set_dpi_awareness()
568
- window_open = True
569
- self.windows_window_tracker_instance = threading.Thread(target=self.windows_window_tracker)
570
- self.windows_window_tracker_instance.start()
571
- logger.opt(ansi=True).info(f'Selected window: {window_title}')
572
-
573
- while not terminated:
574
- if not window_open:
575
- try:
576
- setup_tracker()
577
- except ValueError as e:
578
- logger.error(f"Error setting up persistent windows window tracker: {e}")
579
- break
580
- time.sleep(5)
581
-
582
-
583
550
  def get_windows_window_handle(self, window_title):
584
551
  def callback(hwnd, window_title_part):
585
552
  window_title = win32gui.GetWindowText(hwnd)
@@ -602,7 +569,7 @@ class ScreenshotThread(threading.Thread):
602
569
 
603
570
  def windows_window_tracker(self):
604
571
  found = True
605
- while not terminated or window_open:
572
+ while not terminated:
606
573
  found = win32gui.IsWindow(self.window_handle)
607
574
  if not found:
608
575
  break
@@ -872,18 +839,9 @@ class OBSScreenshotThread(threading.Thread):
872
839
  image_queue.put((result, True))
873
840
 
874
841
  def connect_obs(self):
875
- try:
876
- import obsws_python as obs
877
- self.obs_client = obs.ReqClient(
878
- host=get_config().obs.host,
879
- port=get_config().obs.port,
880
- password=get_config().obs.password,
881
- timeout=10
882
- )
883
- logger.info("Connected to OBS WebSocket.")
884
- except Exception as e:
885
- logger.error(f"Failed to connect to OBS: {e}")
886
- self.obs_client = None
842
+ import GameSentenceMiner.obs as obs
843
+ obs.connect_to_obs_sync()
844
+
887
845
 
888
846
  def run(self):
889
847
  global last_image
@@ -895,7 +853,7 @@ class OBSScreenshotThread(threading.Thread):
895
853
  def init_config(source=None, scene=None):
896
854
  obs.update_current_game()
897
855
  self.current_source = source if source else obs.get_active_source()
898
- self.current_source_name = self.current_source.get('sourceName') if isinstance(self.current_source, dict) else None
856
+ self.current_source_name = self.current_source.get("sourceName") or None
899
857
  self.current_scene = scene if scene else obs.get_current_game()
900
858
  self.ocr_config = get_scene_ocr_config()
901
859
  self.ocr_config.scale_to_custom_size(self.width, self.height)
@@ -927,20 +885,20 @@ class OBSScreenshotThread(threading.Thread):
927
885
  if not self.ocr_config:
928
886
  time.sleep(1)
929
887
  continue
888
+
889
+ if not self.current_source_name:
890
+ obs.update_current_game()
891
+ self.current_source = obs.get_active_source()
892
+ self.current_source_name = self.current_source.get("sourceName") or None
930
893
 
931
894
  try:
932
- response = self.obs_client.get_source_screenshot(
933
- name=self.current_source_name,
934
- img_format='png',
935
- quality=75,
936
- width=self.width,
937
- height=self.height,
938
- )
895
+ if not self.current_source_name:
896
+ logger.error("No active source found in the current scene.")
897
+ time.sleep(1)
898
+ continue
899
+ img = obs.get_screenshot_PIL(source_name=self.current_source_name, width=self.width, height=self.height, img_format='jpg', compression=90)
939
900
 
940
- if response.image_data:
941
- image_data = base64.b64decode(response.image_data.split(",")[1])
942
- img = Image.open(io.BytesIO(image_data)).convert("RGBA")
943
-
901
+ if img is not None:
944
902
  if not img.getbbox():
945
903
  logger.info("OBS Not Capturing anything, sleeping.")
946
904
  time.sleep(1)
@@ -1118,11 +1076,10 @@ def signal_handler(sig, frame):
1118
1076
 
1119
1077
 
1120
1078
  def on_window_closed(alive):
1121
- global terminated, window_open
1079
+ global terminated
1122
1080
  if not (alive or terminated):
1123
1081
  logger.info('Window closed or error occurred, terminated!')
1124
- window_open = False
1125
- # terminated = True
1082
+ terminated = True
1126
1083
 
1127
1084
 
1128
1085
  def on_screenshot_combo():
@@ -1464,8 +1421,12 @@ def run(read_from=None,
1464
1421
  read_from_readable.append(f'directory {read_from_path}')
1465
1422
 
1466
1423
  if len(key_combos) > 0:
1467
- key_combo_listener = keyboard.GlobalHotKeys(key_combos)
1468
- key_combo_listener.start()
1424
+ try:
1425
+ from pynput import keyboard
1426
+ key_combo_listener = keyboard.GlobalHotKeys(key_combos)
1427
+ key_combo_listener.start()
1428
+ except ImportError:
1429
+ pass
1469
1430
 
1470
1431
  if write_to in ('clipboard', 'websocket', 'callback'):
1471
1432
  write_to_readable = write_to
@@ -239,11 +239,12 @@ class Downloader:
239
239
  # Example usage:
240
240
  if __name__ == "__main__":
241
241
  downloader = Downloader()
242
- if downloader.download_and_extract():
243
- print("SnippingTool files are ready.")
244
- print("Press Ctrl+C or X on window to exit.")
245
- input()
246
- else:
247
- print("Failed to download and extract SnippingTool files. You may need to follow instructions at https://github.com/AuroraWright/oneocr")
248
- print("Press Ctrl+C or X on window to exit.")
249
- input()
242
+ downloader.download_and_extract()
243
+ # if downloader.download_and_extract():
244
+ # print("SnippingTool files are ready.")
245
+ # print("Press Ctrl+C or X on window to exit.")
246
+ # # input()
247
+ # else:
248
+ # # print("Failed to download and extract SnippingTool files. You may need to follow instructions at https://github.com/AuroraWright/oneocr")
249
+ # print("Press Ctrl+C or X on window to exit.")
250
+ # input()