GameSentenceMiner 2.18.8__tar.gz → 2.18.9__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.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/ui/anki_confirmation.py +99 -6
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/get_overlay_coords.py +10 -10
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner.egg-info/PKG-INFO +1 -1
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/PKG-INFO +1 -1
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/pyproject.toml +1 -1
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/__init__.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/ai/__init__.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/ai/ai_prompting.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/anki.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/assets/__init__.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/assets/icon.png +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/assets/icon128.png +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/assets/icon256.png +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/assets/icon32.png +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/assets/icon512.png +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/assets/icon64.png +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/assets/pickaxe.png +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/gametext.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/gsm.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/locales/en_us.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/locales/ja_jp.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/locales/zh_cn.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/obs.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/ocr/__init__.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/ocr/gsm_ocr_config.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/ocr/ocrconfig.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/ocr/owocr_area_selector.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/ocr/owocr_helper.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/ocr/ss_picker.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/owocr/owocr/__init__.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/owocr/owocr/__main__.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/owocr/owocr/config.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/owocr/owocr/lens_betterproto.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/owocr/owocr/ocr.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/owocr/owocr/run.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/owocr/owocr/screen_coordinate_picker.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/tools/__init__.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/tools/audio_offset_selector.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/tools/furigana_filter_preview.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/tools/ss_selector.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/tools/window_transparency.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/ui/__init__.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/ui/config_gui.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/ui/screenshot_selector.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/__init__.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/audio_player.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/communication/__init__.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/communication/send.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/communication/websocket.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/configuration.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/db.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/downloader/Untitled_json.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/downloader/__init__.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/downloader/download_tools.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/downloader/oneocr_dl.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/electron_config.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/ffmpeg.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/gsm_utils.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/model.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/notification.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/text_log.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/win10toast/__init__.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/win10toast/__main__.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/vad.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/__init__.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/database_api.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/events.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/gsm_websocket.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/service.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/__init__.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/apple-touch-icon.png +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/css/dashboard-shared.css +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/css/kanji-grid.css +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/css/overview.css +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/css/popups-shared.css +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/css/search.css +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/css/shared.css +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/css/stats.css +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/favicon-96x96.png +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/favicon.ico +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/favicon.svg +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/js/anki_stats.js +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/js/database.js +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/js/goals.js +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/js/kanji-grid.js +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/js/overview.js +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/js/search.js +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/js/shared.js +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/js/stats.js +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/site.webmanifest +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/style.css +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/web-app-manifest-192x192.png +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/web-app-manifest-512x512.png +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/stats.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/anki_stats.html +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/basic_kanji_book_bkb_v1_v2.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/duolingo_kanji.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/grade.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/hk_primary_learning.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/hkscs2016.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/hsk_levels.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/humanum_frequency_list.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/jis_levels.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/jlpt_level.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/jpdb_kanji_frequency_list.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/jpdbv2_kanji_frequency_list.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/jun_das_modern_chinese_character_frequency_list.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/kanji_in_context_revised_edition.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/kanji_kentei_level.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/mainland_china_elementary_textbook_characters.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/moe_way_quiz.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/official_kanji.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/remembering_the_kanji.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/standard_form_of_national_characters.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/table_of_general_standard_chinese_characters.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/the_kodansha_kanji_learners_course_klc.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/thousand_character_classic.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/wanikani_levels.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/kanji_grid/words_hk_frequency_list.json +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/navigation.html +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/components/theme-styles.html +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/database.html +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/goals.html +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/index.html +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/overview.html +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/search.html +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/stats.html +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/utility.html +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/texthooking_page.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/wip/__init___.py +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner.egg-info/SOURCES.txt +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner.egg-info/dependency_links.txt +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner.egg-info/entry_points.txt +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner.egg-info/requires.txt +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner.egg-info/top_level.txt +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/LICENSE +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/README.md +0 -0
- {gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/setup.cfg +0 -0
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/ui/anki_confirmation.py
RENAMED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import tkinter as tk
|
|
2
2
|
from tkinter import scrolledtext
|
|
3
|
+
from tkinter import messagebox
|
|
3
4
|
from PIL import Image, ImageTk
|
|
4
5
|
|
|
5
6
|
import ttkbootstrap as ttk
|
|
6
|
-
from GameSentenceMiner.util.configuration import get_config, logger, gsm_state
|
|
7
|
+
from GameSentenceMiner.util.configuration import get_config, logger, gsm_state, get_temporary_directory
|
|
7
8
|
from GameSentenceMiner.util.audio_player import AudioPlayer
|
|
9
|
+
from GameSentenceMiner.util.gsm_utils import make_unique_file_name
|
|
8
10
|
|
|
9
11
|
import platform
|
|
10
12
|
import subprocess
|
|
11
13
|
import os
|
|
14
|
+
import requests
|
|
15
|
+
from urllib.parse import quote
|
|
12
16
|
|
|
13
17
|
class AnkiConfirmationDialog(tk.Toplevel):
|
|
14
18
|
"""
|
|
@@ -20,13 +24,18 @@ class AnkiConfirmationDialog(tk.Toplevel):
|
|
|
20
24
|
self.screenshot_timestamp = screenshot_timestamp
|
|
21
25
|
self.translation_text = None
|
|
22
26
|
self.sentence_text = None
|
|
27
|
+
self.sentence = sentence # Store sentence text for TTS
|
|
23
28
|
|
|
24
29
|
# Initialize screenshot_path here, will be updated by button if needed
|
|
25
|
-
self.screenshot_path = screenshot_path
|
|
30
|
+
self.screenshot_path = screenshot_path
|
|
31
|
+
self.audio_path = audio_path # Store audio path so it can be updated
|
|
26
32
|
|
|
27
33
|
# Audio player management
|
|
28
34
|
self.audio_player = AudioPlayer(finished_callback=self._audio_finished)
|
|
29
35
|
self.audio_button = None # Store reference to audio button
|
|
36
|
+
self.audio_path_label = None # Store reference to audio path label
|
|
37
|
+
self.tts_button = None # Store reference to TTS button
|
|
38
|
+
self.tts_status_label = None # Store reference to TTS status label
|
|
30
39
|
|
|
31
40
|
self.title("Confirm Anki Card Details")
|
|
32
41
|
self.result = None # This will store the user's choice
|
|
@@ -123,18 +132,36 @@ class AnkiConfirmationDialog(tk.Toplevel):
|
|
|
123
132
|
# Audio Path
|
|
124
133
|
if audio_path and os.path.isfile(audio_path):
|
|
125
134
|
ttk.Label(main_frame, text="Audio Path:", font=("-weight bold")).grid(row=row, column=0, sticky="ne", padx=5, pady=2)
|
|
126
|
-
ttk.Label(main_frame, text=audio_path if audio_path else "No Audio", wraplength=400, justify="left")
|
|
135
|
+
self.audio_path_label = ttk.Label(main_frame, text=audio_path if audio_path else "No Audio", wraplength=400, justify="left")
|
|
136
|
+
self.audio_path_label.grid(row=row, column=1, sticky="w", padx=5, pady=2)
|
|
127
137
|
if audio_path and os.path.isfile(audio_path):
|
|
128
138
|
self.audio_button = ttk.Button(
|
|
129
|
-
main_frame,
|
|
130
|
-
text="▶",
|
|
131
|
-
command=lambda: self._play_audio(audio_path),
|
|
139
|
+
main_frame,
|
|
140
|
+
text="▶",
|
|
141
|
+
command=lambda: self._play_audio(self.audio_path),
|
|
132
142
|
bootstyle="outline-info",
|
|
133
143
|
width=12
|
|
134
144
|
)
|
|
135
145
|
self.audio_button.grid(row=row, column=2, sticky="w", padx=5, pady=2)
|
|
136
146
|
|
|
137
147
|
row += 1
|
|
148
|
+
|
|
149
|
+
# TTS Button - only show if TTS is enabled in config
|
|
150
|
+
if get_config().vad.use_tts_as_fallback and sentence:
|
|
151
|
+
self.tts_button = ttk.Button(
|
|
152
|
+
main_frame,
|
|
153
|
+
text="🔊 Generate TTS Audio",
|
|
154
|
+
command=self._generate_tts_audio,
|
|
155
|
+
bootstyle="info",
|
|
156
|
+
width=20
|
|
157
|
+
)
|
|
158
|
+
self.tts_button.grid(row=row, column=1, sticky="w", padx=5, pady=2)
|
|
159
|
+
|
|
160
|
+
# TTS Status Label
|
|
161
|
+
self.tts_status_label = ttk.Label(main_frame, text="", foreground="green")
|
|
162
|
+
self.tts_status_label.grid(row=row, column=2, sticky="w", padx=5, pady=2)
|
|
163
|
+
|
|
164
|
+
row += 1
|
|
138
165
|
|
|
139
166
|
# Action Buttons
|
|
140
167
|
button_frame = ttk.Frame(main_frame)
|
|
@@ -215,6 +242,72 @@ class AnkiConfirmationDialog(tk.Toplevel):
|
|
|
215
242
|
else:
|
|
216
243
|
self.audio_button.config(text="▶ Play Audio", bootstyle="outline-info")
|
|
217
244
|
|
|
245
|
+
def _generate_tts_audio(self):
|
|
246
|
+
"""Generate TTS audio from the sentence text"""
|
|
247
|
+
try:
|
|
248
|
+
# Get the current sentence text from the widget
|
|
249
|
+
sentence_text = self.sentence_text.get("1.0", tk.END).strip()
|
|
250
|
+
|
|
251
|
+
if not sentence_text:
|
|
252
|
+
messagebox.showerror("TTS Error", "No sentence text available for TTS generation.")
|
|
253
|
+
return
|
|
254
|
+
|
|
255
|
+
# URL-encode the sentence text
|
|
256
|
+
encoded_text = quote(sentence_text)
|
|
257
|
+
|
|
258
|
+
# Build the TTS URL by replacing $s with the encoded text
|
|
259
|
+
tts_url = get_config().vad.tts_url.replace("$s", encoded_text)
|
|
260
|
+
|
|
261
|
+
logger.info(f"Fetching TTS audio from: {tts_url}")
|
|
262
|
+
|
|
263
|
+
# Fetch TTS audio from the URL
|
|
264
|
+
response = requests.get(tts_url, timeout=10)
|
|
265
|
+
|
|
266
|
+
if not response.ok:
|
|
267
|
+
error_msg = f"Failed to fetch TTS audio: HTTP {response.status_code}"
|
|
268
|
+
logger.error(error_msg)
|
|
269
|
+
messagebox.showerror("TTS Error", f"{error_msg}\n\nIs your TTS service running?")
|
|
270
|
+
return
|
|
271
|
+
|
|
272
|
+
# Save TTS audio to GSM temporary directory with game name
|
|
273
|
+
game_name = gsm_state.current_game if gsm_state.current_game else "tts"
|
|
274
|
+
filename = f"{game_name}_tts_audio.opus"
|
|
275
|
+
tts_audio_path = make_unique_file_name(
|
|
276
|
+
os.path.join(get_temporary_directory(), filename)
|
|
277
|
+
)
|
|
278
|
+
with open(tts_audio_path, 'wb') as f:
|
|
279
|
+
f.write(response.content)
|
|
280
|
+
|
|
281
|
+
logger.info(f"TTS audio saved to: {tts_audio_path}")
|
|
282
|
+
|
|
283
|
+
# Update the audio path
|
|
284
|
+
self.audio_path = tts_audio_path
|
|
285
|
+
|
|
286
|
+
# Update the audio path label
|
|
287
|
+
if self.audio_path_label:
|
|
288
|
+
self.audio_path_label.config(text=tts_audio_path)
|
|
289
|
+
|
|
290
|
+
# Update the audio button command to use the new path
|
|
291
|
+
if self.audio_button:
|
|
292
|
+
self.audio_button.config(command=lambda: self._play_audio(self.audio_path))
|
|
293
|
+
|
|
294
|
+
# Update status label to show success
|
|
295
|
+
if self.tts_status_label:
|
|
296
|
+
self.tts_status_label.config(text="✓ TTS Audio Generated", foreground="green")
|
|
297
|
+
|
|
298
|
+
except requests.exceptions.Timeout:
|
|
299
|
+
error_msg = "TTS request timed out. Please check if your TTS service is running."
|
|
300
|
+
logger.error(error_msg)
|
|
301
|
+
messagebox.showerror("TTS Error", error_msg)
|
|
302
|
+
except requests.exceptions.RequestException as e:
|
|
303
|
+
error_msg = f"Failed to connect to TTS service: {str(e)}"
|
|
304
|
+
logger.error(error_msg)
|
|
305
|
+
messagebox.showerror("TTS Error", f"{error_msg}\n\nPlease check your TTS URL configuration.")
|
|
306
|
+
except Exception as e:
|
|
307
|
+
error_msg = f"Unexpected error generating TTS: {str(e)}"
|
|
308
|
+
logger.error(error_msg)
|
|
309
|
+
messagebox.showerror("TTS Error", error_msg)
|
|
310
|
+
|
|
218
311
|
def _cleanup_audio(self):
|
|
219
312
|
"""Clean up audio stream resources"""
|
|
220
313
|
self.audio_player.cleanup()
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/get_overlay_coords.py
RENAMED
|
@@ -106,10 +106,10 @@ class OverlayThread(threading.Thread):
|
|
|
106
106
|
while True:
|
|
107
107
|
if overlay_server_thread.has_clients():
|
|
108
108
|
if get_config().overlay.periodic:
|
|
109
|
-
await self.overlay_processor.find_box_and_send_to_overlay('')
|
|
109
|
+
await self.overlay_processor.find_box_and_send_to_overlay('', True)
|
|
110
110
|
await asyncio.sleep(get_config().overlay.periodic_interval)
|
|
111
111
|
elif self.first_time_run:
|
|
112
|
-
await self.overlay_processor.find_box_and_send_to_overlay('')
|
|
112
|
+
await self.overlay_processor.find_box_and_send_to_overlay('', False)
|
|
113
113
|
self.first_time_run = False
|
|
114
114
|
else:
|
|
115
115
|
await asyncio.sleep(3)
|
|
@@ -161,7 +161,7 @@ class OverlayProcessor:
|
|
|
161
161
|
self.lens = None
|
|
162
162
|
self.regex = None
|
|
163
163
|
|
|
164
|
-
async def find_box_and_send_to_overlay(self, sentence_to_check: str = None):
|
|
164
|
+
async def find_box_and_send_to_overlay(self, sentence_to_check: str = None, check_against_last: bool = False):
|
|
165
165
|
"""
|
|
166
166
|
Sends the detected text boxes to the overlay via WebSocket.
|
|
167
167
|
Cancels any running OCR task before starting a new one.
|
|
@@ -175,7 +175,7 @@ class OverlayProcessor:
|
|
|
175
175
|
logger.info("Previous OCR task was cancelled")
|
|
176
176
|
|
|
177
177
|
# Start new task
|
|
178
|
-
self.current_task = asyncio.create_task(self.find_box_for_sentence(sentence_to_check))
|
|
178
|
+
self.current_task = asyncio.create_task(self.find_box_for_sentence(sentence_to_check, check_against_last))
|
|
179
179
|
try:
|
|
180
180
|
await self.current_task
|
|
181
181
|
except asyncio.CancelledError:
|
|
@@ -183,7 +183,7 @@ class OverlayProcessor:
|
|
|
183
183
|
# logger.info(f"Sending {len(boxes)} boxes to overlay.")
|
|
184
184
|
# await send_word_coordinates_to_overlay(boxes)
|
|
185
185
|
|
|
186
|
-
async def find_box_for_sentence(self, sentence_to_check: str = None) -> List[Dict[str, Any]]:
|
|
186
|
+
async def find_box_for_sentence(self, sentence_to_check: str = None, check_against_last: bool = False) -> List[Dict[str, Any]]:
|
|
187
187
|
"""
|
|
188
188
|
Public method to perform OCR and find text boxes for a given sentence.
|
|
189
189
|
|
|
@@ -191,7 +191,7 @@ class OverlayProcessor:
|
|
|
191
191
|
error handling.
|
|
192
192
|
"""
|
|
193
193
|
try:
|
|
194
|
-
return await self._do_work(sentence_to_check)
|
|
194
|
+
return await self._do_work(sentence_to_check, check_against_last=check_against_last)
|
|
195
195
|
except Exception as e:
|
|
196
196
|
logger.error(f"Error during OCR processing: {e}", exc_info=True)
|
|
197
197
|
return []
|
|
@@ -304,7 +304,7 @@ class OverlayProcessor:
|
|
|
304
304
|
|
|
305
305
|
return composite_img
|
|
306
306
|
|
|
307
|
-
async def _do_work(self, sentence_to_check: str = None) -> Tuple[List[Dict[str, Any]], int]:
|
|
307
|
+
async def _do_work(self, sentence_to_check: str = None, check_against_last: bool = False) -> Tuple[List[Dict[str, Any]], int]:
|
|
308
308
|
"""The main OCR workflow with cancellation support."""
|
|
309
309
|
if not self.lens:
|
|
310
310
|
logger.error("OCR engines are not initialized. Cannot perform OCR for Overlay.")
|
|
@@ -348,7 +348,7 @@ class OverlayProcessor:
|
|
|
348
348
|
text_str = "".join([text for text in text if self.regex.match(text)])
|
|
349
349
|
|
|
350
350
|
# RapidFuzz fuzzy match 90% to not send the same results repeatedly
|
|
351
|
-
if self.last_oneocr_result:
|
|
351
|
+
if self.last_oneocr_result and check_against_last:
|
|
352
352
|
|
|
353
353
|
score = fuzz.ratio(text_str, self.last_oneocr_result)
|
|
354
354
|
if score >= 80:
|
|
@@ -403,7 +403,7 @@ class OverlayProcessor:
|
|
|
403
403
|
text_str = "".join([text for text in text_list if self.regex.match(text)])
|
|
404
404
|
|
|
405
405
|
# RapidFuzz fuzzy match 90% to not send the same results repeatedly
|
|
406
|
-
if self.last_lens_result:
|
|
406
|
+
if self.last_lens_result and check_against_last:
|
|
407
407
|
score = fuzz.ratio(text_str, self.last_lens_result)
|
|
408
408
|
if score >= 80:
|
|
409
409
|
logger.info("Google Lens results are similar to the last results (score: %d). Skipping overlay update.", score)
|
|
@@ -596,7 +596,7 @@ async def main_run_ocr():
|
|
|
596
596
|
"""
|
|
597
597
|
overlay_processor = OverlayProcessor()
|
|
598
598
|
while True:
|
|
599
|
-
await overlay_processor.find_box_and_send_to_overlay('')
|
|
599
|
+
await overlay_processor.find_box_and_send_to_overlay('', False)
|
|
600
600
|
await asyncio.sleep(10)
|
|
601
601
|
|
|
602
602
|
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/ocr/gsm_ocr_config.py
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/ocr/owocr_area_selector.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/owocr/owocr/__init__.py
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/owocr/owocr/__main__.py
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/owocr/owocr/config.py
RENAMED
|
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.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/tools/ss_selector.py
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/tools/window_transparency.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/ui/screenshot_selector.py
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/audio_player.py
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/communication/send.py
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/configuration.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/downloader/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/downloader/oneocr_dl.py
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/electron_config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/notification.py
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/win10toast/__init__.py
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/util/win10toast/__main__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/gsm_websocket.py
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/css/overview.css
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/css/search.css
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/css/shared.css
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/css/stats.css
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/favicon-96x96.png
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/favicon.ico
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/favicon.svg
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/js/anki_stats.js
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/js/database.js
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/js/goals.js
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/js/kanji-grid.js
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/js/overview.js
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/js/search.js
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/js/shared.js
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/js/stats.js
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/site.webmanifest
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/static/style.css
RENAMED
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/database.html
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/goals.html
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/index.html
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/overview.html
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/search.html
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/stats.html
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/templates/utility.html
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner/web/texthooking_page.py
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner.egg-info/requires.txt
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.8 → gamesentenceminer-2.18.9}/GameSentenceMiner.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|