GameSentenceMiner 2.2.2.post2__py3-none-any.whl → 2.2.4__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/anki.py +3 -4
- GameSentenceMiner/config_gui.py +22 -8
- GameSentenceMiner/configuration.py +4 -0
- GameSentenceMiner/gametext.py +32 -3
- GameSentenceMiner/gsm.py +18 -19
- GameSentenceMiner/package_updater.py +0 -8
- {GameSentenceMiner-2.2.2.post2.dist-info → GameSentenceMiner-2.2.4.dist-info}/METADATA +2 -2
- {GameSentenceMiner-2.2.2.post2.dist-info → GameSentenceMiner-2.2.4.dist-info}/RECORD +11 -11
- {GameSentenceMiner-2.2.2.post2.dist-info → GameSentenceMiner-2.2.4.dist-info}/WHEEL +0 -0
- {GameSentenceMiner-2.2.2.post2.dist-info → GameSentenceMiner-2.2.4.dist-info}/entry_points.txt +0 -0
- {GameSentenceMiner-2.2.2.post2.dist-info → GameSentenceMiner-2.2.4.dist-info}/top_level.txt +0 -0
GameSentenceMiner/anki.py
CHANGED
@@ -107,7 +107,7 @@ def get_initial_card_info(last_note):
|
|
107
107
|
note = {'id': last_note['noteId'], 'fields': {}}
|
108
108
|
if not last_note:
|
109
109
|
return note
|
110
|
-
current_line, previous_line = get_last_two_sentences()
|
110
|
+
current_line, previous_line = get_last_two_sentences(last_note)
|
111
111
|
logger.debug(f"Previous Sentence {previous_line}")
|
112
112
|
logger.debug(f"Current Sentence {current_line}")
|
113
113
|
util.use_previous_audio = True
|
@@ -200,7 +200,6 @@ def check_for_new_cards():
|
|
200
200
|
def update_new_card():
|
201
201
|
last_card = get_last_anki_card()
|
202
202
|
if not check_tags_for_should_update(last_card):
|
203
|
-
logger.info("Card not tagged properly! Not updating!")
|
204
203
|
return
|
205
204
|
|
206
205
|
use_prev_audio = util.use_previous_audio
|
@@ -222,11 +221,11 @@ def check_tags_for_should_update(last_card):
|
|
222
221
|
if get_config().anki.tags_to_check:
|
223
222
|
found = False
|
224
223
|
for tag in last_card['tags']:
|
225
|
-
logger.info(tag)
|
226
|
-
logger.info(get_config().anki.tags_to_check)
|
227
224
|
if tag.lower() in get_config().anki.tags_to_check:
|
228
225
|
found = True
|
229
226
|
break
|
227
|
+
if not found:
|
228
|
+
logger.info(f"Card not tagged properly! Not updating! Note Tags: {last_card['tags']}, Tags_To_Check {get_config().anki.tags_to_check}")
|
230
229
|
return found
|
231
230
|
else:
|
232
231
|
return True
|
GameSentenceMiner/config_gui.py
CHANGED
@@ -1,14 +1,16 @@
|
|
1
1
|
import tkinter as tk
|
2
2
|
from tkinter import filedialog, messagebox, simpledialog
|
3
3
|
|
4
|
+
import pyperclip
|
4
5
|
import ttkbootstrap as ttk
|
5
6
|
|
6
|
-
from GameSentenceMiner.package_updater import check_for_updates, get_latest_version,
|
7
|
+
from GameSentenceMiner.package_updater import check_for_updates, get_latest_version, get_current_version
|
7
8
|
from GameSentenceMiner import obs, configuration
|
8
9
|
from GameSentenceMiner.configuration import *
|
9
10
|
|
10
11
|
settings_saved = False
|
11
12
|
on_save = []
|
13
|
+
exit_func = None
|
12
14
|
|
13
15
|
|
14
16
|
def new_tab(func):
|
@@ -45,6 +47,7 @@ class HoverInfoWidget:
|
|
45
47
|
self.tooltip = None
|
46
48
|
|
47
49
|
|
50
|
+
|
48
51
|
class ConfigApp:
|
49
52
|
def __init__(self):
|
50
53
|
self.window = ttk.Window(themename='darkly')
|
@@ -75,7 +78,12 @@ class ConfigApp:
|
|
75
78
|
|
76
79
|
self.window.withdraw()
|
77
80
|
|
81
|
+
def add_save_hook(self, func):
|
82
|
+
on_save.append(func)
|
78
83
|
|
84
|
+
def add_exit_hook(self, func):
|
85
|
+
global exit_func
|
86
|
+
exit_func = func
|
79
87
|
|
80
88
|
def show(self):
|
81
89
|
obs.update_current_game()
|
@@ -93,9 +101,8 @@ class ConfigApp:
|
|
93
101
|
update_available, version = check_for_updates()
|
94
102
|
if update_available:
|
95
103
|
messagebox.showinfo("Update", "GSM Will Copy the Update Command to your clipboard, please run it in a terminal.")
|
96
|
-
|
97
|
-
|
98
|
-
messagebox.showinfo("Update Unsuccessful", "Couldn't Start Update, please update manually.")
|
104
|
+
pyperclip.copy("pip install --upgrade GameSentenceMiner")
|
105
|
+
exit_func(None, None)
|
99
106
|
else:
|
100
107
|
messagebox.showinfo("No Update Found", "No update found.")
|
101
108
|
|
@@ -109,9 +116,6 @@ class ConfigApp:
|
|
109
116
|
elif show_no_update:
|
110
117
|
messagebox.showinfo("No Update Found", "No update found.")
|
111
118
|
|
112
|
-
def add_save_hook(self, func):
|
113
|
-
on_save.append(func)
|
114
|
-
|
115
119
|
def save_settings(self, profile_change=False):
|
116
120
|
global settings_saved
|
117
121
|
|
@@ -139,6 +143,7 @@ class ConfigApp:
|
|
139
143
|
picture_field=self.picture_field.get(),
|
140
144
|
word_field=self.word_field.get(),
|
141
145
|
previous_sentence_field=self.previous_sentence_field.get(),
|
146
|
+
previous_image_field=self.previous_image_field.get(),
|
142
147
|
custom_tags=[tag.strip() for tag in self.custom_tags.get().split(',') if tag.strip()],
|
143
148
|
tags_to_check=[tag.strip().lower() for tag in self.tags_to_check.get().split(',') if tag.strip()],
|
144
149
|
add_game_tag=self.add_game_tag.get(),
|
@@ -476,6 +481,15 @@ class ConfigApp:
|
|
476
481
|
row=self.current_row,
|
477
482
|
column=2)
|
478
483
|
|
484
|
+
ttk.Label(anki_frame, text="Previous Image Field:").grid(row=self.current_row, column=0, sticky='W')
|
485
|
+
self.previous_image_field = ttk.Entry(anki_frame)
|
486
|
+
self.previous_image_field.insert(0, self.settings.anki.previous_image_field)
|
487
|
+
self.previous_image_field.grid(row=self.current_row, column=1)
|
488
|
+
self.add_label_and_increment_row(anki_frame,
|
489
|
+
"Field in Anki for the image line of previous Image. If Empty, will not populate",
|
490
|
+
row=self.current_row,
|
491
|
+
column=2)
|
492
|
+
|
479
493
|
ttk.Label(anki_frame, text="Custom Tags:").grid(row=self.current_row, column=0, sticky='W')
|
480
494
|
self.custom_tags = ttk.Entry(anki_frame)
|
481
495
|
self.custom_tags.insert(0, ', '.join(self.settings.anki.custom_tags))
|
@@ -813,7 +827,7 @@ class ConfigApp:
|
|
813
827
|
def add_profile(self):
|
814
828
|
new_profile_name = simpledialog.askstring("Input", "Enter new profile name:")
|
815
829
|
if new_profile_name:
|
816
|
-
self.master_config.configs[new_profile_name] = self.master_config.
|
830
|
+
self.master_config.configs[new_profile_name] = self.master_config.get_default_config()
|
817
831
|
self.profile_combobox['values'] = list(self.master_config.configs.keys())
|
818
832
|
self.profile_combobox.set(new_profile_name)
|
819
833
|
self.save_settings()
|
@@ -64,6 +64,7 @@ class Anki:
|
|
64
64
|
picture_field: str = "Picture"
|
65
65
|
word_field: str = 'Word'
|
66
66
|
previous_sentence_field: str = ''
|
67
|
+
previous_image_field: str = ''
|
67
68
|
custom_tags: List[str] = None # Initialize to None and set it in __post_init__
|
68
69
|
tags_to_check: List[str] = None
|
69
70
|
add_game_tag: bool = True
|
@@ -249,6 +250,9 @@ class Config:
|
|
249
250
|
def get_all_profile_names(self):
|
250
251
|
return list(self.configs.keys())
|
251
252
|
|
253
|
+
def get_default_config(self):
|
254
|
+
return self.configs[DEFAULT_CONFIG]
|
255
|
+
|
252
256
|
|
253
257
|
def get_app_directory():
|
254
258
|
if platform == 'win32': # Windows
|
GameSentenceMiner/gametext.py
CHANGED
@@ -112,7 +112,7 @@ def get_line_timing(last_note):
|
|
112
112
|
if sentence:
|
113
113
|
for i, (line, clip_time) in enumerate(reversed(line_history.items())):
|
114
114
|
similarity = similar(remove_html_tags(sentence), line)
|
115
|
-
if similarity >= 0.60: # 80% similarity threshold
|
115
|
+
if similarity >= 0.60 or line in remove_html_tags(sentence): # 80% similarity threshold
|
116
116
|
line_time = clip_time
|
117
117
|
next_line = prev_clip_time
|
118
118
|
break
|
@@ -123,6 +123,35 @@ def get_line_timing(last_note):
|
|
123
123
|
return line_time, next_line
|
124
124
|
|
125
125
|
|
126
|
-
def get_last_two_sentences():
|
126
|
+
def get_last_two_sentences(last_note):
|
127
|
+
def similar(a, b):
|
128
|
+
return SequenceMatcher(None, a, b).ratio()
|
127
129
|
lines = list(line_history.items())
|
128
|
-
|
130
|
+
|
131
|
+
if not last_note:
|
132
|
+
return lines[-1][0] if lines else '', lines[-2][0] if len(lines) > 1 else ''
|
133
|
+
|
134
|
+
current_line = ""
|
135
|
+
prev_line = ""
|
136
|
+
|
137
|
+
sentence = last_note['fields'][get_config().anki.sentence_field]['value']
|
138
|
+
if sentence:
|
139
|
+
found = False
|
140
|
+
for i, (line, clip_time) in enumerate(reversed(lines)):
|
141
|
+
similarity = similar(remove_html_tags(sentence), line)
|
142
|
+
logger.debug(f"Comparing: {remove_html_tags(sentence)} with {line} - Similarity: {similarity}")
|
143
|
+
if found:
|
144
|
+
prev_line = line
|
145
|
+
break
|
146
|
+
if similarity >= 0.60 or line in remove_html_tags(sentence): # 80% similarity threshold
|
147
|
+
found = True
|
148
|
+
current_line = line
|
149
|
+
|
150
|
+
logger.debug(f"Current Line: {current_line}")
|
151
|
+
logger.debug(f"Previous Line: {prev_line}")
|
152
|
+
|
153
|
+
if not current_line or not prev_line:
|
154
|
+
logger.debug("Couldn't find lines in history, using last two lines")
|
155
|
+
return lines[-1][0] if lines else '', lines[-2][0] if len(lines) > 1 else ''
|
156
|
+
|
157
|
+
return current_line, prev_line
|
GameSentenceMiner/gsm.py
CHANGED
@@ -29,7 +29,7 @@ from GameSentenceMiner.util import *
|
|
29
29
|
if is_windows():
|
30
30
|
import win32api
|
31
31
|
|
32
|
-
obs_process: Popen
|
32
|
+
obs_process: Popen = None
|
33
33
|
procs_to_close = []
|
34
34
|
settings_window: config_gui.ConfigApp = None
|
35
35
|
obs_paused = False
|
@@ -89,22 +89,19 @@ class VideoToAudioHandler(FileSystemEventHandler):
|
|
89
89
|
should_update_audio = False
|
90
90
|
vad_trimmed_audio = ""
|
91
91
|
logger.info("No SentenceAudio Field in config, skipping audio processing!")
|
92
|
-
try:
|
93
92
|
# Only update sentenceaudio if it's not present. Want to avoid accidentally overwriting sentence audio
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
except FileNotFoundError as f:
|
105
|
-
logger.error("Something went wrong with processing, anki card not updated")
|
93
|
+
try:
|
94
|
+
if get_config().anki.update_anki and last_note:
|
95
|
+
anki.update_anki_card(last_note, note, audio_path=final_audio_output, video_path=video_path,
|
96
|
+
tango=tango,
|
97
|
+
should_update_audio=should_update_audio,
|
98
|
+
ss_time=ss_timing)
|
99
|
+
elif get_config().features.notify_on_update and should_update_audio:
|
100
|
+
notification.send_audio_generated_notification(vad_trimmed_audio)
|
101
|
+
except Exception as e:
|
102
|
+
logger.exception(f"Card failed to update! Maybe it was removed? {e}")
|
106
103
|
except Exception as e:
|
107
|
-
logger.
|
104
|
+
logger.exception(f"Some error was hit catching to allow further work to be done: {e}")
|
108
105
|
if get_config().paths.remove_video and os.path.exists(video_path):
|
109
106
|
os.remove(video_path) # Optionally remove the video after conversion
|
110
107
|
if get_config().paths.remove_audio and os.path.exists(vad_trimmed_audio):
|
@@ -320,10 +317,11 @@ def close_obs():
|
|
320
317
|
|
321
318
|
def restart_obs():
|
322
319
|
global obs_process
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
320
|
+
if obs_process:
|
321
|
+
close_obs()
|
322
|
+
time.sleep(2)
|
323
|
+
obs_process = obs.start_obs()
|
324
|
+
obs.connect_to_obs(start_replay=True)
|
327
325
|
|
328
326
|
def cleanup():
|
329
327
|
logger.info("Performing cleanup...")
|
@@ -393,6 +391,7 @@ def main(reloading=False, do_config_input=True):
|
|
393
391
|
if get_config().general.open_config_on_startup:
|
394
392
|
settings_window.window.after(0, settings_window.show)
|
395
393
|
settings_window.add_save_hook(update_icon)
|
394
|
+
settings_window.on_exit = exit_program
|
396
395
|
settings_window.window.mainloop()
|
397
396
|
except KeyboardInterrupt:
|
398
397
|
cleanup()
|
@@ -39,11 +39,3 @@ def check_for_updates(force=False):
|
|
39
39
|
return False, latest_version
|
40
40
|
except Exception as e:
|
41
41
|
logger.error(f"Error checking for updates: {e}")
|
42
|
-
|
43
|
-
def update():
|
44
|
-
try:
|
45
|
-
pyperclip.copy("pip install --upgrade GameSentenceMiner")
|
46
|
-
exit()
|
47
|
-
except Exception as e:
|
48
|
-
logger.error(f"Error updating {PACKAGE_NAME}: {e}")
|
49
|
-
return False
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: GameSentenceMiner
|
3
|
-
Version: 2.2.
|
4
|
-
Summary: A tool for mining sentences from games. Update:
|
3
|
+
Version: 2.2.4
|
4
|
+
Summary: A tool for mining sentences from games. Update: Fix Previous Sentence When Mining from History
|
5
5
|
Author-email: Beangate <bpwhelan95@gmail.com>
|
6
6
|
License: MIT License
|
7
7
|
Project-URL: Homepage, https://github.com/bpwhelan/GameSentenceMiner
|
@@ -1,14 +1,14 @@
|
|
1
1
|
GameSentenceMiner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
GameSentenceMiner/anki.py,sha256=
|
3
|
-
GameSentenceMiner/config_gui.py,sha256=
|
4
|
-
GameSentenceMiner/configuration.py,sha256=
|
2
|
+
GameSentenceMiner/anki.py,sha256=urgly10zM7etTXfagK327TKWXVq146jqkpTmewoim7s,9238
|
3
|
+
GameSentenceMiner/config_gui.py,sha256=EBl5TuzyqXUovq4YF-UQsl4W7DAzIpdzANI52AiTyoU,49743
|
4
|
+
GameSentenceMiner/configuration.py,sha256=Wd4Cozdus_Tl33_Qz4twibBx6p_3_mHMzdZfZ-B1qI4,14124
|
5
5
|
GameSentenceMiner/ffmpeg.py,sha256=txTpco-IGWtfF8vIiWUzrtgI5TA1xPVIK-WJWxU02mM,10878
|
6
|
-
GameSentenceMiner/gametext.py,sha256=
|
7
|
-
GameSentenceMiner/gsm.py,sha256=
|
6
|
+
GameSentenceMiner/gametext.py,sha256=QQbZnV1eZ1DxwJl9fwfn8p6z1UjpSk6JRpxKmJ4CrUw,5210
|
7
|
+
GameSentenceMiner/gsm.py,sha256=qDa8Q8bjBNnmVGLDqiEYLTC_ZyBkS3zw2SmP4Tc_h0o,16375
|
8
8
|
GameSentenceMiner/model.py,sha256=oh8VVT8T1UKekbmP6MGNgQ8jIuQ_7Rg4GPzDCn2kJo8,1999
|
9
9
|
GameSentenceMiner/notification.py,sha256=WBaQWoPNhW4XqdPBUmxPBgjk0ngzH_4v9zMQ-XQAKC8,2010
|
10
10
|
GameSentenceMiner/obs.py,sha256=3Flcjxy812VpF78EPI7sxlGx6yyM3GfqzlinW17SK20,6231
|
11
|
-
GameSentenceMiner/package_updater.py,sha256=
|
11
|
+
GameSentenceMiner/package_updater.py,sha256=0uaLAp0WrWqostNTBWRS0laITjI9aN9Yt_6GXosS4NQ,1278
|
12
12
|
GameSentenceMiner/util.py,sha256=cgKpPfRpouWI6tjE_35MWp8nXqRzXs3LvsYXWm5_DOg,4584
|
13
13
|
GameSentenceMiner/downloader/Untitled_json.py,sha256=RUUl2bbbCpUDUUS0fP0tdvf5FngZ7ILdA_J5TFYAXUQ,15272
|
14
14
|
GameSentenceMiner/downloader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -17,8 +17,8 @@ GameSentenceMiner/vad/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
|
|
17
17
|
GameSentenceMiner/vad/silero_trim.py,sha256=syDJX_KbFmdyFFtnQqYTD0tICsUCJizYhs-atPgXtxA,1549
|
18
18
|
GameSentenceMiner/vad/vosk_helper.py,sha256=-AAwK0cgOC5rK3_gL0sQgrPJ75E49g_PxZR4d5ckwc4,5826
|
19
19
|
GameSentenceMiner/vad/whisper_helper.py,sha256=bpR1HVnJRn9H5u8XaHBqBJ6JwIjzqn-Fajps8QmQ4zc,3411
|
20
|
-
GameSentenceMiner-2.2.
|
21
|
-
GameSentenceMiner-2.2.
|
22
|
-
GameSentenceMiner-2.2.
|
23
|
-
GameSentenceMiner-2.2.
|
24
|
-
GameSentenceMiner-2.2.
|
20
|
+
GameSentenceMiner-2.2.4.dist-info/METADATA,sha256=-S903oxc3YHCUd7s_F97f0CARKRJgk3E-yZ5AZ2u8pQ,10141
|
21
|
+
GameSentenceMiner-2.2.4.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
22
|
+
GameSentenceMiner-2.2.4.dist-info/entry_points.txt,sha256=2APEP25DbfjSxGeHtwBstMH8mulVhLkqF_b9bqzU6vQ,65
|
23
|
+
GameSentenceMiner-2.2.4.dist-info/top_level.txt,sha256=V1hUY6xVSyUEohb0uDoN4UIE6rUZ_JYx8yMyPGX4PgQ,18
|
24
|
+
GameSentenceMiner-2.2.4.dist-info/RECORD,,
|
File without changes
|
{GameSentenceMiner-2.2.2.post2.dist-info → GameSentenceMiner-2.2.4.dist-info}/entry_points.txt
RENAMED
File without changes
|
File without changes
|