GameSentenceMiner 2.18.18__tar.gz → 2.18.20__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.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/gametext.py +14 -12
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/obs.py +8 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/configuration.py +2 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/get_overlay_coords.py +3 -1
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/text_log.py +36 -40
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/vad.py +6 -4
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/database_api.py +4 -1
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/js/overview.js +45 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/overview.html +1 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner.egg-info/PKG-INFO +36 -36
- gamesentenceminer-2.18.20/GameSentenceMiner.egg-info/requires.txt +38 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/PKG-INFO +36 -36
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/pyproject.toml +37 -37
- gamesentenceminer-2.18.18/GameSentenceMiner.egg-info/requires.txt +0 -40
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/__init__.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/ai/__init__.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/ai/ai_prompting.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/anki.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/assets/__init__.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/assets/icon.png +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/assets/icon128.png +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/assets/icon256.png +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/assets/icon32.png +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/assets/icon512.png +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/assets/icon64.png +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/assets/pickaxe.png +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/gsm.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/locales/en_us.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/locales/ja_jp.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/locales/zh_cn.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/ocr/__init__.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/ocr/gsm_ocr_config.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/ocr/ocrconfig.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/ocr/owocr_area_selector.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/ocr/owocr_helper.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/ocr/ss_picker.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/owocr/owocr/__init__.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/owocr/owocr/__main__.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/owocr/owocr/config.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/owocr/owocr/lens_betterproto.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/owocr/owocr/ocr.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/owocr/owocr/run.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/owocr/owocr/screen_coordinate_picker.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/tools/__init__.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/tools/audio_offset_selector.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/tools/furigana_filter_preview.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/tools/ss_selector.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/tools/window_transparency.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/ui/__init__.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/ui/anki_confirmation.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/ui/config_gui.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/ui/furigana_filter_preview.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/ui/screenshot_selector.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/__init__.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/audio_player.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/communication/__init__.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/communication/send.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/communication/websocket.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/db.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/downloader/Untitled_json.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/downloader/__init__.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/downloader/download_tools.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/downloader/oneocr_dl.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/electron_config.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/ffmpeg.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/games_table.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/gsm_utils.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/model.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/notification.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/win10toast/__init__.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/win10toast/__main__.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/__init__.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/anki_api_endpoints.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/events.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/gsm_websocket.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/service.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/__init__.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/apple-touch-icon.png +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/css/dashboard-shared.css +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/css/kanji-grid.css +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/css/loading-skeleton.css +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/css/overview.css +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/css/popups-shared.css +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/css/search.css +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/css/shared.css +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/css/stats.css +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/favicon-96x96.png +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/favicon.ico +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/favicon.svg +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/js/anki_stats.js +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/js/database.js +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/js/goals.js +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/js/heatmap.js +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/js/kanji-grid.js +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/js/search.js +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/js/shared.js +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/js/stats.js +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/site.webmanifest +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/style.css +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/web-app-manifest-192x192.png +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/web-app-manifest-512x512.png +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/stats.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/anki_stats.html +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/date-range.html +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/html-head.html +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/js-config.html +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/basic_kanji_book_bkb_v1_v2.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/duolingo_kanji.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/grade.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/hk_primary_learning.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/hkscs2016.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/hsk_levels.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/humanum_frequency_list.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/jis_levels.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/jlpt_level.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/jpdb_kanji_frequency_list.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/jpdbv2_kanji_frequency_list.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/jun_das_modern_chinese_character_frequency_list.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/kanji_in_context_revised_edition.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/kanji_kentei_level.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/mainland_china_elementary_textbook_characters.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/moe_way_quiz.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/official_kanji.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/remembering_the_kanji.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/standard_form_of_national_characters.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/table_of_general_standard_chinese_characters.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/the_kodansha_kanji_learners_course_klc.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/thousand_character_classic.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/wanikani_levels.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/kanji_grid/words_hk_frequency_list.json +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/navigation.html +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/popups.html +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/settings-modal.html +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/components/theme-styles.html +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/database.html +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/goals.html +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/index.html +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/search.html +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/stats.html +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/templates/utility.html +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/texthooking_page.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/wip/__init___.py +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner.egg-info/SOURCES.txt +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner.egg-info/dependency_links.txt +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner.egg-info/entry_points.txt +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner.egg-info/top_level.txt +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/LICENSE +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/README.md +0 -0
- {gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/setup.cfg +0 -0
|
@@ -17,7 +17,7 @@ from GameSentenceMiner.util.gsm_utils import add_srt_line
|
|
|
17
17
|
from GameSentenceMiner.util.text_log import add_line, get_text_log
|
|
18
18
|
from GameSentenceMiner.web.texthooking_page import add_event_to_texthooker, overlay_server_thread
|
|
19
19
|
|
|
20
|
-
from GameSentenceMiner.util.get_overlay_coords import
|
|
20
|
+
from GameSentenceMiner.util.get_overlay_coords import overlay_processor
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
current_line = ''
|
|
@@ -33,7 +33,6 @@ last_clipboard = ''
|
|
|
33
33
|
|
|
34
34
|
reconnecting = False
|
|
35
35
|
websocket_connected = {}
|
|
36
|
-
overlay_processor = None
|
|
37
36
|
|
|
38
37
|
async def monitor_clipboard():
|
|
39
38
|
global current_line, last_clipboard
|
|
@@ -67,6 +66,13 @@ async def listen_websockets():
|
|
|
67
66
|
global current_line, current_line_time, reconnecting, websocket_connected
|
|
68
67
|
try_other = False
|
|
69
68
|
websocket_connected[uri] = False
|
|
69
|
+
websocket_names = {
|
|
70
|
+
"9002": "GSM OCR",
|
|
71
|
+
"9001": "Agent or TextractorSender",
|
|
72
|
+
"6677": "textractor_websocket",
|
|
73
|
+
"2333": "LunaTranslator"
|
|
74
|
+
}
|
|
75
|
+
likely_websocket_name = next((f" ({name})" for port, name in websocket_names.items() if port in uri), "")
|
|
70
76
|
while True:
|
|
71
77
|
if not get_config().general.use_websocket:
|
|
72
78
|
await asyncio.sleep(1)
|
|
@@ -76,10 +82,9 @@ async def listen_websockets():
|
|
|
76
82
|
websocket_url = f'ws://{uri}/api/ws/text/origin'
|
|
77
83
|
try:
|
|
78
84
|
async with websockets.connect(websocket_url, ping_interval=None) as websocket:
|
|
79
|
-
logger.info(f"TextHooker Websocket {uri} Connected!")
|
|
80
85
|
gsm_status.websockets_connected.append(websocket_url)
|
|
81
86
|
if reconnecting:
|
|
82
|
-
logger.info(f"Texthooker WebSocket {uri} connected Successfully!" + " Disabling Clipboard Monitor." if (get_config().general.use_clipboard and not get_config().general.use_both_clipboard_and_websocket) else "")
|
|
87
|
+
logger.info(f"Texthooker WebSocket {uri}{likely_websocket_name} connected Successfully!" + " Disabling Clipboard Monitor." if (get_config().general.use_clipboard and not get_config().general.use_both_clipboard_and_websocket) else "")
|
|
83
88
|
reconnecting = False
|
|
84
89
|
websocket_connected[uri] = True
|
|
85
90
|
line_time = None
|
|
@@ -110,13 +115,13 @@ async def listen_websockets():
|
|
|
110
115
|
if isinstance(e, InvalidStatus):
|
|
111
116
|
e: InvalidStatus
|
|
112
117
|
if e.response.status_code == 404:
|
|
113
|
-
logger.info(f"Texthooker WebSocket: {uri} connection failed. Attempting some fixes...")
|
|
118
|
+
logger.info(f"Texthooker WebSocket: {uri}{likely_websocket_name} connection failed. Attempting some fixes...")
|
|
114
119
|
try_other = True
|
|
115
120
|
elif websocket_connected[uri]:
|
|
116
121
|
if not (isinstance(e, ConnectionResetError) or isinstance(e, ConnectionError) or isinstance(e, InvalidStatus) or isinstance(e, websockets.ConnectionClosed)):
|
|
117
|
-
logger.debug(f"Unexpected error in Texthooker WebSocket {uri} connection: {e}, Can be ignored")
|
|
122
|
+
logger.debug(f"Unexpected error in Texthooker WebSocket {uri}{likely_websocket_name} connection: {e}, Can be ignored")
|
|
118
123
|
else:
|
|
119
|
-
logger.warning(f"Texthooker WebSocket {uri} disconnected. Attempting to reconnect...")
|
|
124
|
+
logger.warning(f"Texthooker WebSocket {uri}{likely_websocket_name} disconnected. Attempting to reconnect...")
|
|
120
125
|
websocket_connected[uri] = False
|
|
121
126
|
await asyncio.sleep(1)
|
|
122
127
|
|
|
@@ -184,8 +189,6 @@ async def handle_new_text_event(current_clipboard, line_time=None):
|
|
|
184
189
|
|
|
185
190
|
|
|
186
191
|
async def add_line_to_text_log(line, line_time=None):
|
|
187
|
-
global overlay_processor
|
|
188
|
-
|
|
189
192
|
if get_config().general.texthook_replacement_regex:
|
|
190
193
|
current_line_after_regex = re.sub(get_config().general.texthook_replacement_regex, '', line)
|
|
191
194
|
else:
|
|
@@ -198,12 +201,11 @@ async def add_line_to_text_log(line, line_time=None):
|
|
|
198
201
|
if len(get_text_log().values) > 0:
|
|
199
202
|
await add_event_to_texthooker(get_text_log()[-1])
|
|
200
203
|
if get_config().overlay.websocket_port and overlay_server_thread.has_clients():
|
|
201
|
-
if not overlay_processor:
|
|
202
|
-
overlay_processor = OverlayProcessor()
|
|
203
204
|
if overlay_processor.ready:
|
|
204
205
|
await overlay_processor.find_box_and_send_to_overlay(current_line_after_regex)
|
|
205
206
|
add_srt_line(line_time, new_line)
|
|
206
|
-
|
|
207
|
+
if 'nostatspls' not in new_line.scene.lower():
|
|
208
|
+
GameLinesTable.add_line(new_line)
|
|
207
209
|
|
|
208
210
|
def reset_line_hotkey_pressed():
|
|
209
211
|
global current_line_time
|
|
@@ -35,6 +35,8 @@ class OBSConnectionPool:
|
|
|
35
35
|
self._locks = [threading.Lock() for _ in range(self.size)]
|
|
36
36
|
self._next_idx = 0
|
|
37
37
|
self._idx_lock = threading.Lock()
|
|
38
|
+
self.connected_once = False
|
|
39
|
+
self.last_error_shown = [None] * self.size
|
|
38
40
|
logger.info(f"Initialized OBSConnectionPool with size {self.size}")
|
|
39
41
|
|
|
40
42
|
def connect_all(self):
|
|
@@ -42,8 +44,12 @@ class OBSConnectionPool:
|
|
|
42
44
|
for i in range(self.size):
|
|
43
45
|
try:
|
|
44
46
|
self._clients[i] = obs.ReqClient(**self.connection_kwargs)
|
|
47
|
+
self.connected_once = True
|
|
45
48
|
except Exception as e:
|
|
49
|
+
if str(e) == self.last_error_shown[i]:
|
|
50
|
+
continue
|
|
46
51
|
logger.error(f"Failed to create client {i} in pool: {e}")
|
|
52
|
+
self.last_error_shown[i] = str(e)
|
|
47
53
|
return True
|
|
48
54
|
|
|
49
55
|
def disconnect_all(self):
|
|
@@ -154,6 +160,8 @@ class OBSConnectionManager(threading.Thread):
|
|
|
154
160
|
return errors
|
|
155
161
|
|
|
156
162
|
buffer_seconds, error_message = self.check_replay_buffer_enabled()
|
|
163
|
+
|
|
164
|
+
gsm_state.replay_buffer_length = buffer_seconds or 300
|
|
157
165
|
|
|
158
166
|
if not buffer_seconds:
|
|
159
167
|
errors.append(error_message)
|
{gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/configuration.py
RENAMED
|
@@ -905,6 +905,7 @@ class Config:
|
|
|
905
905
|
if profile.vad.selected_vad_model == WHISPER and profile.vad.backup_vad_model == SILERO:
|
|
906
906
|
profile.vad.backup_vad_model = OFF
|
|
907
907
|
|
|
908
|
+
self.version = current_version
|
|
908
909
|
self.save()
|
|
909
910
|
|
|
910
911
|
def save(self):
|
|
@@ -1315,6 +1316,7 @@ class GsmAppState:
|
|
|
1315
1316
|
self.current_srt = None
|
|
1316
1317
|
self.srt_index = 1
|
|
1317
1318
|
self.current_audio_stream = None
|
|
1319
|
+
self.replay_buffer_length = 0
|
|
1318
1320
|
|
|
1319
1321
|
|
|
1320
1322
|
@dataclass_json
|
{gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/util/get_overlay_coords.py
RENAMED
|
@@ -568,6 +568,8 @@ class OverlayProcessor:
|
|
|
568
568
|
}
|
|
569
569
|
# logger.info(f"Converted OneOCR results to percentages: {converted_results}")
|
|
570
570
|
return converted_results
|
|
571
|
+
|
|
572
|
+
overlay_processor = OverlayProcessor()
|
|
571
573
|
|
|
572
574
|
async def main_test_screenshot():
|
|
573
575
|
"""
|
|
@@ -596,7 +598,7 @@ async def main_test_screenshot():
|
|
|
596
598
|
|
|
597
599
|
new_img.paste(img, (left, top))
|
|
598
600
|
new_img.show()
|
|
599
|
-
|
|
601
|
+
|
|
600
602
|
async def main_run_ocr():
|
|
601
603
|
"""
|
|
602
604
|
Main function to demonstrate running the full OCR process.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import uuid
|
|
2
2
|
from dataclasses import dataclass
|
|
3
|
-
from datetime import datetime
|
|
3
|
+
from datetime import datetime, timedelta
|
|
4
4
|
from difflib import SequenceMatcher
|
|
5
5
|
from typing import Optional
|
|
6
6
|
|
|
@@ -38,9 +38,6 @@ class GameLine:
|
|
|
38
38
|
def set_TL(self, tl: str):
|
|
39
39
|
self.TL = tl
|
|
40
40
|
|
|
41
|
-
def get_stripped_text(self):
|
|
42
|
-
return self.text.replace('\n', '').strip()
|
|
43
|
-
|
|
44
41
|
def __str__(self):
|
|
45
42
|
return str({"text": self.text, "time": self.time})
|
|
46
43
|
|
|
@@ -119,7 +116,7 @@ def strip_whitespace_and_punctuation(text: str) -> str:
|
|
|
119
116
|
return re.sub(r'[\s 、。「」【】《》., ]', '', text).strip()
|
|
120
117
|
|
|
121
118
|
|
|
122
|
-
#
|
|
119
|
+
# Do not use partial_ratio here, ever
|
|
123
120
|
def lines_match(texthooker_sentence, anki_sentence, similarity_threshold=80) -> bool:
|
|
124
121
|
# Replace newlines, spaces, other whitespace characters, AND japanese punctuation
|
|
125
122
|
texthooker_sentence = strip_whitespace_and_punctuation(texthooker_sentence)
|
|
@@ -133,9 +130,20 @@ def lines_match(texthooker_sentence, anki_sentence, similarity_threshold=80) ->
|
|
|
133
130
|
return (anki_sentence in texthooker_sentence) or (texthooker_sentence in anki_sentence) or (similarity >= similarity_threshold)
|
|
134
131
|
|
|
135
132
|
|
|
136
|
-
def
|
|
137
|
-
|
|
138
|
-
|
|
133
|
+
def get_matching_line(last_note: AnkiCard, lines=None) -> GameLine:
|
|
134
|
+
"""
|
|
135
|
+
Find a matching GameLine for the given AnkiCard.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
last_note: The AnkiCard to match against
|
|
139
|
+
lines: Optional list of GameLines to search in. If None, uses all game log lines.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
GameLine: The matching line or the latest line if no match found
|
|
143
|
+
"""
|
|
144
|
+
if not lines:
|
|
145
|
+
lines = get_all_lines()
|
|
146
|
+
|
|
139
147
|
if not lines:
|
|
140
148
|
raise Exception("No voicelines in GSM. GSM can only do work on text that has been sent to it since it started. If you are not getting any text into GSM, please check your setup/config.")
|
|
141
149
|
|
|
@@ -146,8 +154,12 @@ def get_text_event(last_note) -> GameLine:
|
|
|
146
154
|
if not sentence:
|
|
147
155
|
return lines[-1]
|
|
148
156
|
|
|
149
|
-
|
|
150
|
-
|
|
157
|
+
logger.info(f"Replay buffer length: {gsm_state.replay_buffer_length}")
|
|
158
|
+
time_window = datetime.now() - timedelta(seconds=gsm_state.replay_buffer_length) - timedelta(seconds=5)
|
|
159
|
+
for line in reversed(lines):
|
|
160
|
+
if line.time < time_window:
|
|
161
|
+
logger.info("Could not find matching sentence from GSM's history within the replay buffer time window. Using the latest line.")
|
|
162
|
+
return lines[-1]
|
|
151
163
|
if lines_match(line.text, remove_html_and_cloze_tags(sentence)):
|
|
152
164
|
return line
|
|
153
165
|
|
|
@@ -155,38 +167,20 @@ def get_text_event(last_note) -> GameLine:
|
|
|
155
167
|
return lines[-1]
|
|
156
168
|
|
|
157
169
|
|
|
158
|
-
def
|
|
159
|
-
|
|
160
|
-
|
|
170
|
+
def get_text_event(last_note) -> GameLine:
|
|
171
|
+
"""
|
|
172
|
+
Legacy wrapper for get_matching_line with original behavior.
|
|
173
|
+
Uses raw text comparison for backward compatibility.
|
|
174
|
+
"""
|
|
175
|
+
return get_matching_line(last_note, lines=None)
|
|
161
176
|
|
|
162
|
-
sentence = last_note.get_field(get_config().anki.sentence_field)
|
|
163
|
-
found_lines = []
|
|
164
|
-
if sentence:
|
|
165
|
-
found = False
|
|
166
|
-
for line in game_log.values:
|
|
167
|
-
if found:
|
|
168
|
-
found_lines.append(line)
|
|
169
|
-
if lines_match(line.text, remove_html_and_cloze_tags(sentence)): # 80% similarity threshold
|
|
170
|
-
found = True
|
|
171
|
-
found_lines.append(line)
|
|
172
|
-
return found_lines
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
def get_mined_line(last_note: AnkiCard, lines=None):
|
|
176
|
-
if lines is None:
|
|
177
|
-
lines = []
|
|
178
|
-
if not last_note:
|
|
179
|
-
return lines[-1]
|
|
180
|
-
if not lines:
|
|
181
|
-
lines = get_all_lines()
|
|
182
|
-
if not lines:
|
|
183
|
-
raise Exception("No voicelines in GSM. GSM can only do work on text that has been sent to it since it started. If you are not getting any text into GSM, please check your setup/config.")
|
|
184
177
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
178
|
+
def get_mined_line(last_note: AnkiCard, lines=None) -> GameLine:
|
|
179
|
+
"""
|
|
180
|
+
Legacy wrapper for get_matching_line with original behavior.
|
|
181
|
+
Uses stripped text comparison and accepts custom lines.
|
|
182
|
+
"""
|
|
183
|
+
return get_matching_line(last_note, lines=lines)
|
|
190
184
|
|
|
191
185
|
|
|
192
186
|
def get_time_of_line(line):
|
|
@@ -200,9 +194,11 @@ def get_all_lines():
|
|
|
200
194
|
def get_text_log() -> GameText:
|
|
201
195
|
return game_log
|
|
202
196
|
|
|
197
|
+
|
|
203
198
|
def add_line(current_line_after_regex, line_time):
|
|
204
199
|
return game_log.add_line(current_line_after_regex, line_time)
|
|
205
200
|
|
|
201
|
+
|
|
206
202
|
def get_line_by_id(line_id: str) -> Optional[GameLine]:
|
|
207
203
|
"""
|
|
208
204
|
Retrieve a GameLine by its unique ID.
|
|
@@ -151,7 +151,7 @@ class SileroVADProcessor(VADProcessor):
|
|
|
151
151
|
temp_wav = tempfile.NamedTemporaryFile(dir=configuration.get_temporary_directory(), suffix='.wav').name
|
|
152
152
|
ffmpeg.convert_audio_to_wav(input_audio, temp_wav)
|
|
153
153
|
wav = read_audio(temp_wav)
|
|
154
|
-
speech_timestamps = get_speech_timestamps(wav, self.vad_model, return_seconds=True
|
|
154
|
+
speech_timestamps = get_speech_timestamps(wav, self.vad_model, return_seconds=True)
|
|
155
155
|
logger.debug(speech_timestamps)
|
|
156
156
|
return speech_timestamps
|
|
157
157
|
|
|
@@ -166,9 +166,11 @@ class WhisperVADProcessor(VADProcessor):
|
|
|
166
166
|
import torch
|
|
167
167
|
if not self.vad_model:
|
|
168
168
|
self.device = "cpu" if get_config().vad.use_cpu_for_inference else "cuda" if torch.cuda.is_available() else "cpu"
|
|
169
|
+
compute_type = "float32" if torch.cuda.is_available() else "int8"
|
|
169
170
|
with warnings.catch_warnings():
|
|
170
171
|
warnings.simplefilter("ignore")
|
|
171
|
-
|
|
172
|
+
logger.info(f"Loading Whisper model '{get_config().vad.whisper_model}' on device '{self.device}'...")
|
|
173
|
+
self.vad_model = whisper.load_faster_whisper(get_config().vad.whisper_model, device=self.device, compute_type=compute_type)
|
|
172
174
|
logger.info(f"Whisper model '{get_config().vad.whisper_model}' loaded.")
|
|
173
175
|
return self.vad_model
|
|
174
176
|
|
|
@@ -429,13 +431,13 @@ def test_vad_processors():
|
|
|
429
431
|
out_path = os.path.join(output_dir, out_name.replace("after_splice_", "after_trim_"))
|
|
430
432
|
if os.path.exists(out_path):
|
|
431
433
|
os.remove(out_path)
|
|
432
|
-
result = processor.process_audio(test_audio, out_path, None)
|
|
434
|
+
result = processor.process_audio(test_audio, out_path, None, "")
|
|
433
435
|
print(result)
|
|
434
436
|
|
|
435
437
|
vad_system = VADSystem()
|
|
436
438
|
vad_system.init()
|
|
437
439
|
|
|
438
|
-
result = vad_system.trim_audio_with_vad(test_audio, os.path.join(output_dir, "after_vad.opus"), None)
|
|
440
|
+
result = vad_system.trim_audio_with_vad(test_audio, os.path.join(output_dir, "after_vad.opus"), None, full_text="")
|
|
439
441
|
print(result)
|
|
440
442
|
|
|
441
443
|
|
{gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/database_api.py
RENAMED
|
@@ -227,6 +227,8 @@ def register_database_api_routes(app):
|
|
|
227
227
|
data = request.get_json()
|
|
228
228
|
line_ids = data.get('line_ids', [])
|
|
229
229
|
|
|
230
|
+
logger.debug(f"Request to delete line IDs: {line_ids}")
|
|
231
|
+
|
|
230
232
|
if not line_ids:
|
|
231
233
|
return jsonify({'error': 'No line IDs provided'}), 400
|
|
232
234
|
|
|
@@ -1214,7 +1216,8 @@ def register_database_api_routes(app):
|
|
|
1214
1216
|
all_lines_data.append({
|
|
1215
1217
|
'timestamp': float(line.timestamp),
|
|
1216
1218
|
'game_name': line.game_name or 'Unknown Game',
|
|
1217
|
-
'characters': len(line.line_text) if line.line_text else 0
|
|
1219
|
+
'characters': len(line.line_text) if line.line_text else 0,
|
|
1220
|
+
'id': line.id
|
|
1218
1221
|
})
|
|
1219
1222
|
except Exception as e:
|
|
1220
1223
|
logger.error(f"Error preparing all lines data: {e}")
|
{gamesentenceminer-2.18.18 → gamesentenceminer-2.18.20}/GameSentenceMiner/web/static/js/overview.js
RENAMED
|
@@ -578,6 +578,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|
|
578
578
|
// Session navigation button handlers
|
|
579
579
|
const prevSessionBtn = document.querySelector('.prev-session-btn');
|
|
580
580
|
const nextSessionBtn = document.querySelector('.next-session-btn');
|
|
581
|
+
const deleteSessionBtn = document.querySelector('.delete-session-btn');
|
|
581
582
|
|
|
582
583
|
function updateSessionNavigationButtons() {
|
|
583
584
|
if (!window.todaySessionDetails || window.todaySessionDetails.length === 0) {
|
|
@@ -597,6 +598,32 @@ document.addEventListener('DOMContentLoaded', function () {
|
|
|
597
598
|
updateSessionNavigationButtons();
|
|
598
599
|
}
|
|
599
600
|
|
|
601
|
+
function deleteSession(session) {
|
|
602
|
+
const line_ids = session.lines.map(line => line.id);
|
|
603
|
+
fetch('/api/delete-sentence-lines', {
|
|
604
|
+
method: 'POST',
|
|
605
|
+
headers: {
|
|
606
|
+
'Content-Type': 'application/json'
|
|
607
|
+
},
|
|
608
|
+
body: JSON.stringify({ line_ids })
|
|
609
|
+
})
|
|
610
|
+
.then(response => response.json())
|
|
611
|
+
.then(data => {
|
|
612
|
+
if (data.success) {
|
|
613
|
+
// Remove the session from the list
|
|
614
|
+
window.todaySessionDetails = window.todaySessionDetails.filter(s => s !== session);
|
|
615
|
+
// Update the UI
|
|
616
|
+
updateCurrentSessionOverview(window.todaySessionDetails, window.currentSessionIndex);
|
|
617
|
+
updateSessionNavigationButtons();
|
|
618
|
+
} else {
|
|
619
|
+
console.error('Failed to delete session:', data.error);
|
|
620
|
+
}
|
|
621
|
+
})
|
|
622
|
+
.catch(error => {
|
|
623
|
+
console.error('Error deleting session:', error);
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
|
|
600
627
|
prevSessionBtn.addEventListener('click', () => {
|
|
601
628
|
if (!window.todaySessionDetails) return;
|
|
602
629
|
let idx = window.currentSessionIndex || 0;
|
|
@@ -613,6 +640,24 @@ document.addEventListener('DOMContentLoaded', function () {
|
|
|
613
640
|
}
|
|
614
641
|
});
|
|
615
642
|
|
|
643
|
+
deleteSessionBtn.addEventListener('click', () => {
|
|
644
|
+
if (!window.todaySessionDetails || window.todaySessionDetails.length === 0) return;
|
|
645
|
+
const idx = window.currentSessionIndex || 0;
|
|
646
|
+
const sessionToDelete = window.todaySessionDetails[idx];
|
|
647
|
+
if (!sessionToDelete) return;
|
|
648
|
+
|
|
649
|
+
// Confirm deletion
|
|
650
|
+
const confirm1 = confirm(`Are you sure you want to delete the session starting at ${new Date(sessionToDelete.startTime * 1000).toLocaleString()}? This will delete ${sessionToDelete.lines.length} lines. This action cannot be undone.`);
|
|
651
|
+
if (!confirm1) return;
|
|
652
|
+
const confirm2 = confirm("Are you REALLY sure? This cannot be undone.");
|
|
653
|
+
if (!confirm2) return;
|
|
654
|
+
const confirm3 = confirm("Final warning: Delete this session permanently?");
|
|
655
|
+
if (!confirm3) return;
|
|
656
|
+
|
|
657
|
+
// Call the delete function
|
|
658
|
+
deleteSession(sessionToDelete);
|
|
659
|
+
});
|
|
660
|
+
|
|
616
661
|
// Update navigation buttons whenever sessions are loaded
|
|
617
662
|
document.addEventListener('datesSet', () => {
|
|
618
663
|
setTimeout(updateSessionNavigationButtons, 1200);
|
|
@@ -182,6 +182,7 @@
|
|
|
182
182
|
<div class="session-navigation">
|
|
183
183
|
<button class="prev-session-btn" data-action="prevSession">←</button>
|
|
184
184
|
<button class="next-session-btn" data-action="nextSession">→</button>
|
|
185
|
+
<button class="delete-session-btn" data-action="deleteSession" title="Delete Current Session">🗑️</button>
|
|
185
186
|
</div>
|
|
186
187
|
</div>
|
|
187
188
|
<div class="dashboard-stats-grid" id="currentSessionStats">
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: GameSentenceMiner
|
|
3
|
-
Version: 2.18.
|
|
4
|
-
Summary: A tool for mining sentences from games.
|
|
3
|
+
Version: 2.18.20
|
|
4
|
+
Summary: A tool for mining sentences from games. Update: Dependencies, replay buffer based line searching, and bug fixes.
|
|
5
5
|
Author-email: Beangate <bpwhelan95@gmail.com>
|
|
6
6
|
License: MIT License
|
|
7
7
|
Project-URL: Homepage, https://github.com/bpwhelan/GameSentenceMiner
|
|
@@ -12,42 +12,42 @@ Classifier: Operating System :: OS Independent
|
|
|
12
12
|
Requires-Python: >=3.10
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENSE
|
|
15
|
-
Requires-Dist: requests
|
|
16
|
-
Requires-Dist: watchdog
|
|
17
|
-
Requires-Dist: DateTime
|
|
18
|
-
Requires-Dist: pyperclip
|
|
19
|
-
Requires-Dist: soundfile
|
|
20
|
-
Requires-Dist: toml
|
|
21
|
-
Requires-Dist: psutil
|
|
22
|
-
Requires-Dist: rapidfuzz
|
|
23
|
-
Requires-Dist: plyer
|
|
24
|
-
Requires-Dist: keyboard
|
|
25
|
-
Requires-Dist: websockets
|
|
26
|
-
Requires-Dist:
|
|
27
|
-
Requires-Dist:
|
|
28
|
-
Requires-Dist: stable-ts-whisperless
|
|
29
|
-
Requires-Dist: silero-vad~=5.1.2
|
|
30
|
-
Requires-Dist: ttkbootstrap~=1.10.1
|
|
31
|
-
Requires-Dist: dataclasses_json~=0.6.7
|
|
32
|
-
Requires-Dist: win10toast; sys_platform == "win32"
|
|
33
|
-
Requires-Dist: pystray
|
|
34
|
-
Requires-Dist: pywin32; sys_platform == "win32"
|
|
35
|
-
Requires-Dist: pygetwindow; sys_platform == "win32"
|
|
36
|
-
Requires-Dist: flask
|
|
37
|
-
Requires-Dist: groq
|
|
38
|
-
Requires-Dist: matplotlib
|
|
39
|
-
Requires-Dist: sounddevice
|
|
40
|
-
Requires-Dist: google-genai
|
|
41
|
-
Requires-Dist: owocr
|
|
42
|
-
Requires-Dist: oneocr
|
|
43
|
-
Requires-Dist: openai
|
|
44
|
-
Requires-Dist: scikit-image
|
|
45
|
-
Requires-Dist: opencv-python
|
|
15
|
+
Requires-Dist: requests>=2.32.3
|
|
16
|
+
Requires-Dist: watchdog>=5.0.2
|
|
17
|
+
Requires-Dist: DateTime>=5.5
|
|
18
|
+
Requires-Dist: pyperclip>=1.9.0
|
|
19
|
+
Requires-Dist: soundfile>=0.12.1
|
|
20
|
+
Requires-Dist: toml>=0.10.2
|
|
21
|
+
Requires-Dist: psutil>=7.1.0
|
|
22
|
+
Requires-Dist: rapidfuzz>=3.9.7
|
|
23
|
+
Requires-Dist: plyer>=2.1.0
|
|
24
|
+
Requires-Dist: keyboard>=0.13.5
|
|
25
|
+
Requires-Dist: websockets>=15.0.1
|
|
26
|
+
Requires-Dist: ttkbootstrap>=1.10.1
|
|
27
|
+
Requires-Dist: dataclasses_json>=0.6.7
|
|
46
28
|
Requires-Dist: betterproto==2.0.0b7
|
|
47
|
-
Requires-Dist: obsws-python
|
|
29
|
+
Requires-Dist: obsws-python>=1.7.2
|
|
48
30
|
Requires-Dist: numpy==2.2.6
|
|
49
|
-
Requires-Dist:
|
|
50
|
-
Requires-Dist:
|
|
31
|
+
Requires-Dist: faster-whisper>=1.2.0
|
|
32
|
+
Requires-Dist: silero-vad>=6.0.0
|
|
33
|
+
Requires-Dist: regex>=2025.9.18
|
|
34
|
+
Requires-Dist: opencv-python>=4.12.0.88
|
|
35
|
+
Requires-Dist: scikit-image>=0.25.2
|
|
36
|
+
Requires-Dist: openai>=1.108.0
|
|
37
|
+
Requires-Dist: owocr>=1.9.1
|
|
38
|
+
Requires-Dist: oneocr>=1.0.10
|
|
39
|
+
Requires-Dist: google-genai>=1.38.0
|
|
40
|
+
Requires-Dist: sounddevice>=0.5.2
|
|
41
|
+
Requires-Dist: matplotlib>=3.10.6
|
|
42
|
+
Requires-Dist: groq>=0.31.1
|
|
43
|
+
Requires-Dist: flask>=3.1.2
|
|
44
|
+
Requires-Dist: pystray>=0.19.5
|
|
45
|
+
Requires-Dist: pygetwindow>=0.0.9; sys_platform == "win32"
|
|
46
|
+
Requires-Dist: pywin32>=311; sys_platform == "win32"
|
|
47
|
+
Requires-Dist: win10toast>=0.9; sys_platform == "win32"
|
|
48
|
+
Requires-Dist: stable-ts>=2.19.1
|
|
49
|
+
Requires-Dist: torchcodec>=0.7.0
|
|
50
|
+
Requires-Dist: torchaudio>=2.8.0
|
|
51
51
|
Dynamic: license-file
|
|
52
52
|
|
|
53
53
|
# GSM - An Immersion toolkit for Games.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
requests>=2.32.3
|
|
2
|
+
watchdog>=5.0.2
|
|
3
|
+
DateTime>=5.5
|
|
4
|
+
pyperclip>=1.9.0
|
|
5
|
+
soundfile>=0.12.1
|
|
6
|
+
toml>=0.10.2
|
|
7
|
+
psutil>=7.1.0
|
|
8
|
+
rapidfuzz>=3.9.7
|
|
9
|
+
plyer>=2.1.0
|
|
10
|
+
keyboard>=0.13.5
|
|
11
|
+
websockets>=15.0.1
|
|
12
|
+
ttkbootstrap>=1.10.1
|
|
13
|
+
dataclasses_json>=0.6.7
|
|
14
|
+
betterproto==2.0.0b7
|
|
15
|
+
obsws-python>=1.7.2
|
|
16
|
+
numpy==2.2.6
|
|
17
|
+
faster-whisper>=1.2.0
|
|
18
|
+
silero-vad>=6.0.0
|
|
19
|
+
regex>=2025.9.18
|
|
20
|
+
opencv-python>=4.12.0.88
|
|
21
|
+
scikit-image>=0.25.2
|
|
22
|
+
openai>=1.108.0
|
|
23
|
+
owocr>=1.9.1
|
|
24
|
+
oneocr>=1.0.10
|
|
25
|
+
google-genai>=1.38.0
|
|
26
|
+
sounddevice>=0.5.2
|
|
27
|
+
matplotlib>=3.10.6
|
|
28
|
+
groq>=0.31.1
|
|
29
|
+
flask>=3.1.2
|
|
30
|
+
pystray>=0.19.5
|
|
31
|
+
stable-ts>=2.19.1
|
|
32
|
+
torchcodec>=0.7.0
|
|
33
|
+
torchaudio>=2.8.0
|
|
34
|
+
|
|
35
|
+
[:sys_platform == "win32"]
|
|
36
|
+
pygetwindow>=0.0.9
|
|
37
|
+
pywin32>=311
|
|
38
|
+
win10toast>=0.9
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: GameSentenceMiner
|
|
3
|
-
Version: 2.18.
|
|
4
|
-
Summary: A tool for mining sentences from games.
|
|
3
|
+
Version: 2.18.20
|
|
4
|
+
Summary: A tool for mining sentences from games. Update: Dependencies, replay buffer based line searching, and bug fixes.
|
|
5
5
|
Author-email: Beangate <bpwhelan95@gmail.com>
|
|
6
6
|
License: MIT License
|
|
7
7
|
Project-URL: Homepage, https://github.com/bpwhelan/GameSentenceMiner
|
|
@@ -12,42 +12,42 @@ Classifier: Operating System :: OS Independent
|
|
|
12
12
|
Requires-Python: >=3.10
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENSE
|
|
15
|
-
Requires-Dist: requests
|
|
16
|
-
Requires-Dist: watchdog
|
|
17
|
-
Requires-Dist: DateTime
|
|
18
|
-
Requires-Dist: pyperclip
|
|
19
|
-
Requires-Dist: soundfile
|
|
20
|
-
Requires-Dist: toml
|
|
21
|
-
Requires-Dist: psutil
|
|
22
|
-
Requires-Dist: rapidfuzz
|
|
23
|
-
Requires-Dist: plyer
|
|
24
|
-
Requires-Dist: keyboard
|
|
25
|
-
Requires-Dist: websockets
|
|
26
|
-
Requires-Dist:
|
|
27
|
-
Requires-Dist:
|
|
28
|
-
Requires-Dist: stable-ts-whisperless
|
|
29
|
-
Requires-Dist: silero-vad~=5.1.2
|
|
30
|
-
Requires-Dist: ttkbootstrap~=1.10.1
|
|
31
|
-
Requires-Dist: dataclasses_json~=0.6.7
|
|
32
|
-
Requires-Dist: win10toast; sys_platform == "win32"
|
|
33
|
-
Requires-Dist: pystray
|
|
34
|
-
Requires-Dist: pywin32; sys_platform == "win32"
|
|
35
|
-
Requires-Dist: pygetwindow; sys_platform == "win32"
|
|
36
|
-
Requires-Dist: flask
|
|
37
|
-
Requires-Dist: groq
|
|
38
|
-
Requires-Dist: matplotlib
|
|
39
|
-
Requires-Dist: sounddevice
|
|
40
|
-
Requires-Dist: google-genai
|
|
41
|
-
Requires-Dist: owocr
|
|
42
|
-
Requires-Dist: oneocr
|
|
43
|
-
Requires-Dist: openai
|
|
44
|
-
Requires-Dist: scikit-image
|
|
45
|
-
Requires-Dist: opencv-python
|
|
15
|
+
Requires-Dist: requests>=2.32.3
|
|
16
|
+
Requires-Dist: watchdog>=5.0.2
|
|
17
|
+
Requires-Dist: DateTime>=5.5
|
|
18
|
+
Requires-Dist: pyperclip>=1.9.0
|
|
19
|
+
Requires-Dist: soundfile>=0.12.1
|
|
20
|
+
Requires-Dist: toml>=0.10.2
|
|
21
|
+
Requires-Dist: psutil>=7.1.0
|
|
22
|
+
Requires-Dist: rapidfuzz>=3.9.7
|
|
23
|
+
Requires-Dist: plyer>=2.1.0
|
|
24
|
+
Requires-Dist: keyboard>=0.13.5
|
|
25
|
+
Requires-Dist: websockets>=15.0.1
|
|
26
|
+
Requires-Dist: ttkbootstrap>=1.10.1
|
|
27
|
+
Requires-Dist: dataclasses_json>=0.6.7
|
|
46
28
|
Requires-Dist: betterproto==2.0.0b7
|
|
47
|
-
Requires-Dist: obsws-python
|
|
29
|
+
Requires-Dist: obsws-python>=1.7.2
|
|
48
30
|
Requires-Dist: numpy==2.2.6
|
|
49
|
-
Requires-Dist:
|
|
50
|
-
Requires-Dist:
|
|
31
|
+
Requires-Dist: faster-whisper>=1.2.0
|
|
32
|
+
Requires-Dist: silero-vad>=6.0.0
|
|
33
|
+
Requires-Dist: regex>=2025.9.18
|
|
34
|
+
Requires-Dist: opencv-python>=4.12.0.88
|
|
35
|
+
Requires-Dist: scikit-image>=0.25.2
|
|
36
|
+
Requires-Dist: openai>=1.108.0
|
|
37
|
+
Requires-Dist: owocr>=1.9.1
|
|
38
|
+
Requires-Dist: oneocr>=1.0.10
|
|
39
|
+
Requires-Dist: google-genai>=1.38.0
|
|
40
|
+
Requires-Dist: sounddevice>=0.5.2
|
|
41
|
+
Requires-Dist: matplotlib>=3.10.6
|
|
42
|
+
Requires-Dist: groq>=0.31.1
|
|
43
|
+
Requires-Dist: flask>=3.1.2
|
|
44
|
+
Requires-Dist: pystray>=0.19.5
|
|
45
|
+
Requires-Dist: pygetwindow>=0.0.9; sys_platform == "win32"
|
|
46
|
+
Requires-Dist: pywin32>=311; sys_platform == "win32"
|
|
47
|
+
Requires-Dist: win10toast>=0.9; sys_platform == "win32"
|
|
48
|
+
Requires-Dist: stable-ts>=2.19.1
|
|
49
|
+
Requires-Dist: torchcodec>=0.7.0
|
|
50
|
+
Requires-Dist: torchaudio>=2.8.0
|
|
51
51
|
Dynamic: license-file
|
|
52
52
|
|
|
53
53
|
# GSM - An Immersion toolkit for Games.
|