GameSentenceMiner 2.14.8__tar.gz → 2.14.10__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.
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/config_gui.py +19 -10
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/gsm.py +68 -8
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/locales/en_us.json +4 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/locales/ja_jp.json +4 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/locales/zh_cn.json +4 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/obs.py +12 -8
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/ocr/owocr_helper.py +1 -1
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/owocr/owocr/run.py +15 -14
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/configuration.py +1 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/notification.py +11 -1
- gamesentenceminer-2.14.10/GameSentenceMiner/util/win10toast/__init__.py +154 -0
- gamesentenceminer-2.14.10/GameSentenceMiner/util/win10toast/__main__.py +22 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner.egg-info/PKG-INFO +1 -2
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner.egg-info/SOURCES.txt +2 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner.egg-info/requires.txt +0 -1
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/PKG-INFO +1 -2
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/pyproject.toml +2 -3
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/__init__.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/ai/__init__.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/ai/ai_prompting.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/anki.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/assets/__init__.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/assets/icon.png +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/assets/icon128.png +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/assets/icon256.png +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/assets/icon32.png +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/assets/icon512.png +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/assets/icon64.png +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/assets/pickaxe.png +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/gametext.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/ocr/__init__.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/ocr/gsm_ocr_config.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/ocr/ocrconfig.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/ocr/owocr_area_selector.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/ocr/ss_picker.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/owocr/owocr/__init__.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/owocr/owocr/__main__.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/owocr/owocr/config.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/owocr/owocr/lens_betterproto.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/owocr/owocr/ocr.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/owocr/owocr/screen_coordinate_picker.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/tools/__init__.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/tools/audio_offset_selector.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/tools/ss_selector.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/tools/window_transparency.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/__init__.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/communication/__init__.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/communication/send.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/communication/websocket.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/db.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/downloader/Untitled_json.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/downloader/__init__.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/downloader/download_tools.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/downloader/oneocr_dl.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/electron_config.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/ffmpeg.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/get_overlay_coords.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/gsm_utils.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/model.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/text_log.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/vad.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/__init__.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/service.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/static/__init__.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/static/apple-touch-icon.png +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/static/favicon-96x96.png +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/static/favicon.ico +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/static/favicon.svg +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/static/site.webmanifest +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/static/style.css +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/static/web-app-manifest-192x192.png +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/static/web-app-manifest-512x512.png +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/templates/__init__.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/templates/index.html +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/templates/text_replacements.html +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/templates/utility.html +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/texthooking_page.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/wip/__init___.py +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner.egg-info/dependency_links.txt +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner.egg-info/entry_points.txt +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner.egg-info/top_level.txt +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/LICENSE +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/README.md +0 -0
- {gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/setup.cfg +0 -0
@@ -212,6 +212,7 @@ class ConfigApp:
|
|
212
212
|
|
213
213
|
self.create_vars()
|
214
214
|
self.create_tabs()
|
215
|
+
self.get_online_models()
|
215
216
|
self.notebook.bind("<<NotebookTabChanged>>", self.on_profiles_tab_selected)
|
216
217
|
|
217
218
|
button_frame = ttk.Frame(self.window)
|
@@ -285,6 +286,7 @@ class ConfigApp:
|
|
285
286
|
self.obs_close_obs_value = tk.BooleanVar(value=self.settings.obs.close_obs)
|
286
287
|
self.obs_get_game_from_scene_name_value = tk.BooleanVar(value=self.settings.obs.get_game_from_scene)
|
287
288
|
self.obs_minimum_replay_size_value = tk.StringVar(value=str(self.settings.obs.minimum_replay_size))
|
289
|
+
self.obs_turn_off_output_check_value = tk.BooleanVar(value=self.settings.obs.turn_off_output_check)
|
288
290
|
|
289
291
|
# Paths Settings
|
290
292
|
self.folder_to_watch_value = tk.StringVar(value=self.settings.paths.folder_to_watch)
|
@@ -567,7 +569,8 @@ class ConfigApp:
|
|
567
569
|
port=int(self.obs_port_value.get()),
|
568
570
|
password=self.obs_password_value.get(),
|
569
571
|
get_game_from_scene=self.obs_get_game_from_scene_name_value.get(),
|
570
|
-
minimum_replay_size=int(self.obs_minimum_replay_size_value.get())
|
572
|
+
minimum_replay_size=int(self.obs_minimum_replay_size_value.get()),
|
573
|
+
turn_off_output_check=self.obs_turn_off_output_check_value.get()
|
571
574
|
),
|
572
575
|
hotkeys=Hotkeys(
|
573
576
|
reset_line=self.reset_line_hotkey_value.get(),
|
@@ -1721,6 +1724,14 @@ class ConfigApp:
|
|
1721
1724
|
ttk.Entry(obs_frame, textvariable=self.obs_minimum_replay_size_value).grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1722
1725
|
self.current_row += 1
|
1723
1726
|
|
1727
|
+
turn_off_output_check_i18n = obs_i18n.get('turn_off_output_check', {})
|
1728
|
+
HoverInfoLabelWidget(obs_frame, text=turn_off_output_check_i18n.get('label', '...'),
|
1729
|
+
tooltip=turn_off_output_check_i18n.get('tooltip', '...'),
|
1730
|
+
row=self.current_row, column=0)
|
1731
|
+
ttk.Checkbutton(obs_frame, variable=self.obs_turn_off_output_check_value, bootstyle="round-toggle").grid(
|
1732
|
+
row=self.current_row, column=1, sticky='W', pady=2)
|
1733
|
+
self.current_row += 1
|
1734
|
+
|
1724
1735
|
self.add_reset_button(obs_frame, "obs", self.current_row, 0, self.create_obs_tab)
|
1725
1736
|
|
1726
1737
|
for col in range(3): obs_frame.grid_columnconfigure(col, weight=0)
|
@@ -1968,9 +1979,7 @@ class ConfigApp:
|
|
1968
1979
|
self.groq_models_combobox = ttk.Combobox(ai_frame, textvariable=self.groq_model_value, values=RECOMMENDED_GROQ_MODELS, state="readonly")
|
1969
1980
|
self.groq_models_combobox.grid(row=self.current_row, column=1, sticky='EW', pady=2)
|
1970
1981
|
self.current_row += 1
|
1971
|
-
|
1972
|
-
self.get_online_models()
|
1973
|
-
|
1982
|
+
|
1974
1983
|
groq_key_i18n = ai_i18n.get('groq_api_key', {})
|
1975
1984
|
HoverInfoLabelWidget(ai_frame, text=groq_key_i18n.get('label', '...'), tooltip=groq_key_i18n.get('tooltip', '...'),
|
1976
1985
|
row=self.current_row, column=0)
|
@@ -1980,8 +1989,6 @@ class ConfigApp:
|
|
1980
1989
|
groq_apikey_entry.bind("<Return>", lambda e, row=self.current_row: self.get_online_models())
|
1981
1990
|
self.current_row += 1
|
1982
1991
|
|
1983
|
-
|
1984
|
-
|
1985
1992
|
openai_url_i18n = ai_i18n.get('openai_url', {})
|
1986
1993
|
HoverInfoLabelWidget(ai_frame, text=openai_url_i18n.get('label', '...'), tooltip=openai_url_i18n.get('tooltip', '...'),
|
1987
1994
|
row=self.current_row, column=0)
|
@@ -1994,6 +2001,7 @@ class ConfigApp:
|
|
1994
2001
|
|
1995
2002
|
self.openai_model_options = []
|
1996
2003
|
self.update_models_element(ai_frame, self.current_row)
|
2004
|
+
# threading.Thread(target=self.update_models_element, args=(ai_frame, self.current_row)).start()
|
1997
2005
|
self.current_row += 1
|
1998
2006
|
|
1999
2007
|
|
@@ -2050,7 +2058,7 @@ class ConfigApp:
|
|
2050
2058
|
def get_online_models(self):
|
2051
2059
|
ai_models = AIModelsTable.one()
|
2052
2060
|
|
2053
|
-
def
|
2061
|
+
def get_models():
|
2054
2062
|
groq_models = get_groq_models()
|
2055
2063
|
gemini_models = get_gemini_models()
|
2056
2064
|
AIModelsTable.update_models(gemini_models, groq_models)
|
@@ -2099,12 +2107,13 @@ class ConfigApp:
|
|
2099
2107
|
if ai_models and ai_models.gemini_models and ai_models.groq_models:
|
2100
2108
|
if time.time() - ai_models.last_updated > 3600 * 6:
|
2101
2109
|
print("AI models are outdated, fetching new ones.")
|
2102
|
-
threading.Thread(target=
|
2110
|
+
threading.Thread(target=get_models, daemon=True).start()
|
2103
2111
|
self.gemini_model_combobox['values'] = ai_models.gemini_models
|
2104
2112
|
self.groq_models_combobox['values'] = ai_models.groq_models
|
2105
2113
|
else:
|
2106
2114
|
print("No AI models found, fetching new ones.")
|
2107
|
-
threading.Thread(target=
|
2115
|
+
threading.Thread(target=get_models, daemon=True).start()
|
2116
|
+
# get_models()
|
2108
2117
|
|
2109
2118
|
def update_models_element(self, frame, row):
|
2110
2119
|
if hasattr(self, 'last_url') and self.last_url == self.open_ai_url_value.get().strip():
|
@@ -2114,7 +2123,7 @@ class ConfigApp:
|
|
2114
2123
|
if self.open_ai_url_value.get().strip() != "" and any(c in self.open_ai_url_value.get() for c in ["localhost", "127.0.0.1"]):
|
2115
2124
|
import openai
|
2116
2125
|
# get models from openai compatible url
|
2117
|
-
client = openai.Client(api_key=self.settings.ai.open_ai_api_key, base_url=self.open_ai_url_value.get().strip())
|
2126
|
+
client = openai.Client(api_key=self.settings.ai.open_ai_api_key, base_url=self.open_ai_url_value.get().strip(), timeout=1)
|
2118
2127
|
try:
|
2119
2128
|
models = client.models.list()
|
2120
2129
|
if models:
|
@@ -34,27 +34,85 @@ try:
|
|
34
34
|
from watchdog.observers import Observer
|
35
35
|
import psutil
|
36
36
|
|
37
|
+
start_time = time.time()
|
38
|
+
from GameSentenceMiner.util.configuration import *
|
39
|
+
logger.debug(f"[Import] configuration: {time.time() - start_time:.3f}s")
|
40
|
+
|
41
|
+
start_time = time.time()
|
37
42
|
from GameSentenceMiner.util.model import VADResult
|
43
|
+
logger.debug(f"[Import] VADResult model: {time.time() - start_time:.3f}s")
|
44
|
+
|
45
|
+
start_time = time.time()
|
38
46
|
from GameSentenceMiner.vad import vad_processor
|
47
|
+
logger.debug(f"[Import] vad_processor: {time.time() - start_time:.3f}s")
|
48
|
+
|
49
|
+
start_time = time.time()
|
39
50
|
from GameSentenceMiner.util.downloader.download_tools import download_obs_if_needed, download_ffmpeg_if_needed
|
51
|
+
logger.debug(f"[Import] download_tools (download_obs_if_needed, download_ffmpeg_if_needed): {time.time() - start_time:.3f}s")
|
52
|
+
|
53
|
+
start_time = time.time()
|
40
54
|
from GameSentenceMiner.util.communication.send import send_restart_signal
|
55
|
+
logger.debug(f"[Import] send_restart_signal: {time.time() - start_time:.3f}s")
|
56
|
+
|
57
|
+
start_time = time.time()
|
41
58
|
from GameSentenceMiner.util.gsm_utils import wait_for_stable_file, make_unique_file_name, run_new_thread
|
59
|
+
logger.debug(f"[Import] gsm_utils (wait_for_stable_file, make_unique_file_name, run_new_thread): {time.time() - start_time:.3f}s")
|
60
|
+
|
61
|
+
start_time = time.time()
|
42
62
|
from GameSentenceMiner import anki
|
63
|
+
logger.debug(f"[Import] anki: {time.time() - start_time:.3f}s")
|
64
|
+
|
65
|
+
start_time = time.time()
|
43
66
|
from GameSentenceMiner import config_gui
|
67
|
+
logger.debug(f"[Import] config_gui: {time.time() - start_time:.3f}s")
|
68
|
+
|
69
|
+
start_time = time.time()
|
44
70
|
from GameSentenceMiner.util import configuration, notification, ffmpeg
|
71
|
+
logger.debug(f"[Import] util (configuration, notification, ffmpeg): {time.time() - start_time:.3f}s")
|
72
|
+
|
73
|
+
start_time = time.time()
|
45
74
|
from GameSentenceMiner import gametext
|
75
|
+
logger.debug(f"[Import] gametext: {time.time() - start_time:.3f}s")
|
76
|
+
|
77
|
+
start_time = time.time()
|
46
78
|
from GameSentenceMiner import obs
|
79
|
+
logger.debug(f"[Import] obs: {time.time() - start_time:.3f}s")
|
80
|
+
|
81
|
+
start_time = time.time()
|
47
82
|
from GameSentenceMiner.util.communication import Message
|
48
|
-
|
49
|
-
|
50
|
-
|
83
|
+
logger.debug(f"[Import] Message: {time.time() - start_time:.3f}s")
|
84
|
+
|
85
|
+
start_time = time.time()
|
86
|
+
from GameSentenceMiner.util.communication.websocket import connect_websocket, register_websocket_message_handler, FunctionName
|
87
|
+
logger.debug(f"[Import] websocket (connect_websocket, register_websocket_message_handler, FunctionName): {time.time() - start_time:.3f}s")
|
88
|
+
|
89
|
+
start_time = time.time()
|
51
90
|
from GameSentenceMiner.util.ffmpeg import get_audio_and_trim, get_video_timings, get_ffmpeg_path
|
91
|
+
logger.debug(f"[Import] util.ffmpeg (get_audio_and_trim, get_video_timings, get_ffmpeg_path): {time.time() - start_time:.3f}s")
|
92
|
+
|
93
|
+
start_time = time.time()
|
52
94
|
from GameSentenceMiner.obs import check_obs_folder_is_correct
|
95
|
+
logger.debug(f"[Import] obs.check_obs_folder_is_correct: {time.time() - start_time:.3f}s")
|
96
|
+
|
97
|
+
start_time = time.time()
|
53
98
|
from GameSentenceMiner.util.text_log import GameLine, get_text_event, get_mined_line, get_all_lines, game_log
|
99
|
+
logger.debug(f"[Import] util.text_log (GameLine, get_text_event, get_mined_line, get_all_lines, game_log): {time.time() - start_time:.3f}s")
|
100
|
+
|
101
|
+
start_time = time.time()
|
54
102
|
from GameSentenceMiner.util import *
|
103
|
+
logger.debug(f"[Import] util *: {time.time() - start_time:.3f}s")
|
104
|
+
|
105
|
+
start_time = time.time()
|
55
106
|
from GameSentenceMiner.web import texthooking_page
|
107
|
+
logger.debug(f"[Import] web.texthooking_page: {time.time() - start_time:.3f}s")
|
108
|
+
|
109
|
+
start_time = time.time()
|
56
110
|
from GameSentenceMiner.web.service import handle_texthooker_button, set_get_audio_from_video_callback
|
111
|
+
logger.debug(f"[Import] web.service (handle_texthooker_button, set_get_audio_from_video_callback): {time.time() - start_time:.3f}s")
|
112
|
+
|
113
|
+
start_time = time.time()
|
57
114
|
from GameSentenceMiner.web.texthooking_page import run_text_hooker_page
|
115
|
+
logger.debug(f"[Import] web.texthooking_page.run_text_hooker_page: {time.time() - start_time:.3f}s")
|
58
116
|
except Exception as e:
|
59
117
|
from GameSentenceMiner.util.configuration import logger, is_linux, is_windows
|
60
118
|
handle_error_in_initialization(e)
|
@@ -583,7 +641,7 @@ def handle_websocket_message(message: Message):
|
|
583
641
|
f"unknown message from electron websocket: {message.to_json()}")
|
584
642
|
|
585
643
|
|
586
|
-
def
|
644
|
+
def initialize_text_monitor():
|
587
645
|
asyncio.run(gametext.start_text_monitor())
|
588
646
|
|
589
647
|
|
@@ -668,8 +726,8 @@ async def async_main(reloading=False):
|
|
668
726
|
try:
|
669
727
|
global root, settings_window
|
670
728
|
initialize(reloading)
|
671
|
-
logger.info("Script started.")
|
672
729
|
root = ttk.Window(themename='darkly')
|
730
|
+
start_time = time.time()
|
673
731
|
settings_window = config_gui.ConfigApp(root)
|
674
732
|
initialize_async()
|
675
733
|
observer = Observer()
|
@@ -678,10 +736,12 @@ async def async_main(reloading=False):
|
|
678
736
|
observer.start()
|
679
737
|
if is_windows():
|
680
738
|
register_hotkeys()
|
681
|
-
|
682
|
-
run_new_thread(
|
739
|
+
|
740
|
+
run_new_thread(initialize_text_monitor)
|
683
741
|
run_new_thread(run_text_hooker_page)
|
684
|
-
run_new_thread(async_loop)
|
742
|
+
run_new_thread(async_loop).join()
|
743
|
+
|
744
|
+
logger.info("Initialization complete. Happy Mining! がんばれ!")
|
685
745
|
|
686
746
|
# await check_if_script_is_running()
|
687
747
|
# await log_current_pid()
|
@@ -415,6 +415,10 @@
|
|
415
415
|
"min_replay_size": {
|
416
416
|
"label": "Minimum Replay Size (KB):",
|
417
417
|
"tooltip": "Minimum Replay Size for OBS Replays in KB. If Replay is Under this, Audio/Screenshot Will not be grabbed."
|
418
|
+
},
|
419
|
+
"turn_off_output_check": {
|
420
|
+
"label": "Turn Off Output Check:",
|
421
|
+
"tooltip": "Disable the video output Replay Buffer Check."
|
418
422
|
}
|
419
423
|
},
|
420
424
|
"profiles": {
|
@@ -24,13 +24,14 @@ logging.getLogger("obsws_python").setLevel(logging.CRITICAL)
|
|
24
24
|
connecting = False
|
25
25
|
|
26
26
|
class OBSConnectionManager(threading.Thread):
|
27
|
-
def __init__(self):
|
27
|
+
def __init__(self, check_output=True):
|
28
28
|
super().__init__()
|
29
29
|
self.daemon = True
|
30
30
|
self.running = True
|
31
31
|
self.check_connection_interval = 1
|
32
32
|
self.said_no_to_replay_buffer = False
|
33
33
|
self.counter = 0
|
34
|
+
self.check_output = check_output
|
34
35
|
|
35
36
|
def run(self):
|
36
37
|
while self.running:
|
@@ -42,13 +43,16 @@ class OBSConnectionManager(threading.Thread):
|
|
42
43
|
logger.info(f"OBS WebSocket not connected. Attempting to reconnect... {e}")
|
43
44
|
gsm_status.obs_connected = False
|
44
45
|
asyncio.run(connect_to_obs())
|
45
|
-
if self.counter % 5 == 0:
|
46
|
+
if self.counter % 5 == 0 and not get_config().obs.turn_off_output_check and self.check_output:
|
46
47
|
replay_buffer_status = get_replay_buffer_status()
|
47
48
|
if replay_buffer_status and self.said_no_to_replay_buffer:
|
48
49
|
self.said_no_to_replay_buffer = False
|
49
50
|
self.counter = 0
|
50
51
|
if gsm_status.obs_connected and not replay_buffer_status and not self.said_no_to_replay_buffer:
|
51
|
-
|
52
|
+
try:
|
53
|
+
self.check_output()
|
54
|
+
except Exception as e:
|
55
|
+
pass
|
52
56
|
self.counter += 1
|
53
57
|
|
54
58
|
def stop(self):
|
@@ -172,7 +176,7 @@ def get_obs_websocket_config_values():
|
|
172
176
|
full_config.save()
|
173
177
|
reload_config()
|
174
178
|
|
175
|
-
async def connect_to_obs(retry=5):
|
179
|
+
async def connect_to_obs(retry=5, check_output=True):
|
176
180
|
global client, obs_connection_manager, event_client, connecting
|
177
181
|
if is_windows():
|
178
182
|
get_obs_websocket_config_values()
|
@@ -195,7 +199,7 @@ async def connect_to_obs(retry=5):
|
|
195
199
|
gsm_status.obs_connected = True
|
196
200
|
logger.info("Connected to OBS WebSocket.")
|
197
201
|
if not obs_connection_manager:
|
198
|
-
obs_connection_manager = OBSConnectionManager()
|
202
|
+
obs_connection_manager = OBSConnectionManager(check_output=check_output)
|
199
203
|
obs_connection_manager.start()
|
200
204
|
update_current_game()
|
201
205
|
break # Exit the loop once connected
|
@@ -211,7 +215,7 @@ async def connect_to_obs(retry=5):
|
|
211
215
|
retry -= 1
|
212
216
|
connecting = False
|
213
217
|
|
214
|
-
def connect_to_obs_sync(retry=2):
|
218
|
+
def connect_to_obs_sync(retry=2, check_output=True):
|
215
219
|
global client, obs_connection_manager, event_client
|
216
220
|
if is_windows():
|
217
221
|
get_obs_websocket_config_values()
|
@@ -231,7 +235,7 @@ def connect_to_obs_sync(retry=2):
|
|
231
235
|
timeout=1,
|
232
236
|
)
|
233
237
|
if not obs_connection_manager:
|
234
|
-
obs_connection_manager = OBSConnectionManager()
|
238
|
+
obs_connection_manager = OBSConnectionManager(check_output=check_output)
|
235
239
|
obs_connection_manager.start()
|
236
240
|
update_current_game()
|
237
241
|
logger.info("Connected to OBS WebSocket.")
|
@@ -293,7 +297,7 @@ def get_replay_buffer_status():
|
|
293
297
|
try:
|
294
298
|
return client.get_replay_buffer_status().output_active
|
295
299
|
except Exception as e:
|
296
|
-
logger.
|
300
|
+
logger.debug(f"Error getting replay buffer status: {e}")
|
297
301
|
return None
|
298
302
|
|
299
303
|
def stop_replay_buffer():
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/ocr/owocr_helper.py
RENAMED
@@ -584,7 +584,7 @@ if __name__ == "__main__":
|
|
584
584
|
keep_newline = args.keep_newline
|
585
585
|
obs_ocr = args.obs_ocr
|
586
586
|
|
587
|
-
obs.connect_to_obs_sync(retry=0)
|
587
|
+
obs.connect_to_obs_sync(retry=0, check_output=False)
|
588
588
|
|
589
589
|
# Start config change checker thread
|
590
590
|
config_check_thread = ConfigChangeCheckThread()
|
@@ -832,8 +832,8 @@ def set_last_image(image):
|
|
832
832
|
last_image.close()
|
833
833
|
except Exception:
|
834
834
|
pass
|
835
|
-
|
836
|
-
last_image = apply_adaptive_threshold_filter(image)
|
835
|
+
last_image = image
|
836
|
+
# last_image = apply_adaptive_threshold_filter(image)
|
837
837
|
|
838
838
|
|
839
839
|
def are_images_identical(img1, img2):
|
@@ -1113,6 +1113,7 @@ class OBSScreenshotThread(threading.Thread):
|
|
1113
1113
|
print(e)
|
1114
1114
|
logger.info(
|
1115
1115
|
f"An unexpected error occurred during OBS Capture : {e}", exc_info=True)
|
1116
|
+
time.sleep(.5)
|
1116
1117
|
continue
|
1117
1118
|
|
1118
1119
|
|
@@ -1757,18 +1758,18 @@ def run(read_from=None,
|
|
1757
1758
|
logger.debug(f"Could not determine if image is empty: {e}")
|
1758
1759
|
|
1759
1760
|
# Compare images, but only if it's one box, multiple boxes skews results way too much and produces false positives
|
1760
|
-
if ocr_config and len(ocr_config.rectangles) < 2:
|
1761
|
-
|
1762
|
-
|
1763
|
-
|
1764
|
-
|
1765
|
-
|
1766
|
-
else:
|
1767
|
-
|
1768
|
-
|
1769
|
-
|
1770
|
-
|
1771
|
-
|
1761
|
+
# if ocr_config and len(ocr_config.rectangles) < 2:
|
1762
|
+
# if are_images_similar(img, last_image):
|
1763
|
+
# logger.info("Captured screenshot is similar to the last one, sleeping.")
|
1764
|
+
# if time.time() - last_result_time > 10:
|
1765
|
+
# sleep_time_to_add += .005
|
1766
|
+
# continue
|
1767
|
+
# else:
|
1768
|
+
if are_images_identical(img, last_image):
|
1769
|
+
logger.info("Captured screenshot is identical to the last one, sleeping.")
|
1770
|
+
if time.time() - last_result_time > 10:
|
1771
|
+
sleep_time_to_add += .005
|
1772
|
+
continue
|
1772
1773
|
|
1773
1774
|
res, text = process_and_write_results(img, write_to, last_result, filtering, notify,
|
1774
1775
|
ocr_start_time=ocr_start_time, furigana_filter_sensitivity=get_ocr_furigana_filter_sensitivity())
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/notification.py
RENAMED
@@ -3,7 +3,7 @@ from plyer import notification
|
|
3
3
|
from GameSentenceMiner.util.configuration import logger, is_windows
|
4
4
|
|
5
5
|
if is_windows():
|
6
|
-
from win10toast import ToastNotifier
|
6
|
+
from GameSentenceMiner.util.win10toast import ToastNotifier
|
7
7
|
|
8
8
|
if is_windows():
|
9
9
|
class MyToastNotifier(ToastNotifier):
|
@@ -145,3 +145,13 @@ def send_error_notification(message):
|
|
145
145
|
message=message,
|
146
146
|
timeout=5 # Notification disappears after 5 seconds
|
147
147
|
)
|
148
|
+
|
149
|
+
|
150
|
+
if __name__ == "__main__":
|
151
|
+
send_note_updated("TestTango")
|
152
|
+
send_screenshot_updated("TestTango")
|
153
|
+
send_screenshot_saved("C:/Screenshots/test.png")
|
154
|
+
send_audio_generated_notification("C:/Audio/test.mp3")
|
155
|
+
send_check_obs_notification("Replay buffer not active")
|
156
|
+
send_error_no_anki_update()
|
157
|
+
send_error_notification("Custom error message for testing")
|
@@ -0,0 +1,154 @@
|
|
1
|
+
from __future__ import absolute_import
|
2
|
+
from __future__ import print_function
|
3
|
+
from __future__ import unicode_literals
|
4
|
+
|
5
|
+
__all__ = ['ToastNotifier']
|
6
|
+
|
7
|
+
# #############################################################################
|
8
|
+
# ########## Libraries #############
|
9
|
+
# ##################################
|
10
|
+
# standard library
|
11
|
+
import logging
|
12
|
+
import threading
|
13
|
+
from os import path
|
14
|
+
from time import sleep
|
15
|
+
|
16
|
+
# 3rd party modules
|
17
|
+
from win32api import GetModuleHandle
|
18
|
+
from win32api import PostQuitMessage
|
19
|
+
from win32con import CW_USEDEFAULT
|
20
|
+
from win32con import IDI_APPLICATION
|
21
|
+
from win32con import IMAGE_ICON
|
22
|
+
from win32con import LR_DEFAULTSIZE
|
23
|
+
from win32con import LR_LOADFROMFILE
|
24
|
+
from win32con import WM_DESTROY
|
25
|
+
from win32con import WM_USER
|
26
|
+
from win32con import WS_OVERLAPPED
|
27
|
+
from win32con import WS_SYSMENU
|
28
|
+
from win32gui import CreateWindow
|
29
|
+
from win32gui import DestroyWindow
|
30
|
+
from win32gui import LoadIcon
|
31
|
+
from win32gui import LoadImage
|
32
|
+
from win32gui import NIF_ICON
|
33
|
+
from win32gui import NIF_INFO
|
34
|
+
from win32gui import NIF_MESSAGE
|
35
|
+
from win32gui import NIF_TIP
|
36
|
+
from win32gui import NIM_ADD
|
37
|
+
from win32gui import NIM_DELETE
|
38
|
+
from win32gui import NIM_MODIFY
|
39
|
+
from win32gui import RegisterClass
|
40
|
+
from win32gui import UnregisterClass
|
41
|
+
from win32gui import Shell_NotifyIcon
|
42
|
+
from win32gui import UpdateWindow
|
43
|
+
from win32gui import WNDCLASS
|
44
|
+
|
45
|
+
# ############################################################################
|
46
|
+
# ########### Classes ##############
|
47
|
+
# ##################################
|
48
|
+
|
49
|
+
|
50
|
+
class ToastNotifier(object):
|
51
|
+
"""Create a Windows 10 toast notification.
|
52
|
+
|
53
|
+
from: https://github.com/jithurjacob/Windows-10-Toast-Notifications
|
54
|
+
"""
|
55
|
+
|
56
|
+
def __init__(self):
|
57
|
+
"""Initialize."""
|
58
|
+
self._thread = None
|
59
|
+
|
60
|
+
def _show_toast(self, title, msg,
|
61
|
+
icon_path, duration):
|
62
|
+
"""Notification settings.
|
63
|
+
|
64
|
+
:title: notification title
|
65
|
+
:msg: notification message
|
66
|
+
:icon_path: path to the .ico file to custom notification
|
67
|
+
:duration: delay in seconds before notification self-destruction
|
68
|
+
"""
|
69
|
+
message_map = {WM_DESTROY: self.on_destroy, }
|
70
|
+
|
71
|
+
# Register the window class.
|
72
|
+
self.wc = WNDCLASS()
|
73
|
+
self.hinst = self.wc.hInstance = GetModuleHandle(None)
|
74
|
+
self.wc.lpszClassName = str("PythonTaskbar") # must be a string
|
75
|
+
self.wc.lpfnWndProc = message_map # could also specify a wndproc.
|
76
|
+
try:
|
77
|
+
self.classAtom = RegisterClass(self.wc)
|
78
|
+
except:
|
79
|
+
pass #not sure of this
|
80
|
+
style = WS_OVERLAPPED | WS_SYSMENU
|
81
|
+
self.hwnd = CreateWindow(self.classAtom, "Taskbar", style,
|
82
|
+
0, 0, CW_USEDEFAULT,
|
83
|
+
CW_USEDEFAULT,
|
84
|
+
0, 0, self.hinst, None)
|
85
|
+
UpdateWindow(self.hwnd)
|
86
|
+
|
87
|
+
# icon
|
88
|
+
if icon_path is not None:
|
89
|
+
icon_path = path.realpath(icon_path)
|
90
|
+
else:
|
91
|
+
icon_path = path.join(path.dirname(path.abspath(__file__)), 'data', 'python.ico')
|
92
|
+
icon_flags = LR_LOADFROMFILE | LR_DEFAULTSIZE
|
93
|
+
try:
|
94
|
+
hicon = LoadImage(self.hinst, icon_path,
|
95
|
+
IMAGE_ICON, 0, 0, icon_flags)
|
96
|
+
except Exception as e:
|
97
|
+
logging.error("Some trouble with the icon ({}): {}"
|
98
|
+
.format(icon_path, e))
|
99
|
+
hicon = LoadIcon(0, IDI_APPLICATION)
|
100
|
+
|
101
|
+
# Taskbar icon
|
102
|
+
flags = NIF_ICON | NIF_MESSAGE | NIF_TIP
|
103
|
+
nid = (self.hwnd, 0, flags, WM_USER + 20, hicon, "Tooltip")
|
104
|
+
Shell_NotifyIcon(NIM_ADD, nid)
|
105
|
+
Shell_NotifyIcon(NIM_MODIFY, (self.hwnd, 0, NIF_INFO,
|
106
|
+
WM_USER + 20,
|
107
|
+
hicon, "Balloon Tooltip", msg, 200,
|
108
|
+
title))
|
109
|
+
# take a rest then destroy
|
110
|
+
sleep(duration)
|
111
|
+
DestroyWindow(self.hwnd)
|
112
|
+
UnregisterClass(self.wc.lpszClassName, None)
|
113
|
+
return None
|
114
|
+
|
115
|
+
def show_toast(self, title="Notification", msg="Here comes the message",
|
116
|
+
icon_path=None, duration=5, threaded=False):
|
117
|
+
"""Notification settings.
|
118
|
+
|
119
|
+
:title: notification title
|
120
|
+
:msg: notification message
|
121
|
+
:icon_path: path to the .ico file to custom notification
|
122
|
+
:duration: delay in seconds before notification self-destruction
|
123
|
+
"""
|
124
|
+
if not threaded:
|
125
|
+
self._show_toast(title, msg, icon_path, duration)
|
126
|
+
else:
|
127
|
+
if self.notification_active():
|
128
|
+
# We have an active notification, let is finish so we don't spam them
|
129
|
+
return False
|
130
|
+
|
131
|
+
self._thread = threading.Thread(target=self._show_toast, args=(title, msg, icon_path, duration))
|
132
|
+
self._thread.start()
|
133
|
+
return True
|
134
|
+
|
135
|
+
def notification_active(self):
|
136
|
+
"""See if we have an active notification showing"""
|
137
|
+
if self._thread != None and self._thread.is_alive():
|
138
|
+
# We have an active notification, let is finish we don't spam them
|
139
|
+
return True
|
140
|
+
return False
|
141
|
+
|
142
|
+
def on_destroy(self, hwnd, msg, wparam, lparam):
|
143
|
+
"""Clean after notification ended.
|
144
|
+
|
145
|
+
:hwnd:
|
146
|
+
:msg:
|
147
|
+
:wparam:
|
148
|
+
:lparam:
|
149
|
+
"""
|
150
|
+
nid = (self.hwnd, 0)
|
151
|
+
Shell_NotifyIcon(NIM_DELETE, nid)
|
152
|
+
PostQuitMessage(0)
|
153
|
+
|
154
|
+
return 0
|
@@ -0,0 +1,22 @@
|
|
1
|
+
from win10toast import ToastNotifier
|
2
|
+
import time
|
3
|
+
|
4
|
+
# #############################################################################
|
5
|
+
# ###### Stand alone program ########
|
6
|
+
# ###################################
|
7
|
+
if __name__ == "__main__":
|
8
|
+
# Example
|
9
|
+
toaster = ToastNotifier()
|
10
|
+
toaster.show_toast(
|
11
|
+
"Hello World!!!",
|
12
|
+
"Python is 10 seconds awsm!",
|
13
|
+
duration=10)
|
14
|
+
toaster.show_toast(
|
15
|
+
"Example two",
|
16
|
+
"This notification is in it's own thread!",
|
17
|
+
icon_path=None,
|
18
|
+
duration=5,
|
19
|
+
threaded=True
|
20
|
+
)
|
21
|
+
# Wait for threaded notification to finish
|
22
|
+
while toaster.notification_active(): time.sleep(0.1)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: GameSentenceMiner
|
3
|
-
Version: 2.14.
|
3
|
+
Version: 2.14.10
|
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
|
@@ -30,7 +30,6 @@ Requires-Dist: silero-vad~=5.1.2
|
|
30
30
|
Requires-Dist: ttkbootstrap~=1.10.1
|
31
31
|
Requires-Dist: dataclasses_json~=0.6.7
|
32
32
|
Requires-Dist: win10toast; sys_platform == "win32"
|
33
|
-
Requires-Dist: numpy==2.2.6
|
34
33
|
Requires-Dist: pystray
|
35
34
|
Requires-Dist: pywin32; sys_platform == "win32"
|
36
35
|
Requires-Dist: pygetwindow; sys_platform == "win32"
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner.egg-info/SOURCES.txt
RENAMED
@@ -61,6 +61,8 @@ GameSentenceMiner/util/downloader/Untitled_json.py
|
|
61
61
|
GameSentenceMiner/util/downloader/__init__.py
|
62
62
|
GameSentenceMiner/util/downloader/download_tools.py
|
63
63
|
GameSentenceMiner/util/downloader/oneocr_dl.py
|
64
|
+
GameSentenceMiner/util/win10toast/__init__.py
|
65
|
+
GameSentenceMiner/util/win10toast/__main__.py
|
64
66
|
GameSentenceMiner/web/__init__.py
|
65
67
|
GameSentenceMiner/web/service.py
|
66
68
|
GameSentenceMiner/web/texthooking_page.py
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: GameSentenceMiner
|
3
|
-
Version: 2.14.
|
3
|
+
Version: 2.14.10
|
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
|
@@ -30,7 +30,6 @@ Requires-Dist: silero-vad~=5.1.2
|
|
30
30
|
Requires-Dist: ttkbootstrap~=1.10.1
|
31
31
|
Requires-Dist: dataclasses_json~=0.6.7
|
32
32
|
Requires-Dist: win10toast; sys_platform == "win32"
|
33
|
-
Requires-Dist: numpy==2.2.6
|
34
33
|
Requires-Dist: pystray
|
35
34
|
Requires-Dist: pywin32; sys_platform == "win32"
|
36
35
|
Requires-Dist: pygetwindow; sys_platform == "win32"
|
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
|
|
7
7
|
|
8
8
|
[project]
|
9
9
|
name = "GameSentenceMiner"
|
10
|
-
version = "2.14.
|
10
|
+
version = "2.14.10"
|
11
11
|
description = "A tool for mining sentences from games. Update: Overlay?"
|
12
12
|
readme = "README.md"
|
13
13
|
requires-python = ">=3.10"
|
@@ -40,7 +40,6 @@ dependencies = [
|
|
40
40
|
"ttkbootstrap~=1.10.1",
|
41
41
|
"dataclasses_json~=0.6.7",
|
42
42
|
"win10toast; sys_platform == 'win32'",
|
43
|
-
"numpy==2.2.6",
|
44
43
|
"pystray",
|
45
44
|
"pywin32; sys_platform == 'win32'",
|
46
45
|
"pygetwindow; sys_platform == 'win32'",
|
@@ -67,7 +66,7 @@ dependencies = [
|
|
67
66
|
gamesentenceminer = "GameSentenceMiner.gsm:main"
|
68
67
|
|
69
68
|
[tool.setuptools]
|
70
|
-
packages =
|
69
|
+
packages = { find = { include = ["GameSentenceMiner*"] } }
|
71
70
|
|
72
71
|
[tool.setuptools.package-data]
|
73
72
|
"GameSentenceMiner.web" = ["static/*", "templates/*"]
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/ocr/gsm_ocr_config.py
RENAMED
File without changes
|
File without changes
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/ocr/owocr_area_selector.py
RENAMED
File without changes
|
File without changes
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/owocr/owocr/__init__.py
RENAMED
File without changes
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/owocr/owocr/__main__.py
RENAMED
File without changes
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/owocr/owocr/config.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/tools/ss_selector.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/communication/send.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/downloader/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/electron_config.py
RENAMED
File without changes
|
File without changes
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/util/get_overlay_coords.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/static/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/static/favicon.ico
RENAMED
File without changes
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/static/favicon.svg
RENAMED
File without changes
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/static/site.webmanifest
RENAMED
File without changes
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/static/style.css
RENAMED
File without changes
|
File without changes
|
File without changes
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/templates/__init__.py
RENAMED
File without changes
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/templates/index.html
RENAMED
File without changes
|
File without changes
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/templates/utility.html
RENAMED
File without changes
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner/web/texthooking_page.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner.egg-info/entry_points.txt
RENAMED
File without changes
|
{gamesentenceminer-2.14.8 → gamesentenceminer-2.14.10}/GameSentenceMiner.egg-info/top_level.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|