GameSentenceMiner 2.8.16__py3-none-any.whl → 2.8.18__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.
@@ -713,6 +713,10 @@ class ScreenSelector:
713
713
  canvas.bind('<B1-Motion>', on_drag) # Left drag
714
714
  canvas.bind('<ButtonRelease-1>', on_release) # Left click release
715
715
  canvas.bind('<Button-3>', on_right_click) # Right click delete
716
+ canvas.bind('<Control-s>', self.save_rects) # Save
717
+ canvas.bind('<Control-z>', self.undo_last_rect) # Undo
718
+ canvas.bind('<Control-y>', self.redo_last_rect) # Redo
719
+
716
720
 
717
721
  # --- Bind Global Actions to the window (apply to all windows) ---
718
722
  # Use lambdas to ensure the correct toggle function is called if needed,
@@ -209,7 +209,7 @@ def do_second_ocr(ocr1_text, rectangle_index, time, img):
209
209
  global twopassocr, ocr2, last_ocr1_results, last_ocr2_results
210
210
  last_result = ([], -1)
211
211
  try:
212
- orig_text, text = run.process_and_write_results(img, None, None, last_result, TextFiltering(),
212
+ orig_text, text = run.process_and_write_results(img, None, None, None, None,
213
213
  engine=ocr2)
214
214
  previous_ocr2_text = last_ocr2_results[rectangle_index]
215
215
  if fuzz.ratio(previous_ocr2_text, text) >= 80:
@@ -1,4 +1,4 @@
1
- from .run import run, init_config
1
+ from GameSentenceMiner.owocr.owocr.run import run, init_config
2
2
 
3
3
 
4
4
  def main():
@@ -1048,3 +1048,79 @@ class GeminiOCR:
1048
1048
 
1049
1049
  def _preprocess(self, img):
1050
1050
  return pil_image_to_bytes(img, png_compression=1)
1051
+
1052
+
1053
+ class GroqOCR:
1054
+ name = 'groq'
1055
+ readable_name = 'Groq OCR'
1056
+ key = 'j'
1057
+ available = False
1058
+
1059
+ def __init__(self, config={'api_key': None}):
1060
+ try:
1061
+ import groq
1062
+ self.api_key = config['api_key']
1063
+ if not self.api_key:
1064
+ logger.warning('Groq API key not provided, GroqOCR will not work!')
1065
+ else:
1066
+ self.client = groq.Groq(api_key=self.api_key)
1067
+ self.available = True
1068
+ logger.info('Groq OCR ready')
1069
+ except ImportError:
1070
+ logger.warning('groq module not available, GroqOCR will not work!')
1071
+ except Exception as e:
1072
+ logger.error(f'Error initializing Groq client: {e}')
1073
+
1074
+ def __call__(self, img_or_path):
1075
+ if not self.available:
1076
+ return (False, 'GroqOCR is not available due to missing API key or configuration error.')
1077
+
1078
+ try:
1079
+ if isinstance(img_or_path, str) or isinstance(img_or_path, Path):
1080
+ img = Image.open(img_or_path).convert("RGB")
1081
+ elif isinstance(img_or_path, Image.Image):
1082
+ img = img_or_path.convert("RGB")
1083
+ else:
1084
+ raise ValueError(f'img_or_path must be a path or PIL.Image, instead got: {img_or_path}')
1085
+
1086
+ img_base64 = self._preprocess(img)
1087
+ if not img_base64:
1088
+ return (False, 'Error processing image for Groq.')
1089
+
1090
+ prompt = (
1091
+ "Analyze this image and extract text from it"
1092
+ # "(speech bubbles or panels containing character dialogue). From the extracted dialogue text, "
1093
+ # "filter out any furigana. Ignore and do not include any text found outside of dialogue boxes, "
1094
+ # "including character names, speaker labels, or sound effects. Return *only* the filtered dialogue text. "
1095
+ # "If no text is found within dialogue boxes after applying filters, return an empty string. "
1096
+ # "OR, if there are no text bubbles or dialogue boxes found, return everything."
1097
+ "Do not include any other output, formatting markers, or commentary, only the text from the image."
1098
+ )
1099
+
1100
+ response = self.client.chat.completions.create(
1101
+ model="meta-llama/llama-4-scout-17b-16e-instruct",
1102
+ messages=[
1103
+ {
1104
+ "role": "user",
1105
+ "content": [
1106
+ {"type": "text", "text": prompt},
1107
+ {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{img_base64}"}},
1108
+ ],
1109
+ }
1110
+ ],
1111
+ max_tokens=300
1112
+ )
1113
+
1114
+ if response.choices and response.choices[0].message.content:
1115
+ text_output = response.choices[0].message.content.strip()
1116
+ return (True, text_output)
1117
+ else:
1118
+ return (True, "")
1119
+
1120
+ except FileNotFoundError:
1121
+ return (False, f'File not found: {img_or_path}')
1122
+ except Exception as e:
1123
+ return (False, f'Groq API request failed: {e}')
1124
+
1125
+ def _preprocess(self, img):
1126
+ return base64.b64encode(pil_image_to_bytes(img, png_compression=1)).decode('utf-8')
@@ -585,7 +585,8 @@ def process_and_write_results(img_or_path, write_to, notifications, last_result,
585
585
  for i, instance in enumerate(engine_instances):
586
586
  if instance.name.lower() in engine.lower():
587
587
  engine_instance = instance
588
- last_result = (last_result[0], i)
588
+ if last_result:
589
+ last_result = (last_result[0], i)
589
590
  break
590
591
  else:
591
592
  engine_instance = engine_instances[engine_index]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GameSentenceMiner
3
- Version: 2.8.16
3
+ Version: 2.8.18
4
4
  Summary: A tool for mining sentences from games. Update: Multi-Line Mining! Fixed!
5
5
  Author-email: Beangate <bpwhelan95@gmail.com>
6
6
  License: MIT License
@@ -24,14 +24,14 @@ GameSentenceMiner/downloader/oneocr_dl.py,sha256=o3ANp5IodEQoQ8GPcJdg9Y8JzA_lict
24
24
  GameSentenceMiner/ocr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  GameSentenceMiner/ocr/gsm_ocr_config.py,sha256=rQC6C8PKJXWoAvwCOYa363kodQQBwl1YNeYsD0bBbx4,1957
26
26
  GameSentenceMiner/ocr/ocrconfig.py,sha256=_tY8mjnzHMJrLS8E5pHqYXZjMuLoGKYgJwdhYgN-ny4,6466
27
- GameSentenceMiner/ocr/owocr_area_selector.py,sha256=gwYOz-fA5qoL63wh77eyGJtBtO7YVvWyO5cHb3D0Oz4,46738
28
- GameSentenceMiner/ocr/owocr_helper.py,sha256=-ezF6AO7ayZBs2vMt0Zj7D-gc8YbrgO69mFsJD7VmRs,17383
27
+ GameSentenceMiner/ocr/owocr_area_selector.py,sha256=QF45kfvG46RbVW6LbheVIw3S3q6LSCSP8nWRH2XRQPo,46927
28
+ GameSentenceMiner/ocr/owocr_helper.py,sha256=ehQvhq_YjyR8PJYMhvz7M_BuwGAAUujfXgEpBNnAopA,17365
29
29
  GameSentenceMiner/owocr/owocr/__init__.py,sha256=opjBOyGGyEqZCE6YdZPnyt7nVfiwyELHsXA0jAsjm14,25
30
- GameSentenceMiner/owocr/owocr/__main__.py,sha256=r8MI6RAmbkTWqOJ59uvXoDS7CSw5jX5war9ULGWELrA,128
30
+ GameSentenceMiner/owocr/owocr/__main__.py,sha256=XQaqZY99EKoCpU-gWQjNbTs7Kg17HvBVE7JY8LqIE0o,157
31
31
  GameSentenceMiner/owocr/owocr/config.py,sha256=n-xtVylb2Q_H84jb1ZsIGxPQjTNnyvnRny1RhtaLJM8,7550
32
32
  GameSentenceMiner/owocr/owocr/lens_betterproto.py,sha256=oNoISsPilVVRBBPVDtb4-roJtAhp8ZAuFTci3TGXtMc,39141
33
- GameSentenceMiner/owocr/owocr/ocr.py,sha256=n24Xg8Z8dbcgLpq1u4d22z3tLV1evmf0dK3-Xocv3vs,39878
34
- GameSentenceMiner/owocr/owocr/run.py,sha256=fzRUo1iYDZffolYHffqCaIYpvBLO2r_FbXgoQ35Eiqk,51151
33
+ GameSentenceMiner/owocr/owocr/ocr.py,sha256=KDW9twGdgqE2UsmefxEvJmQVjCho_ll256LgoCcO_qQ,43242
34
+ GameSentenceMiner/owocr/owocr/run.py,sha256=7Jfqt-MSYUbeEDBOFic6BmleL9leDmBzfW-kJAO5OO8,51188
35
35
  GameSentenceMiner/owocr/owocr/screen_coordinate_picker.py,sha256=fjJ3CSXLti3WboGPpmsa7MWOwIXsfpHC8N4zKahGGY0,3346
36
36
  GameSentenceMiner/vad/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
37
  GameSentenceMiner/vad/silero_trim.py,sha256=ULf3zwS-JMsY82cKF7gZxREHw8L6lgpWF2U1YqgE9Oc,1681
@@ -51,9 +51,9 @@ GameSentenceMiner/web/static/web-app-manifest-512x512.png,sha256=wyqgCWCrLEUxSRX
51
51
  GameSentenceMiner/web/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
52
  GameSentenceMiner/web/templates/text_replacements.html,sha256=tV5c8mCaWSt_vKuUpbdbLAzXZ3ATZeDvQ9PnnAfqY0M,8598
53
53
  GameSentenceMiner/web/templates/utility.html,sha256=NUp4Yjs6_j7YeqsM2rcF0LzwS6nXSBUWJDl-k2E8BbM,16270
54
- gamesentenceminer-2.8.16.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
55
- gamesentenceminer-2.8.16.dist-info/METADATA,sha256=xYCO06sCETSwSn0_s5kHbMu5gGbkXDM6v_cZv_fYKyw,5933
56
- gamesentenceminer-2.8.16.dist-info/WHEEL,sha256=GHB6lJx2juba1wDgXDNlMTyM13ckjBMKf-OnwgKOCtA,91
57
- gamesentenceminer-2.8.16.dist-info/entry_points.txt,sha256=2APEP25DbfjSxGeHtwBstMH8mulVhLkqF_b9bqzU6vQ,65
58
- gamesentenceminer-2.8.16.dist-info/top_level.txt,sha256=V1hUY6xVSyUEohb0uDoN4UIE6rUZ_JYx8yMyPGX4PgQ,18
59
- gamesentenceminer-2.8.16.dist-info/RECORD,,
54
+ gamesentenceminer-2.8.18.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
55
+ gamesentenceminer-2.8.18.dist-info/METADATA,sha256=gighpeXLuYOSZSnKGjFaYv21v3-hsmolCsCXs6oo0YI,5933
56
+ gamesentenceminer-2.8.18.dist-info/WHEEL,sha256=7ciDxtlje1X8OhobNuGgi1t-ACdFSelPnSmDPrtlobY,91
57
+ gamesentenceminer-2.8.18.dist-info/entry_points.txt,sha256=2APEP25DbfjSxGeHtwBstMH8mulVhLkqF_b9bqzU6vQ,65
58
+ gamesentenceminer-2.8.18.dist-info/top_level.txt,sha256=V1hUY6xVSyUEohb0uDoN4UIE6rUZ_JYx8yMyPGX4PgQ,18
59
+ gamesentenceminer-2.8.18.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.3.0)
2
+ Generator: setuptools (80.2.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5