GameSentenceMiner 2.12.7.post1__py3-none-any.whl → 2.12.9__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/config_gui.py +14 -0
- GameSentenceMiner/gametext.py +67 -7
- GameSentenceMiner/gsm.py +1 -1
- GameSentenceMiner/ocr/owocr_area_selector.py +27 -14
- GameSentenceMiner/owocr/owocr/ocr.py +1 -1
- GameSentenceMiner/util/configuration.py +5 -0
- GameSentenceMiner/util/notification.py +16 -12
- GameSentenceMiner/util/text_log.py +3 -1
- GameSentenceMiner/util/window_transparency.py +26 -8
- GameSentenceMiner/vad.py +2 -0
- {gamesentenceminer-2.12.7.post1.dist-info → gamesentenceminer-2.12.9.dist-info}/METADATA +2 -2
- {gamesentenceminer-2.12.7.post1.dist-info → gamesentenceminer-2.12.9.dist-info}/RECORD +16 -16
- {gamesentenceminer-2.12.7.post1.dist-info → gamesentenceminer-2.12.9.dist-info}/WHEEL +0 -0
- {gamesentenceminer-2.12.7.post1.dist-info → gamesentenceminer-2.12.9.dist-info}/entry_points.txt +0 -0
- {gamesentenceminer-2.12.7.post1.dist-info → gamesentenceminer-2.12.9.dist-info}/licenses/LICENSE +0 -0
- {gamesentenceminer-2.12.7.post1.dist-info → gamesentenceminer-2.12.9.dist-info}/top_level.txt +0 -0
GameSentenceMiner/config_gui.py
CHANGED
@@ -265,6 +265,7 @@ class ConfigApp:
|
|
265
265
|
use_websocket=self.websocket_enabled.get(),
|
266
266
|
use_clipboard=self.clipboard_enabled.get(),
|
267
267
|
websocket_uri=self.websocket_uri.get(),
|
268
|
+
merge_matching_sequential_text= self.merge_matching_sequential_text.get(),
|
268
269
|
open_config_on_startup=self.open_config_on_startup.get(),
|
269
270
|
open_multimine_on_startup=self.open_multimine_on_startup.get(),
|
270
271
|
texthook_replacement_regex=self.texthook_replacement_regex.get(),
|
@@ -519,6 +520,19 @@ class ConfigApp:
|
|
519
520
|
row=self.current_row, column=1,
|
520
521
|
sticky='W', pady=2)
|
521
522
|
self.current_row += 1
|
523
|
+
|
524
|
+
HoverInfoLabelWidget(self.general_tab, text="Merge Matching Sequential Text:",
|
525
|
+
foreground="red", font=("Helvetica", 10, "bold"),
|
526
|
+
tooltip="Enable to merge matching sequential text into a single entry. Designed for Luna's Speech Recognition feature. Very niche.",
|
527
|
+
row=self.current_row, column=0)
|
528
|
+
|
529
|
+
self.merge_matching_sequential_text = tk.BooleanVar(
|
530
|
+
value=self.settings.general.merge_matching_sequential_text)
|
531
|
+
ttk.Checkbutton(self.general_tab, variable=self.merge_matching_sequential_text,
|
532
|
+
bootstyle="round-toggle").grid(
|
533
|
+
row=self.current_row, column=1,
|
534
|
+
sticky='W', pady=2)
|
535
|
+
self.current_row += 1
|
522
536
|
|
523
537
|
HoverInfoLabelWidget(self.general_tab, text="Websocket URI(s):",
|
524
538
|
tooltip="WebSocket URI for connecting. Allows Comma Separated Values for Connecting Multiple.",
|
GameSentenceMiner/gametext.py
CHANGED
@@ -5,6 +5,7 @@ import pyperclip
|
|
5
5
|
import requests
|
6
6
|
import websockets
|
7
7
|
from websockets import InvalidStatus
|
8
|
+
from rapidfuzz import fuzz
|
8
9
|
|
9
10
|
from GameSentenceMiner.util.gsm_utils import do_text_replacements, TEXT_REPLACEMENTS_FILE, run_new_thread
|
10
11
|
from GameSentenceMiner.util.configuration import *
|
@@ -14,9 +15,15 @@ from GameSentenceMiner.web.texthooking_page import add_event_to_texthooker, send
|
|
14
15
|
if get_config().wip.overlay_websocket_send:
|
15
16
|
import GameSentenceMiner.wip.get_overlay_coords as get_overlay_coords
|
16
17
|
|
18
|
+
|
17
19
|
current_line = ''
|
18
20
|
current_line_after_regex = ''
|
19
21
|
current_line_time = datetime.now()
|
22
|
+
# Track the start time for the current sequence
|
23
|
+
current_sequence_start_time = None
|
24
|
+
# Track the last raw clipboard text for prefix comparison
|
25
|
+
last_raw_clipboard = ''
|
26
|
+
timer = None
|
20
27
|
|
21
28
|
last_clipboard = ''
|
22
29
|
|
@@ -84,8 +91,12 @@ async def listen_websockets():
|
|
84
91
|
line_time = datetime.fromisoformat(data["time"])
|
85
92
|
except json.JSONDecodeError or TypeError:
|
86
93
|
current_clipboard = message
|
94
|
+
logger.info
|
87
95
|
if current_clipboard != current_line:
|
88
|
-
|
96
|
+
try:
|
97
|
+
await handle_new_text_event(current_clipboard, line_time if line_time else None)
|
98
|
+
except Exception as e:
|
99
|
+
logger.error(f"Error handling new text event: {e}", exc_info=True)
|
89
100
|
except (websockets.ConnectionClosed, ConnectionError, InvalidStatus, ConnectionResetError, Exception) as e:
|
90
101
|
if websocket_url in gsm_status.websockets_connected:
|
91
102
|
gsm_status.websockets_connected.remove(websocket_url)
|
@@ -112,26 +123,75 @@ async def listen_websockets():
|
|
112
123
|
websocket_tasks.append(listen_on_websocket(f"localhost:{get_config().advanced.ocr_websocket_port}"))
|
113
124
|
|
114
125
|
await asyncio.gather(*websocket_tasks)
|
126
|
+
|
127
|
+
|
128
|
+
async def merge_sequential_lines(line, start_time=None):
|
129
|
+
if not get_config().general.merge_matching_sequential_text:
|
130
|
+
return
|
131
|
+
logger.info(f"Merging Sequential Lines: {line}")
|
132
|
+
# Use the sequence start time for the merged line
|
133
|
+
await add_line_to_text_log(line, start_time if start_time else datetime.now())
|
134
|
+
timer = None
|
135
|
+
# Reset sequence tracking
|
136
|
+
current_sequence_start_time = None
|
137
|
+
last_raw_clipboard = ''
|
138
|
+
|
139
|
+
def schedule_merge(wait, coro, args):
|
140
|
+
async def wrapper():
|
141
|
+
await asyncio.sleep(wait)
|
142
|
+
await coro(*args)
|
143
|
+
task = asyncio.create_task(wrapper())
|
144
|
+
return task
|
145
|
+
|
115
146
|
|
116
147
|
async def handle_new_text_event(current_clipboard, line_time=None):
|
117
|
-
global current_line, current_line_time, current_line_after_regex
|
148
|
+
global current_line, current_line_time, current_line_after_regex, timer, current_sequence_start_time, last_raw_clipboard
|
118
149
|
current_line = current_clipboard
|
150
|
+
logger.info(f"Current Line: {current_line} last raw clipboard: {last_raw_clipboard}")
|
151
|
+
# Only apply this logic if merging is enabled
|
152
|
+
if get_config().general.merge_matching_sequential_text:
|
153
|
+
logger.info(f"Handling new text event: {current_line}")
|
154
|
+
# If no timer is active, this is the start of a new sequence
|
155
|
+
if not timer:
|
156
|
+
logger.info("Starting a new sequence of text lines.")
|
157
|
+
current_sequence_start_time = line_time if line_time else datetime.now()
|
158
|
+
last_raw_clipboard = current_line
|
159
|
+
# Start the timer
|
160
|
+
timer = schedule_merge(2, merge_sequential_lines, [current_line[:], current_sequence_start_time])
|
161
|
+
else:
|
162
|
+
# If the new text starts with the previous, reset the timer (do not update start time)
|
163
|
+
if current_line.startswith(last_raw_clipboard) or fuzz.ratio(current_line, last_raw_clipboard) > 50:
|
164
|
+
logger.info(f"Current line starts with last raw clipboard: {current_line} starts with {last_raw_clipboard}")
|
165
|
+
last_raw_clipboard = current_line
|
166
|
+
timer.cancel()
|
167
|
+
timer = schedule_merge(2, merge_sequential_lines, [current_line[:], current_sequence_start_time])
|
168
|
+
else:
|
169
|
+
logger.info(f"Current line does not start with last raw clipboard: {current_line} does not start with {last_raw_clipboard}")
|
170
|
+
# If not a prefix, treat as a new sequence
|
171
|
+
# timer.cancel()
|
172
|
+
current_sequence_start_time = line_time if line_time else datetime.now()
|
173
|
+
last_raw_clipboard = current_line
|
174
|
+
timer = schedule_merge(2, merge_sequential_lines, [current_line[:], current_sequence_start_time])
|
175
|
+
else:
|
176
|
+
await add_line_to_text_log(current_line, line_time)
|
177
|
+
|
178
|
+
|
179
|
+
async def add_line_to_text_log(line, line_time=None):
|
119
180
|
if get_config().general.texthook_replacement_regex:
|
120
|
-
current_line_after_regex = re.sub(get_config().general.texthook_replacement_regex, '',
|
181
|
+
current_line_after_regex = re.sub(get_config().general.texthook_replacement_regex, '', line)
|
121
182
|
else:
|
122
|
-
current_line_after_regex =
|
123
|
-
current_line_after_regex = do_text_replacements(
|
183
|
+
current_line_after_regex = line
|
184
|
+
current_line_after_regex = do_text_replacements(current_line_after_regex, TEXT_REPLACEMENTS_FILE)
|
124
185
|
logger.info(f"Line Received: {current_line_after_regex}")
|
125
186
|
current_line_time = line_time if line_time else datetime.now()
|
126
187
|
gsm_status.last_line_received = current_line_time.strftime("%Y-%m-%d %H:%M:%S")
|
127
|
-
add_line(current_line_after_regex, line_time)
|
188
|
+
add_line(current_line_after_regex, line_time if line_time else datetime.now())
|
128
189
|
if len(get_text_log().values) > 0:
|
129
190
|
await add_event_to_texthooker(get_text_log()[-1])
|
130
191
|
if get_config().wip.overlay_websocket_port and get_config().wip.overlay_websocket_send and overlay_server_thread.has_clients():
|
131
192
|
boxes = await find_box_for_sentence(current_line_after_regex)
|
132
193
|
if boxes:
|
133
194
|
await send_word_coordinates_to_overlay(boxes)
|
134
|
-
|
135
195
|
|
136
196
|
async def find_box_for_sentence(sentence):
|
137
197
|
boxes = []
|
GameSentenceMiner/gsm.py
CHANGED
@@ -597,7 +597,7 @@ async def async_main(reloading=False):
|
|
597
597
|
observer = Observer()
|
598
598
|
observer.schedule(VideoToAudioHandler(), get_config().paths.folder_to_watch, recursive=False)
|
599
599
|
observer.start()
|
600
|
-
if not
|
600
|
+
if not is_windows():
|
601
601
|
register_hotkeys()
|
602
602
|
|
603
603
|
run_new_thread(post_init2)
|
@@ -13,6 +13,7 @@ from PIL import Image, ImageTk
|
|
13
13
|
from GameSentenceMiner import obs
|
14
14
|
from GameSentenceMiner.ocr.gsm_ocr_config import set_dpi_awareness, get_window, get_scene_ocr_config_path
|
15
15
|
from GameSentenceMiner.util.gsm_utils import sanitize_filename
|
16
|
+
from GameSentenceMiner.util.configuration import logger
|
16
17
|
|
17
18
|
try:
|
18
19
|
import tkinter as tk
|
@@ -95,6 +96,7 @@ class ScreenSelector:
|
|
95
96
|
self.image_mode = True
|
96
97
|
self.redo_stack = []
|
97
98
|
self.bounding_box = {} # Geometry of the single large canvas window
|
99
|
+
self.instructions_showing = True
|
98
100
|
|
99
101
|
self.canvas = None
|
100
102
|
self.window = None
|
@@ -282,11 +284,10 @@ class ScreenSelector:
|
|
282
284
|
tk.Button(button_frame, text="Redo (Ctrl+Y)", command=canvas_event_wrapper(self.redo_last_rect)).pack(fill=tk.X, pady=2)
|
283
285
|
tk.Button(button_frame, text="Toggle Background (M)", command=root_event_wrapper(self.toggle_image_mode)).pack(fill=tk.X, pady=2)
|
284
286
|
tk.Button(button_frame, text="Quit without Saving (Esc)", command=root_event_wrapper(self.quit_app)).pack(fill=tk.X, pady=2)
|
287
|
+
tk.Button(button_frame, text="Toggle Instructions (I)", command=canvas_event_wrapper(self.toggle_instructions)).pack(fill=tk.X, pady=2)
|
285
288
|
|
286
|
-
hotkeys_text = "\n• I: Toggle this instruction panel"
|
287
|
-
tk.Label(main_frame, text=hotkeys_text, justify=tk.LEFT, anchor="w").pack(pady=(10, 0), fill=tk.X)
|
288
|
-
|
289
|
-
self.instructions_widget.protocol("WM_DELETE_WINDOW", self.toggle_instructions)
|
289
|
+
# hotkeys_text = "\n• I: Toggle this instruction panel"
|
290
|
+
# tk.Label(main_frame, text=hotkeys_text, justify=tk.LEFT, anchor="w").pack(pady=(10, 0), fill=tk.X)
|
290
291
|
|
291
292
|
|
292
293
|
# --- NEW METHOD TO DISPLAY INSTRUCTIONS ---
|
@@ -310,7 +311,7 @@ class ScreenSelector:
|
|
310
311
|
instruction_font = tkfont.Font(family="Segoe UI", size=10, weight="normal")
|
311
312
|
|
312
313
|
# Create the text item first to get its size
|
313
|
-
|
314
|
+
self.instructions_overlay = canvas.create_text(
|
314
315
|
20, 20, # Position with a small margin
|
315
316
|
text=instructions_text,
|
316
317
|
anchor=tk.NW,
|
@@ -320,10 +321,10 @@ class ScreenSelector:
|
|
320
321
|
)
|
321
322
|
|
322
323
|
# Get the bounding box of the text to draw a background
|
323
|
-
text_bbox = canvas.bbox(
|
324
|
+
text_bbox = canvas.bbox(self.instructions_overlay)
|
324
325
|
|
325
326
|
# Create a background rectangle with padding
|
326
|
-
|
327
|
+
self.instructions_rect = canvas.create_rectangle(
|
327
328
|
text_bbox[0] - 10, # left
|
328
329
|
text_bbox[1] - 10, # top
|
329
330
|
text_bbox[2] + 10, # right
|
@@ -334,15 +335,27 @@ class ScreenSelector:
|
|
334
335
|
)
|
335
336
|
|
336
337
|
# Lower the rectangle so it's behind the text
|
337
|
-
canvas.tag_lower(
|
338
|
+
canvas.tag_lower(self.instructions_rect, self.instructions_overlay)
|
339
|
+
|
338
340
|
|
339
341
|
def toggle_instructions(self, event=None):
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
342
|
+
canvas = event.widget.winfo_toplevel().winfo_children()[0]
|
343
|
+
for element in [self.instructions_overlay, self.instructions_rect]:
|
344
|
+
current_state = canvas.itemcget(element, 'state')
|
345
|
+
new_state = tk.NORMAL if current_state == tk.HIDDEN else tk.HIDDEN
|
346
|
+
canvas.itemconfigure(element, state=new_state)
|
347
|
+
|
348
|
+
# if self.instructions_showing:
|
349
|
+
# self.instructions_widget.withdraw()
|
350
|
+
# logger.info(f"Toggled instructions visibility: OFF")
|
351
|
+
# self.instructions_showing = False
|
352
|
+
# else:
|
353
|
+
# self.instructions_widget.deiconify()
|
354
|
+
# self.instructions_widget.lift()
|
355
|
+
# self.canvas.focus_set()
|
356
|
+
# self.instructions_widget.update_idletasks() # Ensure it is fully rendered
|
357
|
+
# logger.info("Toggled instructions visibility: ON")
|
358
|
+
# self.instructions_showing = True
|
346
359
|
|
347
360
|
def start(self):
|
348
361
|
self.root = tk.Tk()
|
@@ -11,7 +11,6 @@ import json
|
|
11
11
|
import base64
|
12
12
|
from urllib.parse import urlparse, parse_qs
|
13
13
|
|
14
|
-
import jaconv
|
15
14
|
import numpy as np
|
16
15
|
import rapidfuzz.fuzz
|
17
16
|
from PIL import Image
|
@@ -95,6 +94,7 @@ def empty_post_process(text):
|
|
95
94
|
|
96
95
|
|
97
96
|
def post_process(text, keep_blank_lines=False):
|
97
|
+
import jaconv
|
98
98
|
if keep_blank_lines:
|
99
99
|
text = '\n'.join([''.join(i.split()) for i in text.splitlines()])
|
100
100
|
else:
|
@@ -312,6 +312,7 @@ class General:
|
|
312
312
|
use_websocket: bool = True
|
313
313
|
use_clipboard: bool = True
|
314
314
|
use_both_clipboard_and_websocket: bool = False
|
315
|
+
merge_matching_sequential_text: bool = False
|
315
316
|
websocket_uri: str = 'localhost:6677,localhost:9001,localhost:2333'
|
316
317
|
open_config_on_startup: bool = False
|
317
318
|
open_multimine_on_startup: bool = True
|
@@ -530,6 +531,10 @@ class WIP:
|
|
530
531
|
overlay_websocket_port: int = 55499
|
531
532
|
overlay_websocket_send: bool = False
|
532
533
|
monitor_to_capture: int = 0
|
534
|
+
|
535
|
+
def __post_init__(self):
|
536
|
+
if self.monitor_to_capture == -1:
|
537
|
+
self.monitor_to_capture = 0 # Default to the first monitor if not set
|
533
538
|
|
534
539
|
|
535
540
|
|
@@ -19,6 +19,7 @@ if is_windows():
|
|
19
19
|
else:
|
20
20
|
notifier = notification
|
21
21
|
|
22
|
+
|
22
23
|
def open_browser_window(note_id, query=None):
|
23
24
|
url = "http://localhost:8765"
|
24
25
|
headers = {'Content-Type': 'application/json'}
|
@@ -75,17 +76,21 @@ def open_anki_card(note_id):
|
|
75
76
|
logger.info(f"Error connecting to AnkiConnect: {e}")
|
76
77
|
|
77
78
|
|
78
|
-
|
79
79
|
def send_notification(title, message, timeout):
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
80
|
+
try:
|
81
|
+
if is_windows():
|
82
|
+
notifier.show_toast(
|
83
|
+
title, message, duration=timeout, threaded=True)
|
84
|
+
else:
|
85
|
+
notification.notify(
|
86
|
+
title=title,
|
87
|
+
message=message,
|
88
|
+
app_name="GameSentenceMiner",
|
89
|
+
timeout=timeout # Notification disappears after 5 seconds
|
90
|
+
)
|
91
|
+
except Exception as e:
|
92
|
+
logger.error(f"Failed to send notification: {e}")
|
93
|
+
|
89
94
|
|
90
95
|
def send_note_updated(tango):
|
91
96
|
send_notification(
|
@@ -94,6 +99,7 @@ def send_note_updated(tango):
|
|
94
99
|
timeout=5 # Notification disappears after 5 seconds
|
95
100
|
)
|
96
101
|
|
102
|
+
|
97
103
|
def send_screenshot_updated(tango):
|
98
104
|
send_notification(
|
99
105
|
title="Anki Card Updated",
|
@@ -132,5 +138,3 @@ def send_error_no_anki_update():
|
|
132
138
|
message=f"Anki Card not updated, Check Console for Reason!",
|
133
139
|
timeout=5 # Notification disappears after 5 seconds
|
134
140
|
)
|
135
|
-
|
136
|
-
|
@@ -127,7 +127,7 @@ def get_text_event(last_note) -> GameLine:
|
|
127
127
|
lines = game_log.values
|
128
128
|
|
129
129
|
if not lines:
|
130
|
-
raise Exception("No
|
130
|
+
raise Exception("No voicelines in GSM. GSM can only do work on text that has been sent to it since it started. If you are not getting any text into GSM, please check your setup/config.")
|
131
131
|
|
132
132
|
if not last_note:
|
133
133
|
return lines[-1]
|
@@ -168,6 +168,8 @@ def get_mined_line(last_note: AnkiCard, lines=None):
|
|
168
168
|
return lines[-1]
|
169
169
|
if not lines:
|
170
170
|
lines = get_all_lines()
|
171
|
+
if not lines:
|
172
|
+
raise Exception("No voicelines in GSM. GSM can only do work on text that has been sent to it since it started. If you are not getting any text into GSM, please check your setup/config.")
|
171
173
|
|
172
174
|
sentence = last_note.get_field(get_config().anki.sentence_field)
|
173
175
|
for line in reversed(lines):
|
@@ -65,18 +65,21 @@ def reset_window_state(hwnd):
|
|
65
65
|
|
66
66
|
# --- Hotkey Callback (equivalent to AHK ^!y::) ---
|
67
67
|
|
68
|
-
def toggle_functionality():
|
68
|
+
def toggle_functionality(window_hwnd=None):
|
69
69
|
"""
|
70
70
|
This function is called when the hotkey is pressed.
|
71
71
|
It manages the toggling logic.
|
72
72
|
"""
|
73
73
|
global is_toggled, target_hwnd
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
74
|
+
|
75
|
+
if window_hwnd:
|
76
|
+
current_hwnd = window_hwnd
|
77
|
+
else:
|
78
|
+
# Get the currently focused window (equivalent to WinGetID("A"))
|
79
|
+
current_hwnd = win32gui.GetForegroundWindow()
|
80
|
+
if not current_hwnd:
|
81
|
+
logger.info("No window is currently active!")
|
82
|
+
return
|
80
83
|
|
81
84
|
with state_lock:
|
82
85
|
# Case 1: The hotkey is pressed on the currently toggled window to disable it.
|
@@ -167,8 +170,23 @@ if __name__ == "__main__":
|
|
167
170
|
# get hotkey from args
|
168
171
|
parser = argparse.ArgumentParser(description="Window Transparency Toggle Script")
|
169
172
|
parser.add_argument('--hotkey', type=str, default=HOTKEY, help='Hotkey to toggle transparency (default: ctrl+alt+y)')
|
173
|
+
parser.add_argument('--window', type=str, help='Window title to target (optional)')
|
170
174
|
|
171
|
-
|
175
|
+
args = parser.parse_args()
|
176
|
+
hotkey = args.hotkey.lower()
|
177
|
+
target_window_title = args.window
|
178
|
+
|
179
|
+
if target_window_title:
|
180
|
+
# Find the window by title if specified
|
181
|
+
target_hwnd = win32gui.FindWindow(None, target_window_title)
|
182
|
+
logger.info(f"Searching for window with title: {target_window_title}")
|
183
|
+
logger.info(f"Target HWND: {target_hwnd}")
|
184
|
+
if not target_hwnd:
|
185
|
+
logger.error(f"Window with title '{target_window_title}' not found.")
|
186
|
+
sys.exit(1)
|
187
|
+
else:
|
188
|
+
logger.info(f"Target window found: {target_window_title}")
|
189
|
+
toggle_functionality(target_hwnd) # Enable functionality for the specified window
|
172
190
|
|
173
191
|
# Register the global hotkey
|
174
192
|
keyboard.add_hotkey(hotkey, toggle_functionality)
|
GameSentenceMiner/vad.py
CHANGED
@@ -47,6 +47,8 @@ class VADSystem:
|
|
47
47
|
else:
|
48
48
|
logger.info(result.trim_successful_string())
|
49
49
|
return result
|
50
|
+
else:
|
51
|
+
return VADResult(True, 0, get_audio_length(input_audio), "OFF", [], input_audio)
|
50
52
|
|
51
53
|
|
52
54
|
def _do_vad_processing(self, model, input_audio, output_audio, game_line):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: GameSentenceMiner
|
3
|
-
Version: 2.12.
|
3
|
+
Version: 2.12.9
|
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
|
@@ -29,7 +29,7 @@ Requires-Dist: silero-vad~=5.1.2
|
|
29
29
|
Requires-Dist: ttkbootstrap~=1.10.1
|
30
30
|
Requires-Dist: dataclasses_json~=0.6.7
|
31
31
|
Requires-Dist: win10toast; sys_platform == "win32"
|
32
|
-
Requires-Dist: numpy
|
32
|
+
Requires-Dist: numpy==2.2.6
|
33
33
|
Requires-Dist: pystray
|
34
34
|
Requires-Dist: pywin32; sys_platform == "win32"
|
35
35
|
Requires-Dist: pygetwindow; sys_platform == "win32"
|
@@ -1,10 +1,10 @@
|
|
1
1
|
GameSentenceMiner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
2
|
GameSentenceMiner/anki.py,sha256=FUwcWO0-arzfQjejQmDKP7pNNakhboo8InQ4s_jv6AY,19099
|
3
|
-
GameSentenceMiner/config_gui.py,sha256=
|
4
|
-
GameSentenceMiner/gametext.py,sha256=
|
5
|
-
GameSentenceMiner/gsm.py,sha256=
|
3
|
+
GameSentenceMiner/config_gui.py,sha256=UCipZVAVupJeA8Kaa1tqTBsZpErNIIePJabqKh4SI7s,105693
|
4
|
+
GameSentenceMiner/gametext.py,sha256=TYlkgM5-J2o8-WCKypSUitmKq_UcjOGpsZBINiR-mWk,10875
|
5
|
+
GameSentenceMiner/gsm.py,sha256=XfoxdN31rNUF5xPdCSamBlqIX3MPdOyoYWTPKNhWttE,25343
|
6
6
|
GameSentenceMiner/obs.py,sha256=bMVWAPQ6QLf4celLiOsL9BUO8pTdMn9lpT9fQCNfm7Q,18718
|
7
|
-
GameSentenceMiner/vad.py,sha256
|
7
|
+
GameSentenceMiner/vad.py,sha256=-Q1KtDJnT8zRFeEc4LLyAECf07YOUM15UDRrnWkuDgo,18817
|
8
8
|
GameSentenceMiner/ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
9
|
GameSentenceMiner/ai/ai_prompting.py,sha256=iHkEx2pQJ-tEyejOgYy4G0DcZc8qvBugVL6-CQpPSME,26089
|
10
10
|
GameSentenceMiner/assets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -18,28 +18,28 @@ GameSentenceMiner/assets/pickaxe.png,sha256=VfIGyXyIZdzEnVcc4PmG3wszPMO1W4KCT7Q_
|
|
18
18
|
GameSentenceMiner/ocr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
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
|
-
GameSentenceMiner/ocr/owocr_area_selector.py,sha256=
|
21
|
+
GameSentenceMiner/ocr/owocr_area_selector.py,sha256=seTO8kUCTW445qAUo4c7mvLtiv1SWeElpSUpP9DPDOA,26331
|
22
22
|
GameSentenceMiner/ocr/owocr_helper.py,sha256=To_tIGPgj68QkEGasQuh5vK6Zg-BLqJmkVHusp-q4Bs,25427
|
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
|
-
GameSentenceMiner/owocr/owocr/ocr.py,sha256=
|
28
|
+
GameSentenceMiner/owocr/owocr/ocr.py,sha256=jjm7TGIOaR-7JfoP_4B24uW7tLsxJL36s2kFndJy_SA,63025
|
29
29
|
GameSentenceMiner/owocr/owocr/run.py,sha256=BvUmJAb1YboDn3FNS6jP92i3gmYjTE_uGJi-_qG_LdY,65962
|
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
|
33
|
-
GameSentenceMiner/util/configuration.py,sha256=
|
33
|
+
GameSentenceMiner/util/configuration.py,sha256=M9pMUykKhwlp5sEfIip9Ikakdl_im6ArItBWeCUcgaY,36199
|
34
34
|
GameSentenceMiner/util/electron_config.py,sha256=8LZwl-T_uF5z_ig-IZcm9QI-VKaD7zaHX9u6MaLYuo4,8648
|
35
35
|
GameSentenceMiner/util/ffmpeg.py,sha256=t0tflxq170n8PZKkdw8fTZIUQfXD0p_qARa9JTdhBTc,21530
|
36
36
|
GameSentenceMiner/util/gsm_utils.py,sha256=iRyLVcodMptRhkCzLf3hyqc6_RCktXnwApi6mLju6oQ,11565
|
37
37
|
GameSentenceMiner/util/model.py,sha256=hmA_seopP2bK40v9T4ulua9TrAeWtbkdCv-sTBPBQDk,6660
|
38
|
-
GameSentenceMiner/util/notification.py,sha256=
|
38
|
+
GameSentenceMiner/util/notification.py,sha256=uZbaIpyNE2GSiGOT64sKLkHL1AShifqo6vYgZhH6CKo,4021
|
39
39
|
GameSentenceMiner/util/package.py,sha256=u1ym5z869lw5EHvIviC9h9uH97bzUXSXXA8KIn8rUvk,1157
|
40
40
|
GameSentenceMiner/util/ss_selector.py,sha256=cbjMxiKOCuOfbRvLR_PCRlykBrGtm1LXd6u5czPqkmc,4793
|
41
|
-
GameSentenceMiner/util/text_log.py,sha256=
|
42
|
-
GameSentenceMiner/util/window_transparency.py,sha256=
|
41
|
+
GameSentenceMiner/util/text_log.py,sha256=38b5Qrluev2zTxoKZ1BS06DBsoycZQ5HB0YYGeFF1Q4,6290
|
42
|
+
GameSentenceMiner/util/window_transparency.py,sha256=GtbxbmZg0-UYPXhfHff-7IKZyY2DKe4B9GdyovfmpeM,8166
|
43
43
|
GameSentenceMiner/util/communication/__init__.py,sha256=xh__yn2MhzXi9eLi89PeZWlJPn-cbBSjskhi1BRraXg,643
|
44
44
|
GameSentenceMiner/util/communication/send.py,sha256=Wki9qIY2CgYnuHbmnyKVIYkcKAN_oYS4up93XMikBaI,222
|
45
45
|
GameSentenceMiner/util/communication/websocket.py,sha256=TbphRGmxVrgEupS7tNdifsmQfWDfIp0Hio2cSiUKgsk,3317
|
@@ -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.
|
68
|
-
gamesentenceminer-2.12.
|
69
|
-
gamesentenceminer-2.12.
|
70
|
-
gamesentenceminer-2.12.
|
71
|
-
gamesentenceminer-2.12.
|
72
|
-
gamesentenceminer-2.12.
|
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,,
|
File without changes
|
{gamesentenceminer-2.12.7.post1.dist-info → gamesentenceminer-2.12.9.dist-info}/entry_points.txt
RENAMED
File without changes
|
{gamesentenceminer-2.12.7.post1.dist-info → gamesentenceminer-2.12.9.dist-info}/licenses/LICENSE
RENAMED
File without changes
|
{gamesentenceminer-2.12.7.post1.dist-info → gamesentenceminer-2.12.9.dist-info}/top_level.txt
RENAMED
File without changes
|