GameSentenceMiner 2.5.9__py3-none-any.whl → 2.5.11__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 +6 -3
- GameSentenceMiner/config_gui.py +3 -0
- GameSentenceMiner/configuration.py +52 -0
- GameSentenceMiner/ffmpeg.py +3 -2
- GameSentenceMiner/gsm.py +42 -31
- GameSentenceMiner/model.py +6 -0
- GameSentenceMiner/notification.py +9 -1
- GameSentenceMiner/obs.py +20 -3
- GameSentenceMiner/utility_gui.py +6 -2
- {gamesentenceminer-2.5.9.dist-info → gamesentenceminer-2.5.11.dist-info}/METADATA +1 -1
- gamesentenceminer-2.5.11.dist-info/RECORD +29 -0
- gamesentenceminer-2.5.9.dist-info/RECORD +0 -29
- {gamesentenceminer-2.5.9.dist-info → gamesentenceminer-2.5.11.dist-info}/WHEEL +0 -0
- {gamesentenceminer-2.5.9.dist-info → gamesentenceminer-2.5.11.dist-info}/entry_points.txt +0 -0
- {gamesentenceminer-2.5.9.dist-info → gamesentenceminer-2.5.11.dist-info}/licenses/LICENSE +0 -0
- {gamesentenceminer-2.5.9.dist-info → gamesentenceminer-2.5.11.dist-info}/top_level.txt +0 -0
GameSentenceMiner/anki.py
CHANGED
@@ -28,7 +28,7 @@ card_queue = []
|
|
28
28
|
|
29
29
|
|
30
30
|
def update_anki_card(last_note: AnkiCard, note=None, audio_path='', video_path='', tango='', reuse_audio=False,
|
31
|
-
should_update_audio=True, ss_time=0, game_line=None):
|
31
|
+
should_update_audio=True, ss_time=0, game_line=None, selected_lines=None):
|
32
32
|
global audio_in_anki, screenshot_in_anki, prev_screenshot_in_anki
|
33
33
|
update_audio = should_update_audio and (get_config().anki.sentence_audio_field and not
|
34
34
|
last_note.get_field(get_config().anki.sentence_audio_field) or get_config().anki.overwrite_audio)
|
@@ -44,7 +44,7 @@ def update_anki_card(last_note: AnkiCard, note=None, audio_path='', video_path='
|
|
44
44
|
if get_config().paths.remove_screenshot:
|
45
45
|
os.remove(screenshot)
|
46
46
|
if get_config().anki.previous_image_field:
|
47
|
-
prev_screenshot = ffmpeg.get_screenshot(video_path, ffmpeg.get_screenshot_time(video_path, game_line.prev))
|
47
|
+
prev_screenshot = ffmpeg.get_screenshot(video_path, ffmpeg.get_screenshot_time(video_path, selected_lines[0].prev if selected_lines else game_line.prev))
|
48
48
|
prev_screenshot_in_anki = store_media_file(prev_screenshot)
|
49
49
|
if get_config().paths.remove_screenshot:
|
50
50
|
os.remove(prev_screenshot)
|
@@ -158,7 +158,10 @@ def get_initial_card_info(last_note: AnkiCard, selected_lines):
|
|
158
158
|
last_note.get_field(get_config().anki.previous_sentence_field):
|
159
159
|
logger.debug(
|
160
160
|
f"Adding Previous Sentence: {get_config().anki.previous_sentence_field and game_line.prev.text and not last_note.get_field(get_config().anki.previous_sentence_field)}")
|
161
|
-
|
161
|
+
if selected_lines:
|
162
|
+
note['fields'][get_config().anki.previous_sentence_field] = selected_lines[0].prev.text
|
163
|
+
else:
|
164
|
+
note['fields'][get_config().anki.previous_sentence_field] = game_line.prev.text
|
162
165
|
return note
|
163
166
|
|
164
167
|
|
GameSentenceMiner/config_gui.py
CHANGED
@@ -216,6 +216,8 @@ class ConfigApp:
|
|
216
216
|
self.master_config.current_profile = current_profile
|
217
217
|
self.master_config.set_config_for_profile(current_profile, config)
|
218
218
|
|
219
|
+
self.master_config = self.master_config.sync_shared_fields()
|
220
|
+
|
219
221
|
# Serialize the config instance to JSON
|
220
222
|
with open(get_config_path(), 'w') as file:
|
221
223
|
file.write(self.master_config.to_json(indent=4))
|
@@ -225,6 +227,7 @@ class ConfigApp:
|
|
225
227
|
if self.master_config.get_config().restart_required(prev_config):
|
226
228
|
logger.info("Restart Required for some settings to take affect!")
|
227
229
|
send_restart_signal()
|
230
|
+
|
228
231
|
settings_saved = True
|
229
232
|
configuration.reload_config()
|
230
233
|
self.settings = get_config()
|
@@ -303,6 +303,58 @@ class Config:
|
|
303
303
|
def get_default_config(self):
|
304
304
|
return self.configs[DEFAULT_CONFIG]
|
305
305
|
|
306
|
+
def sync_shared_fields(self):
|
307
|
+
config = self.get_config()
|
308
|
+
for profile in self.configs.values():
|
309
|
+
self.sync_shared_field(config.hotkeys, profile.hotkeys, "reset_line")
|
310
|
+
self.sync_shared_field(config.hotkeys, profile.hotkeys, "take_screenshot")
|
311
|
+
self.sync_shared_field(config.hotkeys, profile.hotkeys, "open_utility")
|
312
|
+
self.sync_shared_field(config.hotkeys, profile.hotkeys, "play_latest_audio")
|
313
|
+
# self.sync_shared_field(config.advanced, profile.advanced, "audio_player_path")
|
314
|
+
# self.sync_shared_field(config.advanced, profile.advanced, "video_player_path")
|
315
|
+
# self.sync_shared_field(config.advanced, profile.advanced, "show_screenshot_buttons")
|
316
|
+
self.sync_shared_field(config.anki, profile.anki, "url")
|
317
|
+
self.sync_shared_field(config.anki, profile.anki, "sentence_field")
|
318
|
+
self.sync_shared_field(config.anki, profile.anki, "sentence_audio_field")
|
319
|
+
self.sync_shared_field(config.anki, profile.anki, "picture_field")
|
320
|
+
self.sync_shared_field(config.anki, profile.anki, "word_field")
|
321
|
+
self.sync_shared_field(config.anki, profile.anki, "previous_sentence_field")
|
322
|
+
self.sync_shared_field(config.anki, profile.anki, "previous_image_field")
|
323
|
+
self.sync_shared_field(config.anki, profile.anki, "tags_to_check")
|
324
|
+
self.sync_shared_field(config.anki, profile.anki, "add_game_tag")
|
325
|
+
self.sync_shared_field(config.anki, profile.anki, "polling_rate")
|
326
|
+
self.sync_shared_field(config.anki, profile.anki, "overwrite_audio")
|
327
|
+
self.sync_shared_field(config.anki, profile.anki, "overwrite_picture")
|
328
|
+
self.sync_shared_field(config.anki, profile.anki, "multi_overwrites_sentence")
|
329
|
+
self.sync_shared_field(config.anki, profile.anki, "anki_custom_fields")
|
330
|
+
self.sync_shared_field(config.general, profile.general, "open_config_on_startup")
|
331
|
+
self.sync_shared_field(config.general, profile.general, "open_multimine_on_startup")
|
332
|
+
self.sync_shared_field(config.general, profile.general, "websocket_uri")
|
333
|
+
self.sync_shared_field(config.audio, profile.audio, "external_tool")
|
334
|
+
self.sync_shared_field(config.audio, profile.audio, "anki_media_collection")
|
335
|
+
self.sync_shared_field(config, profile, "advanced")
|
336
|
+
self.sync_shared_field(config, profile, "paths")
|
337
|
+
self.sync_shared_field(config, profile, "obs")
|
338
|
+
|
339
|
+
return self
|
340
|
+
|
341
|
+
def sync_shared_field(self, config, config2, field_name):
|
342
|
+
try:
|
343
|
+
config_value = getattr(config, field_name, None)
|
344
|
+
config2_value = getattr(config2, field_name, None)
|
345
|
+
|
346
|
+
if config_value != config2_value: # Check if values are different.
|
347
|
+
if config_value is not None:
|
348
|
+
logging.info(f"Syncing shared field '{field_name}' to other profile.")
|
349
|
+
setattr(config2, field_name, config_value)
|
350
|
+
elif config2_value is not None:
|
351
|
+
logging.info(f"Syncing shared field '{field_name}' to current profile.")
|
352
|
+
setattr(config, field_name, config2_value)
|
353
|
+
except AttributeError as e:
|
354
|
+
logging.error(f"AttributeError during sync of '{field_name}': {e}")
|
355
|
+
except Exception as e:
|
356
|
+
logging.error(f"An unexpected error occurred during sync of '{field_name}': {e}")
|
357
|
+
|
306
358
|
|
307
359
|
def get_default_anki_path():
|
308
360
|
if platform == 'win32': # Windows
|
GameSentenceMiner/ffmpeg.py
CHANGED
@@ -191,7 +191,7 @@ def trim_audio_based_on_last_line(untrimmed_audio, video_path, game_line, next_l
|
|
191
191
|
|
192
192
|
ffmpeg_command = ffmpeg_base_command_list + [
|
193
193
|
"-i", untrimmed_audio,
|
194
|
-
"-ss", start_trim_time]
|
194
|
+
"-ss", str(start_trim_time)]
|
195
195
|
if next_line and next_line > game_line.time:
|
196
196
|
end_total_seconds = total_seconds + (next_line - game_line.time).total_seconds() + 1
|
197
197
|
hours, remainder = divmod(end_total_seconds, 3600)
|
@@ -222,7 +222,8 @@ def get_video_timings(video_path, game_line):
|
|
222
222
|
total_seconds = file_length - time_delta.total_seconds()
|
223
223
|
total_seconds_after_offset = total_seconds + get_config().audio.beginning_offset
|
224
224
|
if total_seconds < 0 or total_seconds >= file_length:
|
225
|
-
logger.
|
225
|
+
logger.error("Line mined is outside of the replay buffer! Defaulting to the beginning of the replay buffer. ")
|
226
|
+
logger.info("Recommend either increasing replay buffer length in OBS Settings or mining faster.")
|
226
227
|
return 0, 0, 0
|
227
228
|
|
228
229
|
hours, remainder = divmod(total_seconds_after_offset, 3600)
|
GameSentenceMiner/gsm.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import os.path
|
1
2
|
import signal
|
2
3
|
import time
|
3
4
|
from subprocess import Popen
|
@@ -25,6 +26,7 @@ from GameSentenceMiner.configuration import *
|
|
25
26
|
from GameSentenceMiner.downloader.download_tools import download_obs_if_needed, download_ffmpeg_if_needed
|
26
27
|
from GameSentenceMiner.ffmpeg import get_audio_and_trim, get_video_timings
|
27
28
|
from GameSentenceMiner.gametext import get_text_event, get_mined_line, GameLine
|
29
|
+
from GameSentenceMiner.obs import check_obs_folder_is_correct
|
28
30
|
from GameSentenceMiner.util import *
|
29
31
|
from GameSentenceMiner.utility_gui import init_utility_window, get_utility_window
|
30
32
|
from GameSentenceMiner.vad import silero_trim, whisper_helper, vosk_helper
|
@@ -70,21 +72,27 @@ class VideoToAudioHandler(FileSystemEventHandler):
|
|
70
72
|
|
71
73
|
@staticmethod
|
72
74
|
def convert_to_audio(video_path):
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
75
|
+
try:
|
76
|
+
if get_utility_window().line_for_audio:
|
77
|
+
line: GameLine = get_utility_window().line_for_audio
|
78
|
+
get_utility_window().line_for_audio = None
|
79
|
+
if get_config().advanced.audio_player_path:
|
80
|
+
audio = VideoToAudioHandler.get_audio(line, line.next.time if line.next else None, video_path, temporary=True)
|
81
|
+
play_audio_in_external(audio)
|
82
|
+
os.remove(video_path)
|
83
|
+
elif get_config().advanced.video_player_path:
|
84
|
+
play_video_in_external(line, video_path)
|
85
|
+
return
|
86
|
+
if get_utility_window().line_for_screenshot:
|
87
|
+
line: GameLine = get_utility_window().line_for_screenshot
|
88
|
+
get_utility_window().line_for_screenshot = None
|
89
|
+
screenshot = ffmpeg.get_screenshot_for_line(video_path, line)
|
90
|
+
os.startfile(screenshot)
|
79
91
|
os.remove(video_path)
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
line: GameLine = get_utility_window().line_for_screenshot
|
85
|
-
get_utility_window().line_for_screenshot = None
|
86
|
-
screenshot = ffmpeg.get_screenshot_for_line(video_path, line)
|
87
|
-
os.startfile(screenshot)
|
92
|
+
return
|
93
|
+
except Exception as e:
|
94
|
+
logger.error(f"Error Playing Audio/Video: {e}")
|
95
|
+
logger.debug(f"Error Playing Audio/Video: {e}", exc_info=True)
|
88
96
|
os.remove(video_path)
|
89
97
|
return
|
90
98
|
try:
|
@@ -128,8 +136,8 @@ class VideoToAudioHandler(FileSystemEventHandler):
|
|
128
136
|
ss_timing = ffmpeg.get_screenshot_time(video_path, mined_line)
|
129
137
|
if last_note:
|
130
138
|
logger.debug(last_note.to_json())
|
131
|
-
|
132
|
-
note = anki.get_initial_card_info(last_note,
|
139
|
+
selected_lines = get_utility_window().get_selected_lines()
|
140
|
+
note = anki.get_initial_card_info(last_note, selected_lines)
|
133
141
|
tango = last_note.get_field(get_config().anki.word_field) if last_note else ''
|
134
142
|
get_utility_window().reset_checkboxes()
|
135
143
|
|
@@ -149,17 +157,19 @@ class VideoToAudioHandler(FileSystemEventHandler):
|
|
149
157
|
tango=tango,
|
150
158
|
should_update_audio=should_update_audio,
|
151
159
|
ss_time=ss_timing,
|
152
|
-
game_line=start_line
|
160
|
+
game_line=start_line,
|
161
|
+
selected_lines=selected_lines)
|
153
162
|
elif get_config().features.notify_on_update and should_update_audio:
|
154
163
|
notification.send_audio_generated_notification(vad_trimmed_audio)
|
155
164
|
except Exception as e:
|
156
165
|
logger.error(f"Failed Processing and/or adding to Anki: Reason {e}")
|
157
166
|
logger.debug(f"Some error was hit catching to allow further work to be done: {e}", exc_info=True)
|
158
167
|
notification.send_error_no_anki_update()
|
159
|
-
|
160
|
-
os.
|
161
|
-
|
162
|
-
os.
|
168
|
+
finally:
|
169
|
+
if get_config().paths.remove_video and os.path.exists(video_path):
|
170
|
+
os.remove(video_path) # Optionally remove the video after conversion
|
171
|
+
if get_config().paths.remove_audio and os.path.exists(vad_trimmed_audio):
|
172
|
+
os.remove(vad_trimmed_audio) # Optionally remove the screenshot after conversion
|
163
173
|
|
164
174
|
|
165
175
|
@staticmethod
|
@@ -226,18 +236,17 @@ def play_video_in_external(line, filepath):
|
|
226
236
|
|
227
237
|
start, _, _ = get_video_timings(filepath, line)
|
228
238
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
command.append(
|
235
|
-
|
236
|
-
command.extend([convert_to_vlc_seconds(start), os.path.normpath(filepath)])
|
239
|
+
if start:
|
240
|
+
if "vlc" in get_config().advanced.video_player_path:
|
241
|
+
command.append("--start-time")
|
242
|
+
else:
|
243
|
+
command.append("--start")
|
244
|
+
command.append(convert_to_vlc_seconds(start))
|
245
|
+
command.append(os.path.normpath(filepath))
|
237
246
|
|
238
247
|
try:
|
239
248
|
proc = subprocess.Popen(command)
|
240
|
-
print(f"Opened {filepath} in
|
249
|
+
print(f"Opened {filepath} in {get_config().advanced.video_player_path}.")
|
241
250
|
threading.Thread(target=remove_video_when_closed, args=(proc, filepath)).start()
|
242
251
|
except FileNotFoundError:
|
243
252
|
print("VLC not found. Make sure it's installed and in your PATH.")
|
@@ -535,7 +544,8 @@ def initialize_async():
|
|
535
544
|
if get_config().obs.enabled:
|
536
545
|
if get_config().obs.open_obs:
|
537
546
|
tasks.append(obs.start_obs)
|
538
|
-
|
547
|
+
else:
|
548
|
+
tasks.append(obs.connect_to_obs)
|
539
549
|
tasks.append(anki.start_monitoring_anki)
|
540
550
|
if get_config().vad.do_vad_postprocessing:
|
541
551
|
if VOSK in (get_config().vad.backup_vad_model, get_config().vad.selected_vad_model):
|
@@ -571,6 +581,7 @@ def main(reloading=False):
|
|
571
581
|
init_utility_window(root)
|
572
582
|
initialize(reloading)
|
573
583
|
initialize_async()
|
584
|
+
check_obs_folder_is_correct()
|
574
585
|
observer = Observer()
|
575
586
|
observer.schedule(VideoToAudioHandler(), get_config().paths.folder_to_watch, recursive=False)
|
576
587
|
observer.start()
|
GameSentenceMiner/model.py
CHANGED
@@ -77,6 +77,12 @@ class SceneItemsResponse:
|
|
77
77
|
# def __init__(self, **kwargs):
|
78
78
|
# self.sceneItems = [SceneItem(**item) for item in kwargs['sceneItems']]
|
79
79
|
|
80
|
+
|
81
|
+
@dataclass_json
|
82
|
+
@dataclass
|
83
|
+
class RecordDirectory:
|
84
|
+
recordDirectory: str
|
85
|
+
|
80
86
|
#
|
81
87
|
# @dataclass_json
|
82
88
|
# @dataclass
|
@@ -6,9 +6,17 @@ from win10toast import ToastNotifier
|
|
6
6
|
|
7
7
|
from GameSentenceMiner.configuration import logger
|
8
8
|
|
9
|
+
class MyToastNotifier(ToastNotifier):
|
10
|
+
def __init__(self):
|
11
|
+
super().__init__()
|
12
|
+
|
13
|
+
def on_destroy(self, hwnd, msg, wparam, lparam):
|
14
|
+
super().on_destroy(hwnd, msg, wparam, lparam)
|
15
|
+
return 0
|
16
|
+
|
9
17
|
system = platform.system()
|
10
18
|
if system == "Windows":
|
11
|
-
notifier =
|
19
|
+
notifier = MyToastNotifier()
|
12
20
|
else:
|
13
21
|
notifier = notification
|
14
22
|
|
GameSentenceMiner/obs.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import logging
|
2
|
+
import os.path
|
2
3
|
import subprocess
|
3
4
|
import time
|
4
5
|
|
@@ -32,11 +33,21 @@ def start_obs():
|
|
32
33
|
return obs_pid
|
33
34
|
obs_process = subprocess.Popen([obs_path, '--disable-shutdown-check', '--portable'], cwd=os.path.dirname(obs_path))
|
34
35
|
logger.info("OBS launched")
|
36
|
+
connect_to_obs()
|
35
37
|
return obs_process.pid
|
36
38
|
except Exception as e:
|
37
39
|
logger.error(f"Error launching OBS: {e}")
|
38
40
|
return None
|
39
41
|
|
42
|
+
def check_obs_folder_is_correct():
|
43
|
+
obs_record_directory = get_record_directory()
|
44
|
+
if obs_record_directory and os.path.normpath(obs_record_directory) != os.path.normpath(
|
45
|
+
get_config().paths.folder_to_watch):
|
46
|
+
logger.info("OBS Path Setting wrong, OBS Recording folder in GSM Config")
|
47
|
+
get_config().paths.folder_to_watch = os.path.normpath(obs_record_directory)
|
48
|
+
get_master_config().sync_shared_fields()
|
49
|
+
save_full_config(get_master_config())
|
50
|
+
|
40
51
|
def is_obs_running(obs_path):
|
41
52
|
obs_path = os.path.abspath(obs_path) # Normalize path
|
42
53
|
for process in psutil.process_iter(['exe']):
|
@@ -114,7 +125,7 @@ def disconnect_from_obs():
|
|
114
125
|
client = None
|
115
126
|
logger.info("Disconnected from OBS WebSocket.")
|
116
127
|
|
117
|
-
def do_obs_call(request, from_dict = None, retry=
|
128
|
+
def do_obs_call(request, from_dict = None, retry=10):
|
118
129
|
try:
|
119
130
|
response = client.call(request)
|
120
131
|
if not response.status and retry > 0:
|
@@ -163,14 +174,13 @@ def stop_replay_buffer():
|
|
163
174
|
except Exception as e:
|
164
175
|
logger.error(f"Error stopping replay buffer: {e}")
|
165
176
|
|
166
|
-
|
167
177
|
# Save the current replay buffer
|
168
178
|
def save_replay_buffer():
|
169
179
|
try:
|
170
180
|
replay_buffer_started = client.call(requests.GetReplayBufferStatus()).datain['outputActive']
|
171
181
|
if replay_buffer_started:
|
172
182
|
client.call(requests.SaveReplayBuffer())
|
173
|
-
logger.info("Replay buffer saved.")
|
183
|
+
logger.info("Replay buffer saved. If your log stops bere, make sure your obs output path matches \"Path To Watch\" in GSM settings.")
|
174
184
|
else:
|
175
185
|
logger.error("Replay Buffer is not active, could not save Replay Buffer!")
|
176
186
|
except Exception as e:
|
@@ -192,6 +202,13 @@ def get_source_from_scene(scene_name):
|
|
192
202
|
logger.error(f"Error getting source from scene: {e}")
|
193
203
|
return ''
|
194
204
|
|
205
|
+
def get_record_directory():
|
206
|
+
try:
|
207
|
+
return do_obs_call(requests.GetRecordDirectory(), RecordDirectory.from_dict).recordDirectory
|
208
|
+
except Exception as e:
|
209
|
+
logger.error(f"Error getting recording folder: {e}")
|
210
|
+
return ''
|
211
|
+
|
195
212
|
|
196
213
|
def get_screenshot():
|
197
214
|
try:
|
GameSentenceMiner/utility_gui.py
CHANGED
@@ -78,8 +78,12 @@ class UtilityApp:
|
|
78
78
|
|
79
79
|
def add_text(self, line):
|
80
80
|
if line.text:
|
81
|
-
|
82
|
-
|
81
|
+
try:
|
82
|
+
var = tk.BooleanVar()
|
83
|
+
self.items.append((line, var))
|
84
|
+
except Exception as e:
|
85
|
+
logger.error(f"NOT AN ERROR: Attempted to add text to multi-mine window, before it was initialized: {e}")
|
86
|
+
return
|
83
87
|
|
84
88
|
if len(self.items) > 10:
|
85
89
|
if self.checkboxes:
|
@@ -0,0 +1,29 @@
|
|
1
|
+
GameSentenceMiner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
+
GameSentenceMiner/anki.py,sha256=xeWU1jX1ZK6tZVnDPqhBzetkCxdbPUWG1LkUy0sfHVg,13089
|
3
|
+
GameSentenceMiner/config_gui.py,sha256=v4XRxGqRddqCrdv1UHu4Gnp7aMjL-CCCHBFlTy1Y2v0,61265
|
4
|
+
GameSentenceMiner/configuration.py,sha256=DXlwEV4A7X3yzVV6UomY2jmmYAZx_jjMRxZeweoCtRE,20149
|
5
|
+
GameSentenceMiner/ffmpeg.py,sha256=fzOxrn-a4KqFdUY2oove164CTDOSsdPQtzqRW5f1P7c,12002
|
6
|
+
GameSentenceMiner/gametext.py,sha256=LORVdE2WEo1CDI8gonc7qxrhbS4KFKXFQVKjhlkpLbc,7368
|
7
|
+
GameSentenceMiner/gsm.py,sha256=XZLc_HwA8Zzxas0M0oFYbjRwgXa7OLPhT2QXhoiUVzQ,25125
|
8
|
+
GameSentenceMiner/model.py,sha256=JdnkT4VoPOXmOpRgFdvERZ09c9wLN6tUJxdrKlGZcqo,5305
|
9
|
+
GameSentenceMiner/notification.py,sha256=FY39ChSRK0Y8TQ6lBGsLnpZUFPtFpSy2tweeXVoV7kc,2809
|
10
|
+
GameSentenceMiner/obs.py,sha256=EcgQ0VdeYXGeXCyvk8mBiHBL-HHai037BoCXomH9ge4,8239
|
11
|
+
GameSentenceMiner/package.py,sha256=YlS6QRMuVlm6mdXx0rlXv9_3erTGS21jaP3PNNWfAH0,1250
|
12
|
+
GameSentenceMiner/util.py,sha256=tkaoU1bj8iPMTNwUCWUzFLAnT44Ot92D1tYwQMEnARw,7336
|
13
|
+
GameSentenceMiner/utility_gui.py,sha256=H4aOddlsrVR768RwbMzYScCziuOz1JeySUigNrPlaac,7692
|
14
|
+
GameSentenceMiner/communication/__init__.py,sha256=_jGn9PJxtOAOPtJ2rI-Qu9hEHVZVpIvWlxKvqk91_zI,638
|
15
|
+
GameSentenceMiner/communication/send.py,sha256=oOJdCS6-LNX90amkRn5FL2xqx6THGm56zHR2ntVIFTE,229
|
16
|
+
GameSentenceMiner/communication/websocket.py,sha256=vrZ9KwRUyZOepjayJkxZZTsNIbHGcDLgDRO9dNDwizM,2914
|
17
|
+
GameSentenceMiner/downloader/Untitled_json.py,sha256=RUUl2bbbCpUDUUS0fP0tdvf5FngZ7ILdA_J5TFYAXUQ,15272
|
18
|
+
GameSentenceMiner/downloader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
|
+
GameSentenceMiner/downloader/download_tools.py,sha256=mI1u_FGBmBqDIpCH3jOv8DOoZ3obgP5pIf9o9SVfX2Q,8131
|
20
|
+
GameSentenceMiner/vad/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
21
|
+
GameSentenceMiner/vad/silero_trim.py,sha256=-thDIZLuTLra3YBj7WR16Z6JeDgSpge2YuahprBvD8I,1585
|
22
|
+
GameSentenceMiner/vad/vosk_helper.py,sha256=BI_mg_qyrjNbuEJjXSUDoV0FWEtQtEOAPmrrNixnZ_8,5974
|
23
|
+
GameSentenceMiner/vad/whisper_helper.py,sha256=OF4J8TPPoKPJR1uFwrWAZ2Q7v0HJkVvNGmF8l1tACX0,3447
|
24
|
+
gamesentenceminer-2.5.11.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
25
|
+
gamesentenceminer-2.5.11.dist-info/METADATA,sha256=7yFwFF9yNCL_KdU8_aYpg6BeWpiQKBjWD1sm6Scl9UI,5436
|
26
|
+
gamesentenceminer-2.5.11.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
27
|
+
gamesentenceminer-2.5.11.dist-info/entry_points.txt,sha256=2APEP25DbfjSxGeHtwBstMH8mulVhLkqF_b9bqzU6vQ,65
|
28
|
+
gamesentenceminer-2.5.11.dist-info/top_level.txt,sha256=V1hUY6xVSyUEohb0uDoN4UIE6rUZ_JYx8yMyPGX4PgQ,18
|
29
|
+
gamesentenceminer-2.5.11.dist-info/RECORD,,
|
@@ -1,29 +0,0 @@
|
|
1
|
-
GameSentenceMiner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
GameSentenceMiner/anki.py,sha256=YcdNDpUskjdxi8upZ5SLGTyRbO8NlOPcqsV_8akTwuM,12877
|
3
|
-
GameSentenceMiner/config_gui.py,sha256=cLKVliB0X61WNduNisOmaEtqSr1mvTO6ZAiv-t2jW-8,61194
|
4
|
-
GameSentenceMiner/configuration.py,sha256=-b1wW6EkkOFwF1No1uZLD2nPUV5gfBIzG5a8_ykqyUI,16691
|
5
|
-
GameSentenceMiner/ffmpeg.py,sha256=Bvkk0TMHtoQkpEYQls48CbC4TB0-FzrnqQhRNg36hVk,11831
|
6
|
-
GameSentenceMiner/gametext.py,sha256=LORVdE2WEo1CDI8gonc7qxrhbS4KFKXFQVKjhlkpLbc,7368
|
7
|
-
GameSentenceMiner/gsm.py,sha256=FahSpCMBQGZjbROTfrDFUrELJ09TvOKCsWKFXpeuaIU,24473
|
8
|
-
GameSentenceMiner/model.py,sha256=bZm-2vkIw4gQCGLB02eDoTtO1Ymb_dnHk0VDJDFO3y8,5228
|
9
|
-
GameSentenceMiner/notification.py,sha256=2d8_8DUxImeC1zY-V4c_PZw1zbvvGZ6KiAnPaSmH9G0,2592
|
10
|
-
GameSentenceMiner/obs.py,sha256=N7XoPSzLk9rHi4sgsG_LS2dN06MrqwN2mpSHfjONTjE,7368
|
11
|
-
GameSentenceMiner/package.py,sha256=YlS6QRMuVlm6mdXx0rlXv9_3erTGS21jaP3PNNWfAH0,1250
|
12
|
-
GameSentenceMiner/util.py,sha256=tkaoU1bj8iPMTNwUCWUzFLAnT44Ot92D1tYwQMEnARw,7336
|
13
|
-
GameSentenceMiner/utility_gui.py,sha256=aVdI9zVXADS53g7QtTgmkVK1LumBsXF4Lou3qJzgHN8,7487
|
14
|
-
GameSentenceMiner/communication/__init__.py,sha256=_jGn9PJxtOAOPtJ2rI-Qu9hEHVZVpIvWlxKvqk91_zI,638
|
15
|
-
GameSentenceMiner/communication/send.py,sha256=oOJdCS6-LNX90amkRn5FL2xqx6THGm56zHR2ntVIFTE,229
|
16
|
-
GameSentenceMiner/communication/websocket.py,sha256=vrZ9KwRUyZOepjayJkxZZTsNIbHGcDLgDRO9dNDwizM,2914
|
17
|
-
GameSentenceMiner/downloader/Untitled_json.py,sha256=RUUl2bbbCpUDUUS0fP0tdvf5FngZ7ILdA_J5TFYAXUQ,15272
|
18
|
-
GameSentenceMiner/downloader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
|
-
GameSentenceMiner/downloader/download_tools.py,sha256=mI1u_FGBmBqDIpCH3jOv8DOoZ3obgP5pIf9o9SVfX2Q,8131
|
20
|
-
GameSentenceMiner/vad/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
21
|
-
GameSentenceMiner/vad/silero_trim.py,sha256=-thDIZLuTLra3YBj7WR16Z6JeDgSpge2YuahprBvD8I,1585
|
22
|
-
GameSentenceMiner/vad/vosk_helper.py,sha256=BI_mg_qyrjNbuEJjXSUDoV0FWEtQtEOAPmrrNixnZ_8,5974
|
23
|
-
GameSentenceMiner/vad/whisper_helper.py,sha256=OF4J8TPPoKPJR1uFwrWAZ2Q7v0HJkVvNGmF8l1tACX0,3447
|
24
|
-
gamesentenceminer-2.5.9.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
25
|
-
gamesentenceminer-2.5.9.dist-info/METADATA,sha256=tQ1mZZNVR5H06FYNkgokrzWUd7IZW6piZtR6GlPbDDs,5435
|
26
|
-
gamesentenceminer-2.5.9.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
27
|
-
gamesentenceminer-2.5.9.dist-info/entry_points.txt,sha256=2APEP25DbfjSxGeHtwBstMH8mulVhLkqF_b9bqzU6vQ,65
|
28
|
-
gamesentenceminer-2.5.9.dist-info/top_level.txt,sha256=V1hUY6xVSyUEohb0uDoN4UIE6rUZ_JYx8yMyPGX4PgQ,18
|
29
|
-
gamesentenceminer-2.5.9.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|