GameSentenceMiner 2.18.11__py3-none-any.whl → 2.18.13__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.
Potentially problematic release.
This version of GameSentenceMiner might be problematic. Click here for more details.
- GameSentenceMiner/anki.py +1 -1
- GameSentenceMiner/locales/en_us.json +2 -2
- GameSentenceMiner/locales/ja_jp.json +4 -4
- GameSentenceMiner/locales/zh_cn.json +4 -4
- GameSentenceMiner/ui/anki_confirmation.py +9 -20
- GameSentenceMiner/ui/config_gui.py +2 -2
- GameSentenceMiner/ui/screenshot_selector.py +6 -19
- GameSentenceMiner/util/configuration.py +10 -7
- GameSentenceMiner/web/texthooking_page.py +6 -1
- {gamesentenceminer-2.18.11.dist-info → gamesentenceminer-2.18.13.dist-info}/METADATA +1 -1
- {gamesentenceminer-2.18.11.dist-info → gamesentenceminer-2.18.13.dist-info}/RECORD +15 -15
- {gamesentenceminer-2.18.11.dist-info → gamesentenceminer-2.18.13.dist-info}/WHEEL +0 -0
- {gamesentenceminer-2.18.11.dist-info → gamesentenceminer-2.18.13.dist-info}/entry_points.txt +0 -0
- {gamesentenceminer-2.18.11.dist-info → gamesentenceminer-2.18.13.dist-info}/licenses/LICENSE +0 -0
- {gamesentenceminer-2.18.11.dist-info → gamesentenceminer-2.18.13.dist-info}/top_level.txt +0 -0
GameSentenceMiner/anki.py
CHANGED
|
@@ -134,7 +134,7 @@ def _prepare_anki_note_fields(note: Dict, last_note: 'AnkiCard', assets: MediaAs
|
|
|
134
134
|
if game_name_field := config.anki.game_name_field:
|
|
135
135
|
note['fields'][game_name_field] = get_current_game()
|
|
136
136
|
|
|
137
|
-
if config.ai.
|
|
137
|
+
if config.ai.add_to_anki:
|
|
138
138
|
sentence_field = note['fields'].get(config.anki.sentence_field, {})
|
|
139
139
|
sentence_to_translate = sentence_field or last_note.get_field(config.anki.sentence_field)
|
|
140
140
|
translation = get_ai_prompt_result(get_all_lines(), sentence_to_translate, game_line, get_current_game())
|
|
@@ -515,8 +515,8 @@
|
|
|
515
515
|
"ai": {
|
|
516
516
|
"title": "AI",
|
|
517
517
|
"enabled": {
|
|
518
|
-
"label": "
|
|
519
|
-
"tooltip": "Enable or disable AI
|
|
518
|
+
"label": "Add To Anki:",
|
|
519
|
+
"tooltip": "Enable or disable Adding AI Result to Anki."
|
|
520
520
|
},
|
|
521
521
|
"provider": {
|
|
522
522
|
"label": "Provider:",
|
|
@@ -513,10 +513,10 @@
|
|
|
513
513
|
},
|
|
514
514
|
"ai": {
|
|
515
515
|
"title": "AI",
|
|
516
|
-
|
|
517
|
-
"label": "
|
|
518
|
-
"tooltip": "AI
|
|
519
|
-
|
|
516
|
+
"enabled": {
|
|
517
|
+
"label": "Ankiに追加:",
|
|
518
|
+
"tooltip": "AI結果をAnkiに追加するかどうかを有効化します。"
|
|
519
|
+
},
|
|
520
520
|
"provider": {
|
|
521
521
|
"label": "プロバイダー:",
|
|
522
522
|
"tooltip": "AIプロバイダーを選択。"
|
|
@@ -444,10 +444,10 @@
|
|
|
444
444
|
"label": "最小回放大小 (KB):",
|
|
445
445
|
"tooltip": "OBS 录像回放的最小大小(KB)。如果回放小于此大小,将不抓取音频/截图。"
|
|
446
446
|
},
|
|
447
|
-
|
|
447
|
+
"turn_off_replay_buffer_management": {
|
|
448
448
|
"label": "关闭回放缓冲区管理:",
|
|
449
449
|
"tooltip": "禁用 OBS 回放缓冲区管理。如果您想在 OBS 中手动管理回放缓冲区,这将很有用。"
|
|
450
|
-
|
|
450
|
+
}
|
|
451
451
|
},
|
|
452
452
|
"profiles": {
|
|
453
453
|
"title": "配置文件",
|
|
@@ -515,8 +515,8 @@
|
|
|
515
515
|
"ai": {
|
|
516
516
|
"title": "AI",
|
|
517
517
|
"enabled": {
|
|
518
|
-
"label": "
|
|
519
|
-
"tooltip": "
|
|
518
|
+
"label": "添加到 Anki:",
|
|
519
|
+
"tooltip": "启用或禁用将 AI 结果添加到 Anki。"
|
|
520
520
|
},
|
|
521
521
|
"provider": {
|
|
522
522
|
"label": "提供商:",
|
|
@@ -46,28 +46,17 @@ class AnkiConfirmationDialog(tk.Toplevel):
|
|
|
46
46
|
# --- Create and lay out widgets ---
|
|
47
47
|
self._create_widgets(expression, sentence, screenshot_path, audio_path, translation)
|
|
48
48
|
|
|
49
|
-
# ---
|
|
49
|
+
# --- Center the dialog on screen ---
|
|
50
50
|
self.update_idletasks()
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
else:
|
|
61
|
-
self.transient(parent)
|
|
62
|
-
parent_x = parent.winfo_x()
|
|
63
|
-
parent_y = parent.winfo_y()
|
|
64
|
-
parent_width = parent.winfo_width()
|
|
65
|
-
parent_height = parent.winfo_height()
|
|
66
|
-
dialog_width = self.winfo_width()
|
|
67
|
-
dialog_height = self.winfo_height()
|
|
68
|
-
x = parent_x + (parent_width // 2) - (dialog_width // 2)
|
|
69
|
-
y = parent_y + (parent_height // 2) - (dialog_height // 2)
|
|
70
|
-
self.geometry(f'+{x}+{y}')
|
|
52
|
+
dialog_width = self.winfo_width()
|
|
53
|
+
dialog_height = self.winfo_height()
|
|
54
|
+
screen_width = self.winfo_screenwidth()
|
|
55
|
+
screen_height = self.winfo_screenheight()
|
|
56
|
+
|
|
57
|
+
x = (screen_width // 2) - (dialog_width // 2)
|
|
58
|
+
y = (screen_height // 2) - (dialog_height // 2)
|
|
59
|
+
self.geometry(f'+{x}+{y}')
|
|
71
60
|
|
|
72
61
|
self.protocol("WM_DELETE_WINDOW", self._on_cancel)
|
|
73
62
|
self.attributes('-topmost', True)
|
|
@@ -473,7 +473,7 @@ class ConfigApp:
|
|
|
473
473
|
self.localhost_bind_address_value = tk.StringVar(value=self.settings.advanced.localhost_bind_address)
|
|
474
474
|
|
|
475
475
|
# AI Settings
|
|
476
|
-
self.ai_enabled_value = tk.BooleanVar(value=self.settings.ai.
|
|
476
|
+
self.ai_enabled_value = tk.BooleanVar(value=self.settings.ai.add_to_anki)
|
|
477
477
|
self.ai_provider_value = tk.StringVar(value=self.settings.ai.provider)
|
|
478
478
|
self.gemini_model_value = tk.StringVar(value=self.settings.ai.gemini_model)
|
|
479
479
|
self.use_cpu_for_inference_value = tk.BooleanVar(value=self.settings.vad.use_cpu_for_inference)
|
|
@@ -714,7 +714,7 @@ class ConfigApp:
|
|
|
714
714
|
localhost_bind_address=self.localhost_bind_address_value.get(),
|
|
715
715
|
),
|
|
716
716
|
ai=Ai(
|
|
717
|
-
|
|
717
|
+
add_to_anki=self.ai_enabled_value.get(),
|
|
718
718
|
provider=self.ai_provider_value.get(),
|
|
719
719
|
gemini_model=self.gemini_model_value.get(),
|
|
720
720
|
groq_model=self.groq_model_value.get(),
|
|
@@ -169,30 +169,17 @@ class ScreenshotSelectorDialog(tk.Toplevel):
|
|
|
169
169
|
|
|
170
170
|
def _center_window(self):
|
|
171
171
|
"""
|
|
172
|
-
|
|
173
|
-
otherwise centers on the screen.
|
|
172
|
+
Centers the dialog on the screen regardless of parent state.
|
|
174
173
|
"""
|
|
175
174
|
self.update_idletasks()
|
|
176
175
|
|
|
177
|
-
parent = self.parent_window
|
|
178
176
|
dialog_width = self.winfo_width()
|
|
179
177
|
dialog_height = self.winfo_height()
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
x = (screen_width // 2) - (dialog_width // 2)
|
|
186
|
-
y = (screen_height // 2) - (dialog_height // 2)
|
|
187
|
-
else:
|
|
188
|
-
# PARENT IS VISIBLE: Center relative to the parent window
|
|
189
|
-
self.transient(parent) # Associate dialog with its parent
|
|
190
|
-
parent_x = parent.winfo_x()
|
|
191
|
-
parent_y = parent.winfo_y()
|
|
192
|
-
parent_width = parent.winfo_width()
|
|
193
|
-
parent_height = parent.winfo_height()
|
|
194
|
-
x = parent_x + (parent_width // 2) - (dialog_width // 2)
|
|
195
|
-
y = parent_y + (parent_height // 2) - (dialog_height // 2)
|
|
178
|
+
screen_width = self.winfo_screenwidth()
|
|
179
|
+
screen_height = self.winfo_screenheight()
|
|
180
|
+
|
|
181
|
+
x = (screen_width // 2) - (dialog_width // 2)
|
|
182
|
+
y = (screen_height // 2) - (dialog_height // 2)
|
|
196
183
|
|
|
197
184
|
self.geometry(f'+{x}+{y}')
|
|
198
185
|
|
|
@@ -619,6 +619,7 @@ class Advanced:
|
|
|
619
619
|
@dataclass
|
|
620
620
|
class Ai:
|
|
621
621
|
enabled: bool = False
|
|
622
|
+
add_to_anki: bool = False
|
|
622
623
|
anki_field: str = ''
|
|
623
624
|
provider: str = AI_GEMINI
|
|
624
625
|
gemini_model: str = 'gemini-2.5-flash-lite'
|
|
@@ -645,19 +646,21 @@ class Ai:
|
|
|
645
646
|
self.gemini_model = 'gemini-2.5-flash-lite'
|
|
646
647
|
if self.groq_model in ['RECOMMENDED', 'OTHER']:
|
|
647
648
|
self.groq_model = 'meta-llama/llama-4-scout-17b-16e-instruct'
|
|
649
|
+
|
|
650
|
+
if self.enabled:
|
|
651
|
+
self.add_to_anki = True
|
|
648
652
|
|
|
649
653
|
# Change Legacy Model Name
|
|
650
654
|
if self.gemini_model == 'gemini-2.5-flash-lite-preview-06-17':
|
|
651
655
|
self.gemini_model = 'gemini-2.5-flash-lite'
|
|
652
656
|
|
|
653
657
|
def is_configured(self) -> bool:
|
|
654
|
-
if self.
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
return True
|
|
658
|
+
if self.provider == AI_GEMINI and self.gemini_api_key and self.gemini_model:
|
|
659
|
+
return True
|
|
660
|
+
if self.provider == AI_GROQ and self.groq_api_key and self.groq_model:
|
|
661
|
+
return True
|
|
662
|
+
if self.provider == AI_OPENAI and self.open_ai_api_key and self.open_ai_model and self.open_ai_url:
|
|
663
|
+
return True
|
|
661
664
|
return False
|
|
662
665
|
|
|
663
666
|
|
|
@@ -235,14 +235,19 @@ def translate_multiple():
|
|
|
235
235
|
event_ids = data.get('ids', [])
|
|
236
236
|
if not event_ids:
|
|
237
237
|
return jsonify({'error': 'Missing ids'}), 400
|
|
238
|
+
|
|
239
|
+
if not get_config().ai.is_configured():
|
|
240
|
+
return jsonify({'error': 'AI translation is not properly configured. Please check your settings in the "AI" Tab.'}), 400
|
|
238
241
|
|
|
239
242
|
lines = [get_line_by_id(event_id) for event_id in event_ids if get_line_by_id(event_id) is not None]
|
|
240
243
|
|
|
241
244
|
text = "\n".join(line.text for line in lines)
|
|
242
245
|
|
|
246
|
+
language = get_config().general.get_native_language_name() if get_config().general.native_language else "English"
|
|
247
|
+
|
|
243
248
|
translate_multiple_lines_prompt = f"""
|
|
244
249
|
**Professional Game Localization Task**
|
|
245
|
-
Translate the following lines of game dialogue into natural-sounding, context-aware {
|
|
250
|
+
Translate the following lines of game dialogue into natural-sounding, context-aware {language}:
|
|
246
251
|
|
|
247
252
|
**Output Requirements**
|
|
248
253
|
- Maintain the original tone and style of the dialogue.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
GameSentenceMiner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
GameSentenceMiner/anki.py,sha256=
|
|
2
|
+
GameSentenceMiner/anki.py,sha256=fQ5ccQGvhbH2hmdzNSDXXJTeqfIc_GVfFPqVgBds_fM,31255
|
|
3
3
|
GameSentenceMiner/gametext.py,sha256=FBL3kgJ71hCg5Nczuo9dAEi_sLGdVIGgvc62bT5KhCc,10691
|
|
4
4
|
GameSentenceMiner/gsm.py,sha256=0hEpEBDbI9FtiKtHeyrSLKV1nys-mKTKfxLY0Dk7mOQ,36387
|
|
5
5
|
GameSentenceMiner/obs.py,sha256=tyiZhVTGxWUsc_L1A5PmmSxHuWILx-B_QnW5TKbcf4A,36873
|
|
@@ -14,9 +14,9 @@ GameSentenceMiner/assets/icon32.png,sha256=Kww0hU_qke9_22wBuO_Nq0Dv2SfnOLwMhCyGg
|
|
|
14
14
|
GameSentenceMiner/assets/icon512.png,sha256=HxUj2GHjyQsk8NV433256UxU9phPhtjCY-YB_7W4sqs,192487
|
|
15
15
|
GameSentenceMiner/assets/icon64.png,sha256=N8xgdZXvhqVQP9QUK3wX5iqxX9LxHljD7c-Bmgim6tM,9301
|
|
16
16
|
GameSentenceMiner/assets/pickaxe.png,sha256=VfIGyXyIZdzEnVcc4PmG3wszPMO1W4KCT7Q_nFK6eSE,1403829
|
|
17
|
-
GameSentenceMiner/locales/en_us.json,sha256=
|
|
18
|
-
GameSentenceMiner/locales/ja_jp.json,sha256=
|
|
19
|
-
GameSentenceMiner/locales/zh_cn.json,sha256=
|
|
17
|
+
GameSentenceMiner/locales/en_us.json,sha256=d2tObDFhZi8SZkIMbo5HfeXDo84tCpXbKXkhvzVKjyY,28166
|
|
18
|
+
GameSentenceMiner/locales/ja_jp.json,sha256=Ok4VMPS-C57OC9nVtwWF_rKLNbxHkqvAz_S1G5c_Qt4,30236
|
|
19
|
+
GameSentenceMiner/locales/zh_cn.json,sha256=NPoJqk_xayqp0dCfFdBx818-BtIXp6eni2Ql3G5Kon0,26165
|
|
20
20
|
GameSentenceMiner/ocr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
21
|
GameSentenceMiner/ocr/gsm_ocr_config.py,sha256=Ov04c-nKzh3sADxO-5JyZWVe4DlrHM9edM9tc7-97Jo,5970
|
|
22
22
|
GameSentenceMiner/ocr/ocrconfig.py,sha256=_tY8mjnzHMJrLS8E5pHqYXZjMuLoGKYgJwdhYgN-ny4,6466
|
|
@@ -36,13 +36,13 @@ GameSentenceMiner/tools/furigana_filter_preview.py,sha256=DAT2-j6vSDHr9ufk6PiaLi
|
|
|
36
36
|
GameSentenceMiner/tools/ss_selector.py,sha256=ob2oJdiYreDMMau7CvsglpnhZ1CDnJqop3lV54-PjRo,4782
|
|
37
37
|
GameSentenceMiner/tools/window_transparency.py,sha256=GtbxbmZg0-UYPXhfHff-7IKZyY2DKe4B9GdyovfmpeM,8166
|
|
38
38
|
GameSentenceMiner/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
|
-
GameSentenceMiner/ui/anki_confirmation.py,sha256=
|
|
40
|
-
GameSentenceMiner/ui/config_gui.py,sha256=
|
|
39
|
+
GameSentenceMiner/ui/anki_confirmation.py,sha256=GXNvujWSc3L8-tZ_93zdcEqJxAEBoh2oV5EP78Xcn7E,14685
|
|
40
|
+
GameSentenceMiner/ui/config_gui.py,sha256=pCZK7-PyllrNc7QmnT4MQ2rADkSC8y7YJcwz8UqjP48,155072
|
|
41
41
|
GameSentenceMiner/ui/furigana_filter_preview.py,sha256=DAT2-j6vSDHr9ufk6PiaLikEsbIp56B_OHIEeYLMwlk,17135
|
|
42
|
-
GameSentenceMiner/ui/screenshot_selector.py,sha256=
|
|
42
|
+
GameSentenceMiner/ui/screenshot_selector.py,sha256=7QvDhOMpA0ej8x_lYtu6fhmrWbM1GCg-dps3XVWwk1Q,8234
|
|
43
43
|
GameSentenceMiner/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
44
44
|
GameSentenceMiner/util/audio_player.py,sha256=-yFsf0qoTSS1ga5rCmEJZJGUSJzXCvfZHY3t0NxycDk,7896
|
|
45
|
-
GameSentenceMiner/util/configuration.py,sha256=
|
|
45
|
+
GameSentenceMiner/util/configuration.py,sha256=8cXpeUJ4hOr8Qd4JPAx1qn_phBIFuKR5D-PybThu-Qk,48233
|
|
46
46
|
GameSentenceMiner/util/db.py,sha256=1DjGjlwWnPefmQfzvMqqFPW0a0qeO-fIXE1YqKiok18,32000
|
|
47
47
|
GameSentenceMiner/util/electron_config.py,sha256=KfeJToeFFVw0IR5MKa-gBzpzaGrU-lyJbR9z-sDEHYU,8767
|
|
48
48
|
GameSentenceMiner/util/ffmpeg.py,sha256=cAzztfY36Xf2WvsJDjavoiMOvA9ac2GVdCrSB4LzHk4,29007
|
|
@@ -66,7 +66,7 @@ GameSentenceMiner/web/events.py,sha256=6Vyz5c9MdpMIa7Zqljqhap2XFQnAVYJ0CdQV64TSZ
|
|
|
66
66
|
GameSentenceMiner/web/gsm_websocket.py,sha256=B0VKpxmsRu0WRh5nFWlpDPBQ6-K2ed7TEIa0O6YWeoo,4166
|
|
67
67
|
GameSentenceMiner/web/service.py,sha256=6cgUmDgtp3ZKzuPFszowjPoq-BDtC1bS3ux6sykeaqo,6662
|
|
68
68
|
GameSentenceMiner/web/stats.py,sha256=zIK0ZzyInvvlJh87KhAKYl2CCuMJWW6Wyv7UssURFbE,22366
|
|
69
|
-
GameSentenceMiner/web/texthooking_page.py,sha256=
|
|
69
|
+
GameSentenceMiner/web/texthooking_page.py,sha256=YBcxXweFpcr-OaVYKrhIfEW3EPLZCizuWNWXhyvRCoY,16138
|
|
70
70
|
GameSentenceMiner/web/static/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
71
71
|
GameSentenceMiner/web/static/apple-touch-icon.png,sha256=OcMI8af_68DA_tweOsQ5LytTyMwm7-hPW07IfrOVgEs,46132
|
|
72
72
|
GameSentenceMiner/web/static/favicon-96x96.png,sha256=lOePzjiKl1JY2J1kT_PMdyEnrlJmi5GWbmXJunM12B4,16502
|
|
@@ -126,9 +126,9 @@ GameSentenceMiner/web/templates/components/kanji_grid/thousand_character_classic
|
|
|
126
126
|
GameSentenceMiner/web/templates/components/kanji_grid/wanikani_levels.json,sha256=8wjnnaYQqmho6t5tMxrIAc03512A2tYhQh5dfsQnfAM,11372
|
|
127
127
|
GameSentenceMiner/web/templates/components/kanji_grid/words_hk_frequency_list.json,sha256=wRkqZNPzz6DT9OTPHpXwfqW96Qb96stCQNNgOL-ZdKk,17535
|
|
128
128
|
GameSentenceMiner/wip/__init___.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
129
|
-
gamesentenceminer-2.18.
|
|
130
|
-
gamesentenceminer-2.18.
|
|
131
|
-
gamesentenceminer-2.18.
|
|
132
|
-
gamesentenceminer-2.18.
|
|
133
|
-
gamesentenceminer-2.18.
|
|
134
|
-
gamesentenceminer-2.18.
|
|
129
|
+
gamesentenceminer-2.18.13.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
130
|
+
gamesentenceminer-2.18.13.dist-info/METADATA,sha256=-RlrFfDrpOL4phyopOOrxBC02uOufNZjkxH5VFRN86Q,7488
|
|
131
|
+
gamesentenceminer-2.18.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
132
|
+
gamesentenceminer-2.18.13.dist-info/entry_points.txt,sha256=2APEP25DbfjSxGeHtwBstMH8mulVhLkqF_b9bqzU6vQ,65
|
|
133
|
+
gamesentenceminer-2.18.13.dist-info/top_level.txt,sha256=V1hUY6xVSyUEohb0uDoN4UIE6rUZ_JYx8yMyPGX4PgQ,18
|
|
134
|
+
gamesentenceminer-2.18.13.dist-info/RECORD,,
|
|
File without changes
|
{gamesentenceminer-2.18.11.dist-info → gamesentenceminer-2.18.13.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.11.dist-info → gamesentenceminer-2.18.13.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|