GameSentenceMiner 2.8.16__tar.gz → 2.8.18__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 (64) hide show
  1. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/ocr/owocr_area_selector.py +4 -0
  2. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/ocr/owocr_helper.py +1 -1
  3. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/owocr/owocr/__main__.py +1 -1
  4. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/owocr/owocr/ocr.py +76 -0
  5. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/owocr/owocr/run.py +2 -1
  6. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner.egg-info/PKG-INFO +1 -1
  7. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/PKG-INFO +1 -1
  8. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/pyproject.toml +1 -1
  9. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/__init__.py +0 -0
  10. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/ai/__init__.py +0 -0
  11. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/ai/ai_prompting.py +0 -0
  12. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/anki.py +0 -0
  13. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/communication/__init__.py +0 -0
  14. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/communication/send.py +0 -0
  15. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/communication/websocket.py +0 -0
  16. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/config_gui.py +0 -0
  17. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/configuration.py +0 -0
  18. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/downloader/Untitled_json.py +0 -0
  19. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/downloader/__init__.py +0 -0
  20. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/downloader/download_tools.py +0 -0
  21. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/downloader/oneocr_dl.py +0 -0
  22. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/electron_config.py +0 -0
  23. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/ffmpeg.py +0 -0
  24. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/gametext.py +0 -0
  25. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/gsm.py +0 -0
  26. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/model.py +0 -0
  27. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/notification.py +0 -0
  28. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/obs.py +0 -0
  29. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/ocr/__init__.py +0 -0
  30. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/ocr/gsm_ocr_config.py +0 -0
  31. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/ocr/ocrconfig.py +0 -0
  32. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/owocr/owocr/__init__.py +0 -0
  33. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/owocr/owocr/config.py +0 -0
  34. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/owocr/owocr/lens_betterproto.py +0 -0
  35. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/owocr/owocr/screen_coordinate_picker.py +0 -0
  36. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/package.py +0 -0
  37. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/text_log.py +0 -0
  38. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/util.py +0 -0
  39. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/vad/__init__.py +0 -0
  40. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/vad/silero_trim.py +0 -0
  41. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/vad/vosk_helper.py +0 -0
  42. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/vad/whisper_helper.py +0 -0
  43. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/web/__init__.py +0 -0
  44. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/web/static/__init__.py +0 -0
  45. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/web/static/apple-touch-icon.png +0 -0
  46. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/web/static/favicon-96x96.png +0 -0
  47. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/web/static/favicon.ico +0 -0
  48. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/web/static/favicon.svg +0 -0
  49. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/web/static/site.webmanifest +0 -0
  50. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/web/static/style.css +0 -0
  51. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/web/static/web-app-manifest-192x192.png +0 -0
  52. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/web/static/web-app-manifest-512x512.png +0 -0
  53. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/web/templates/__init__.py +0 -0
  54. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/web/templates/text_replacements.html +0 -0
  55. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/web/templates/utility.html +0 -0
  56. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner/web/texthooking_page.py +0 -0
  57. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner.egg-info/SOURCES.txt +0 -0
  58. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner.egg-info/dependency_links.txt +0 -0
  59. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner.egg-info/entry_points.txt +0 -0
  60. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner.egg-info/requires.txt +0 -0
  61. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/GameSentenceMiner.egg-info/top_level.txt +0 -0
  62. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/LICENSE +0 -0
  63. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/README.md +0 -0
  64. {gamesentenceminer-2.8.16 → gamesentenceminer-2.8.18}/setup.cfg +0 -0
@@ -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
@@ -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
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
7
7
 
8
8
  [project]
9
9
  name = "GameSentenceMiner"
10
- version = "2.8.16"
10
+ version = "2.8.18"
11
11
  description = "A tool for mining sentences from games. Update: Multi-Line Mining! Fixed!"
12
12
  readme = "README.md"
13
13
  requires-python = ">=3.10"