GameSentenceMiner 2.18.3__tar.gz → 2.18.5__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.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/obs.py +52 -26
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/db.py +107 -41
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/database_api.py +1 -1
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner.egg-info/PKG-INFO +1 -1
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/PKG-INFO +1 -1
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/pyproject.toml +1 -1
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/__init__.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/ai/__init__.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/ai/ai_prompting.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/anki.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/assets/__init__.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/assets/icon.png +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/assets/icon128.png +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/assets/icon256.png +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/assets/icon32.png +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/assets/icon512.png +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/assets/icon64.png +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/assets/pickaxe.png +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/gametext.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/gsm.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/locales/en_us.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/locales/ja_jp.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/locales/zh_cn.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/ocr/__init__.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/ocr/gsm_ocr_config.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/ocr/ocrconfig.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/ocr/owocr_area_selector.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/ocr/owocr_helper.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/ocr/ss_picker.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/owocr/owocr/__init__.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/owocr/owocr/__main__.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/owocr/owocr/config.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/owocr/owocr/lens_betterproto.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/owocr/owocr/ocr.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/owocr/owocr/run.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/owocr/owocr/screen_coordinate_picker.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/tools/__init__.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/tools/audio_offset_selector.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/tools/furigana_filter_preview.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/tools/ss_selector.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/tools/window_transparency.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/ui/__init__.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/ui/anki_confirmation.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/ui/config_gui.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/ui/screenshot_selector.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/__init__.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/communication/__init__.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/communication/send.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/communication/websocket.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/configuration.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/downloader/Untitled_json.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/downloader/__init__.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/downloader/download_tools.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/downloader/oneocr_dl.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/electron_config.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/ffmpeg.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/get_overlay_coords.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/gsm_utils.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/model.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/notification.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/text_log.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/win10toast/__init__.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/win10toast/__main__.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/vad.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/__init__.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/events.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/gsm_websocket.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/service.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/__init__.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/apple-touch-icon.png +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/css/dashboard-shared.css +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/css/kanji-grid.css +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/css/overview.css +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/css/popups-shared.css +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/css/search.css +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/css/shared.css +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/css/stats.css +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/favicon-96x96.png +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/favicon.ico +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/favicon.svg +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/js/anki_stats.js +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/js/database.js +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/js/goals.js +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/js/kanji-grid.js +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/js/overview.js +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/js/search.js +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/js/shared.js +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/js/stats.js +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/site.webmanifest +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/style.css +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/web-app-manifest-192x192.png +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/web-app-manifest-512x512.png +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/stats.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/anki_stats.html +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/basic_kanji_book_bkb_v1_v2.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/duolingo_kanji.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/grade.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/hk_primary_learning.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/hkscs2016.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/hsk_levels.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/humanum_frequency_list.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/jis_levels.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/jlpt_level.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/jpdb_kanji_frequency_list.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/jpdbv2_kanji_frequency_list.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/jun_das_modern_chinese_character_frequency_list.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/kanji_in_context_revised_edition.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/kanji_kentei_level.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/mainland_china_elementary_textbook_characters.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/moe_way_quiz.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/official_kanji.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/remembering_the_kanji.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/standard_form_of_national_characters.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/table_of_general_standard_chinese_characters.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/the_kodansha_kanji_learners_course_klc.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/thousand_character_classic.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/wanikani_levels.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/kanji_grid/words_hk_frequency_list.json +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/navigation.html +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/components/theme-styles.html +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/database.html +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/goals.html +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/index.html +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/overview.html +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/search.html +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/stats.html +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/utility.html +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/texthooking_page.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/wip/__init___.py +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner.egg-info/SOURCES.txt +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner.egg-info/dependency_links.txt +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner.egg-info/entry_points.txt +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner.egg-info/requires.txt +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner.egg-info/top_level.txt +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/LICENSE +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/README.md +0 -0
- {gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/setup.cfg +0 -0
|
@@ -132,11 +132,14 @@ class OBSConnectionManager(threading.Thread):
|
|
|
132
132
|
|
|
133
133
|
def check_replay_buffer_enabled(self):
|
|
134
134
|
if not self.should_check_output:
|
|
135
|
-
return
|
|
136
|
-
|
|
137
|
-
if not
|
|
138
|
-
|
|
139
|
-
|
|
135
|
+
return 300, ""
|
|
136
|
+
buffer_seconds = get_replay_buffer_max_time_seconds()
|
|
137
|
+
if not buffer_seconds:
|
|
138
|
+
replay_output = get_replay_buffer_output()
|
|
139
|
+
if not replay_output:
|
|
140
|
+
return 0, "Replay Buffer output not found in OBS. Please enable Replay Buffer In OBS Settings -> Output -> Replay Buffer. I recommend 300 seconds (5 minutes) or higher."
|
|
141
|
+
return 300, ""
|
|
142
|
+
return buffer_seconds, ""
|
|
140
143
|
|
|
141
144
|
def _manage_replay_buffer_and_utils(self):
|
|
142
145
|
errors = []
|
|
@@ -150,11 +153,13 @@ class OBSConnectionManager(threading.Thread):
|
|
|
150
153
|
errors.append("Automatic Replay Buffer management is disabled in GSM settings.")
|
|
151
154
|
return errors
|
|
152
155
|
|
|
153
|
-
|
|
156
|
+
buffer_seconds, error_message = self.check_replay_buffer_enabled()
|
|
154
157
|
|
|
155
|
-
if not
|
|
158
|
+
if not buffer_seconds:
|
|
156
159
|
errors.append(error_message)
|
|
157
160
|
return errors
|
|
161
|
+
|
|
162
|
+
self.NO_OUTPUT_SHUTDOWN_SECONDS = max(300, buffer_seconds * 1.10) # At least 5 minutes or 10% more than buffer
|
|
158
163
|
|
|
159
164
|
current_status = get_replay_buffer_status()
|
|
160
165
|
|
|
@@ -167,10 +172,10 @@ class OBSConnectionManager(threading.Thread):
|
|
|
167
172
|
self.no_output_timestamp = None
|
|
168
173
|
return errors
|
|
169
174
|
|
|
170
|
-
img = get_screenshot_PIL(compression=
|
|
171
|
-
|
|
175
|
+
img = get_screenshot_PIL(compression=75, img_format='jpg', width=1280, height=720)
|
|
176
|
+
is_empty = self.is_image_empty(img) if img else True
|
|
172
177
|
|
|
173
|
-
if not
|
|
178
|
+
if not is_empty:
|
|
174
179
|
self.no_output_timestamp = None
|
|
175
180
|
if not current_status:
|
|
176
181
|
start_replay_buffer()
|
|
@@ -184,20 +189,18 @@ class OBSConnectionManager(threading.Thread):
|
|
|
184
189
|
self.last_replay_buffer_status = False
|
|
185
190
|
self.no_output_timestamp = None
|
|
186
191
|
|
|
187
|
-
def
|
|
188
|
-
if self.previous_image is None:
|
|
189
|
-
self.previous_image = np.array(img)
|
|
190
|
-
return True
|
|
192
|
+
def is_image_empty(self, img):
|
|
191
193
|
try:
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
194
|
+
extrema = img.getextrema()
|
|
195
|
+
if isinstance(extrema[0], tuple):
|
|
196
|
+
is_empty = all(e[0] == e[1] for e in extrema)
|
|
197
|
+
else:
|
|
198
|
+
is_empty = extrema[0] == extrema[1]
|
|
199
|
+
return is_empty
|
|
195
200
|
except Exception:
|
|
196
|
-
logger.warning("Failed to
|
|
201
|
+
logger.warning("Failed to check image extrema for emptiness.")
|
|
197
202
|
return False
|
|
198
203
|
|
|
199
|
-
return (img1_np.shape == img2_np.shape) and np.array_equal(img1_np, img2_np)
|
|
200
|
-
|
|
201
204
|
def run(self):
|
|
202
205
|
time.sleep(5) # Initial delay to allow OBS to start
|
|
203
206
|
while self.running:
|
|
@@ -566,7 +569,7 @@ def get_replay_buffer_max_time_seconds():
|
|
|
566
569
|
logger.warning(f"get_output_settings for replay_buffer failed: {response.status}")
|
|
567
570
|
return 0
|
|
568
571
|
except Exception as e:
|
|
569
|
-
logger.error(f"Exception while fetching replay buffer settings: {e}")
|
|
572
|
+
# logger.error(f"Exception while fetching replay buffer settings: {e}")
|
|
570
573
|
return 0
|
|
571
574
|
|
|
572
575
|
def enable_replay_buffer():
|
|
@@ -805,7 +808,24 @@ def set_fit_to_screen_for_scene_items(scene_name: str):
|
|
|
805
808
|
except obs.error.OBSSDKError as e:
|
|
806
809
|
logger.error(f"An OBS error occurred: {e}")
|
|
807
810
|
except Exception as e:
|
|
808
|
-
logger.error(f"An unexpected error occurred: {e}")
|
|
811
|
+
logger.error(f"An unexpected error occurred: {e}")
|
|
812
|
+
|
|
813
|
+
def get_current_source_input_settings():
|
|
814
|
+
with connection_pool.get_client() as client:
|
|
815
|
+
client: obs.ReqClient
|
|
816
|
+
current_scene = get_current_scene()
|
|
817
|
+
if not current_scene:
|
|
818
|
+
return None
|
|
819
|
+
scene_items_response = client.get_scene_item_list(name=current_scene)
|
|
820
|
+
items = scene_items_response.scene_items if scene_items_response and scene_items_response.scene_items else []
|
|
821
|
+
if not items:
|
|
822
|
+
return None
|
|
823
|
+
first_item = items[0]
|
|
824
|
+
source_name = first_item.get('sourceName')
|
|
825
|
+
if not source_name:
|
|
826
|
+
return None
|
|
827
|
+
input_settings_response = client.get_input_settings(name=source_name)
|
|
828
|
+
return input_settings_response.input_settings if input_settings_response else None
|
|
809
829
|
|
|
810
830
|
|
|
811
831
|
def main():
|
|
@@ -867,17 +887,23 @@ if __name__ == '__main__':
|
|
|
867
887
|
logging.basicConfig(level=logging.INFO)
|
|
868
888
|
connect_to_obs_sync()
|
|
869
889
|
|
|
870
|
-
|
|
890
|
+
# outputs = get_output_list()
|
|
891
|
+
# print(outputs)
|
|
892
|
+
|
|
893
|
+
# output = get_replay_buffer_output()
|
|
894
|
+
# print(output)
|
|
895
|
+
|
|
896
|
+
# save_replay_buffer()
|
|
871
897
|
# img = get_screenshot_PIL(source_name='Display Capture 2', compression=100, img_format='jpg', width=2560, height=1440)
|
|
872
898
|
# img.show()
|
|
873
|
-
#
|
|
874
|
-
# print(
|
|
899
|
+
# source = get_current_source_input_settings()
|
|
900
|
+
# print(source)
|
|
875
901
|
|
|
876
902
|
# response = enable_replay_buffer()
|
|
877
903
|
# print(response)
|
|
878
904
|
|
|
879
905
|
# response = get_replay_buffer_max_time_seconds()
|
|
880
|
-
#
|
|
906
|
+
# response is dataclass with attributes, print attributes
|
|
881
907
|
# print(response)
|
|
882
908
|
|
|
883
909
|
# response = enable_replay_buffer()
|
|
@@ -93,6 +93,7 @@ class SQLiteDBTable:
|
|
|
93
93
|
_types: List[type] = []
|
|
94
94
|
_pk: str = 'id'
|
|
95
95
|
_auto_increment: bool = True
|
|
96
|
+
_column_order_cache: Optional[List[str]] = None # Cache for actual column order
|
|
96
97
|
|
|
97
98
|
def __init_subclass__(cls, **kwargs):
|
|
98
99
|
super().__init_subclass__(**kwargs)
|
|
@@ -104,6 +105,7 @@ class SQLiteDBTable:
|
|
|
104
105
|
@classmethod
|
|
105
106
|
def set_db(cls, db: SQLiteDB):
|
|
106
107
|
cls._db = db
|
|
108
|
+
cls._column_order_cache = None # Reset cache when database changes
|
|
107
109
|
# Ensure table exists
|
|
108
110
|
if not db.table_exists(cls._table):
|
|
109
111
|
fields_def = ', '.join([f"{field} TEXT" for field in cls._fields])
|
|
@@ -115,6 +117,7 @@ class SQLiteDBTable:
|
|
|
115
117
|
for field in cls._fields:
|
|
116
118
|
if field not in existing_columns:
|
|
117
119
|
db.execute(f"ALTER TABLE {cls._table} ADD COLUMN {field} TEXT", commit=True)
|
|
120
|
+
cls._column_order_cache = None # Reset cache when schema changes
|
|
118
121
|
|
|
119
122
|
@classmethod
|
|
120
123
|
def all(cls: Type[T]) -> List[T]:
|
|
@@ -137,49 +140,80 @@ class SQLiteDBTable:
|
|
|
137
140
|
if not row:
|
|
138
141
|
return None
|
|
139
142
|
obj = cls()
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
143
|
+
|
|
144
|
+
try:
|
|
145
|
+
# Get actual column order from database schema
|
|
146
|
+
actual_columns = cls.get_actual_column_order()
|
|
147
|
+
expected_fields = [cls._pk] + cls._fields
|
|
148
|
+
|
|
149
|
+
# Create a mapping from actual column positions to expected field positions
|
|
150
|
+
column_mapping = {}
|
|
151
|
+
for i, actual_col in enumerate(actual_columns):
|
|
152
|
+
if actual_col in expected_fields:
|
|
153
|
+
expected_index = expected_fields.index(actual_col)
|
|
154
|
+
column_mapping[i] = expected_index
|
|
155
|
+
|
|
156
|
+
# Process each column in the row based on the mapping
|
|
157
|
+
for actual_pos, row_value in enumerate(row):
|
|
158
|
+
if actual_pos not in column_mapping:
|
|
159
|
+
continue # Skip unknown columns
|
|
160
|
+
|
|
161
|
+
expected_pos = column_mapping[actual_pos]
|
|
162
|
+
field = expected_fields[expected_pos]
|
|
163
|
+
field_type = cls._types[expected_pos]
|
|
164
|
+
|
|
165
|
+
cls._set_field_value(obj, field, field_type, row_value, expected_pos == 0 and field == cls._pk)
|
|
166
|
+
|
|
167
|
+
except Exception as e:
|
|
168
|
+
# Fallback to original behavior if schema-based mapping fails
|
|
169
|
+
logger.warning(f"Column mapping failed for {cls._table}, falling back to positional mapping: {e}")
|
|
170
|
+
expected_fields = [cls._pk] + cls._fields
|
|
171
|
+
for i, field in enumerate(expected_fields):
|
|
172
|
+
if i >= len(row):
|
|
173
|
+
break # Safety check
|
|
174
|
+
field_type = cls._types[i]
|
|
175
|
+
cls._set_field_value(obj, field, field_type, row[i], i == 0 and field == cls._pk)
|
|
176
|
+
|
|
177
|
+
return obj
|
|
178
|
+
|
|
179
|
+
@classmethod
|
|
180
|
+
def _set_field_value(cls, obj, field: str, field_type: type, row_value, is_pk: bool = False):
|
|
181
|
+
"""Helper method to set field value with proper type conversion."""
|
|
182
|
+
if is_pk:
|
|
183
|
+
if field_type is int:
|
|
184
|
+
setattr(obj, field, int(row_value) if row_value is not None else None)
|
|
185
|
+
elif field_type is str:
|
|
186
|
+
setattr(obj, field, str(row_value) if row_value is not None else None)
|
|
187
|
+
return
|
|
188
|
+
|
|
189
|
+
if field_type is str:
|
|
190
|
+
if not row_value:
|
|
191
|
+
setattr(obj, field, "")
|
|
192
|
+
elif isinstance(row_value, str) and (row_value.startswith('[') or row_value.startswith('{')):
|
|
176
193
|
try:
|
|
177
|
-
setattr(obj, field, json.loads(
|
|
194
|
+
setattr(obj, field, json.loads(row_value))
|
|
178
195
|
except json.JSONDecodeError:
|
|
179
|
-
setattr(obj, field,
|
|
196
|
+
setattr(obj, field, row_value)
|
|
180
197
|
else:
|
|
181
|
-
setattr(obj, field,
|
|
182
|
-
|
|
198
|
+
setattr(obj, field, str(row_value) if row_value is not None else None)
|
|
199
|
+
elif field_type is list:
|
|
200
|
+
try:
|
|
201
|
+
setattr(obj, field, json.loads(row_value) if row_value else [])
|
|
202
|
+
except json.JSONDecodeError:
|
|
203
|
+
setattr(obj, field, [])
|
|
204
|
+
elif field_type is int:
|
|
205
|
+
setattr(obj, field, int(row_value) if row_value is not None else None)
|
|
206
|
+
elif field_type is float:
|
|
207
|
+
setattr(obj, field, float(row_value) if row_value is not None else None)
|
|
208
|
+
elif field_type is bool:
|
|
209
|
+
setattr(obj, field, bool(row_value) if row_value is not None else None)
|
|
210
|
+
elif field_type is dict:
|
|
211
|
+
try:
|
|
212
|
+
setattr(obj, field, json.loads(row_value) if row_value else {})
|
|
213
|
+
except json.JSONDecodeError:
|
|
214
|
+
setattr(obj, field, {})
|
|
215
|
+
else:
|
|
216
|
+
setattr(obj, field, row_value)
|
|
183
217
|
|
|
184
218
|
def save(self, retry=1):
|
|
185
219
|
try:
|
|
@@ -245,9 +279,9 @@ class SQLiteDBTable:
|
|
|
245
279
|
|
|
246
280
|
def add_column(self, column_name: str, new_column_type: str = "TEXT"):
|
|
247
281
|
try:
|
|
248
|
-
index = self._fields.index(column_name) + 1
|
|
249
282
|
self._db.execute(
|
|
250
283
|
f"ALTER TABLE {self._table} ADD COLUMN {column_name} {new_column_type}", commit=True)
|
|
284
|
+
self.__class__._column_order_cache = None # Reset cache when schema changes
|
|
251
285
|
logger.info(f"Added column {column_name} to {self._table}")
|
|
252
286
|
except sqlite3.OperationalError as e:
|
|
253
287
|
if "duplicate column name" in str(e):
|
|
@@ -286,11 +320,13 @@ class SQLiteDBTable:
|
|
|
286
320
|
def rename_column(cls, old_column: str, new_column: str):
|
|
287
321
|
cls._db.execute(
|
|
288
322
|
f"ALTER TABLE {cls._table} RENAME COLUMN {old_column} TO {new_column}", commit=True)
|
|
323
|
+
cls._column_order_cache = None # Reset cache when schema changes
|
|
289
324
|
|
|
290
325
|
@classmethod
|
|
291
326
|
def drop_column(cls, column_name: str):
|
|
292
327
|
cls._db.execute(
|
|
293
328
|
f"ALTER TABLE {cls._table} DROP COLUMN {column_name}", commit=True)
|
|
329
|
+
cls._column_order_cache = None # Reset cache when schema changes
|
|
294
330
|
|
|
295
331
|
@classmethod
|
|
296
332
|
def get_column_type(cls, column_name: str) -> Optional[str]:
|
|
@@ -315,6 +351,36 @@ class SQLiteDBTable:
|
|
|
315
351
|
f"UPDATE {cls._table} SET {new_column} = CAST({old_column} AS {new_type})", commit=True)
|
|
316
352
|
cls._db.execute(
|
|
317
353
|
f"ALTER TABLE {cls._table} DROP COLUMN {old_column}", commit=True)
|
|
354
|
+
cls._column_order_cache = None # Reset cache when schema changes
|
|
355
|
+
|
|
356
|
+
@classmethod
|
|
357
|
+
def get_actual_column_order(cls) -> List[str]:
|
|
358
|
+
"""Get the actual column order from the database schema."""
|
|
359
|
+
if cls._column_order_cache is not None:
|
|
360
|
+
return cls._column_order_cache
|
|
361
|
+
|
|
362
|
+
# Use direct database access to avoid recursion through from_row()
|
|
363
|
+
with cls._db._lock:
|
|
364
|
+
import sqlite3
|
|
365
|
+
with sqlite3.connect(cls._db.db_path, check_same_thread=False) as conn:
|
|
366
|
+
cursor = conn.cursor()
|
|
367
|
+
cursor.execute(f"PRAGMA table_info({cls._table})")
|
|
368
|
+
columns_info = cursor.fetchall()
|
|
369
|
+
|
|
370
|
+
# Each row is (cid, name, type, notnull, dflt_value, pk)
|
|
371
|
+
# Sort by column id (cid) to get the actual order
|
|
372
|
+
sorted_columns = sorted(columns_info, key=lambda x: x[0])
|
|
373
|
+
column_order = [col[1] for col in sorted_columns]
|
|
374
|
+
|
|
375
|
+
# Cache the result
|
|
376
|
+
cls._column_order_cache = column_order
|
|
377
|
+
return column_order
|
|
378
|
+
|
|
379
|
+
@classmethod
|
|
380
|
+
def get_expected_column_list(cls) -> str:
|
|
381
|
+
"""Get comma-separated list of columns in expected order for explicit SELECT queries."""
|
|
382
|
+
expected_fields = [cls._pk] + cls._fields
|
|
383
|
+
return ', '.join(expected_fields)
|
|
318
384
|
|
|
319
385
|
|
|
320
386
|
class AIModelsTable(SQLiteDBTable):
|
|
@@ -1182,7 +1182,7 @@ def register_database_api_routes(app):
|
|
|
1182
1182
|
})
|
|
1183
1183
|
|
|
1184
1184
|
except Exception as e:
|
|
1185
|
-
logger.error(f"Unexpected error in api_stats: {e}")
|
|
1185
|
+
logger.error(f"Unexpected error in api_stats: {e}", exc_info=True)
|
|
1186
1186
|
return jsonify({'error': 'Failed to generate statistics'}), 500
|
|
1187
1187
|
|
|
1188
1188
|
@app.route('/api/goals-today', methods=['GET'])
|
|
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.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/ocr/gsm_ocr_config.py
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/ocr/owocr_area_selector.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/owocr/owocr/__init__.py
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/owocr/owocr/__main__.py
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/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.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/tools/ss_selector.py
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/tools/window_transparency.py
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/ui/anki_confirmation.py
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/ui/screenshot_selector.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/communication/send.py
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/configuration.py
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/downloader/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/downloader/oneocr_dl.py
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/electron_config.py
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/get_overlay_coords.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/notification.py
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/win10toast/__init__.py
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/util/win10toast/__main__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/gsm_websocket.py
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/css/overview.css
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/css/search.css
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/css/shared.css
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/css/stats.css
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/favicon-96x96.png
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/favicon.ico
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/favicon.svg
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/js/anki_stats.js
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/js/database.js
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/js/goals.js
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/js/kanji-grid.js
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/js/overview.js
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/js/search.js
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/js/shared.js
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/js/stats.js
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/static/site.webmanifest
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/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.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/database.html
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/goals.html
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/index.html
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/overview.html
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/search.html
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/stats.html
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/templates/utility.html
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner/web/texthooking_page.py
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner.egg-info/requires.txt
RENAMED
|
File without changes
|
{gamesentenceminer-2.18.3 → gamesentenceminer-2.18.5}/GameSentenceMiner.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|