GameSentenceMiner 2.14.7__py3-none-any.whl → 2.14.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. GameSentenceMiner/config_gui.py +19 -10
  2. GameSentenceMiner/gsm.py +68 -8
  3. GameSentenceMiner/locales/en_us.json +4 -0
  4. GameSentenceMiner/locales/ja_jp.json +4 -0
  5. GameSentenceMiner/locales/zh_cn.json +4 -0
  6. GameSentenceMiner/obs.py +12 -8
  7. {gamesentenceminer-2.14.7.dist-info → gamesentenceminer-2.14.9.dist-info}/METADATA +1 -2
  8. gamesentenceminer-2.14.9.dist-info/RECORD +24 -0
  9. GameSentenceMiner/ai/__init__.py +0 -0
  10. GameSentenceMiner/ai/ai_prompting.py +0 -473
  11. GameSentenceMiner/ocr/__init__.py +0 -0
  12. GameSentenceMiner/ocr/gsm_ocr_config.py +0 -174
  13. GameSentenceMiner/ocr/ocrconfig.py +0 -129
  14. GameSentenceMiner/ocr/owocr_area_selector.py +0 -629
  15. GameSentenceMiner/ocr/owocr_helper.py +0 -638
  16. GameSentenceMiner/ocr/ss_picker.py +0 -140
  17. GameSentenceMiner/owocr/owocr/__init__.py +0 -1
  18. GameSentenceMiner/owocr/owocr/__main__.py +0 -9
  19. GameSentenceMiner/owocr/owocr/config.py +0 -148
  20. GameSentenceMiner/owocr/owocr/lens_betterproto.py +0 -1238
  21. GameSentenceMiner/owocr/owocr/ocr.py +0 -1691
  22. GameSentenceMiner/owocr/owocr/run.py +0 -1817
  23. GameSentenceMiner/owocr/owocr/screen_coordinate_picker.py +0 -109
  24. GameSentenceMiner/tools/__init__.py +0 -0
  25. GameSentenceMiner/tools/audio_offset_selector.py +0 -215
  26. GameSentenceMiner/tools/ss_selector.py +0 -135
  27. GameSentenceMiner/tools/window_transparency.py +0 -214
  28. GameSentenceMiner/util/__init__.py +0 -0
  29. GameSentenceMiner/util/communication/__init__.py +0 -22
  30. GameSentenceMiner/util/communication/send.py +0 -7
  31. GameSentenceMiner/util/communication/websocket.py +0 -94
  32. GameSentenceMiner/util/configuration.py +0 -1198
  33. GameSentenceMiner/util/db.py +0 -408
  34. GameSentenceMiner/util/downloader/Untitled_json.py +0 -472
  35. GameSentenceMiner/util/downloader/__init__.py +0 -0
  36. GameSentenceMiner/util/downloader/download_tools.py +0 -194
  37. GameSentenceMiner/util/downloader/oneocr_dl.py +0 -250
  38. GameSentenceMiner/util/electron_config.py +0 -259
  39. GameSentenceMiner/util/ffmpeg.py +0 -571
  40. GameSentenceMiner/util/get_overlay_coords.py +0 -366
  41. GameSentenceMiner/util/gsm_utils.py +0 -323
  42. GameSentenceMiner/util/model.py +0 -206
  43. GameSentenceMiner/util/notification.py +0 -147
  44. GameSentenceMiner/util/text_log.py +0 -214
  45. GameSentenceMiner/web/__init__.py +0 -0
  46. GameSentenceMiner/web/service.py +0 -132
  47. GameSentenceMiner/web/static/__init__.py +0 -0
  48. GameSentenceMiner/web/static/apple-touch-icon.png +0 -0
  49. GameSentenceMiner/web/static/favicon-96x96.png +0 -0
  50. GameSentenceMiner/web/static/favicon.ico +0 -0
  51. GameSentenceMiner/web/static/favicon.svg +0 -3
  52. GameSentenceMiner/web/static/site.webmanifest +0 -21
  53. GameSentenceMiner/web/static/style.css +0 -292
  54. GameSentenceMiner/web/static/web-app-manifest-192x192.png +0 -0
  55. GameSentenceMiner/web/static/web-app-manifest-512x512.png +0 -0
  56. GameSentenceMiner/web/templates/__init__.py +0 -0
  57. GameSentenceMiner/web/templates/index.html +0 -50
  58. GameSentenceMiner/web/templates/text_replacements.html +0 -238
  59. GameSentenceMiner/web/templates/utility.html +0 -483
  60. GameSentenceMiner/web/texthooking_page.py +0 -584
  61. GameSentenceMiner/wip/__init___.py +0 -0
  62. gamesentenceminer-2.14.7.dist-info/RECORD +0 -77
  63. {gamesentenceminer-2.14.7.dist-info → gamesentenceminer-2.14.9.dist-info}/WHEEL +0 -0
  64. {gamesentenceminer-2.14.7.dist-info → gamesentenceminer-2.14.9.dist-info}/entry_points.txt +0 -0
  65. {gamesentenceminer-2.14.7.dist-info → gamesentenceminer-2.14.9.dist-info}/licenses/LICENSE +0 -0
  66. {gamesentenceminer-2.14.7.dist-info → gamesentenceminer-2.14.9.dist-info}/top_level.txt +0 -0
@@ -1,483 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta charset="UTF-8">
5
- <title>GSM TextHooker</title>
6
- <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
7
- <style>
8
- body {
9
- background-color: #121212;
10
- color: #e0e0e0;
11
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
12
- margin: 20px;
13
- }
14
-
15
- h2 {
16
- color: #ffffff;
17
- text-align: center;
18
- font-weight: 300;
19
- margin-bottom: 20px;
20
- }
21
-
22
- .textline {
23
- margin: 15px 0;
24
- padding: 15px;
25
- display: flex;
26
- align-items: center;
27
- gap: 15px;
28
- }
29
- .textline:last-child {
30
- border-bottom: none;
31
- }
32
-
33
- .textline > p {
34
- font-size: 24px;
35
- flex: 1;
36
- min-width: 200px;
37
- }
38
-
39
- .textline > em {
40
- color: #aaa;
41
- font-size: 0.9em;
42
- margin-right: 10px;
43
- }
44
-
45
- .textline > button {
46
- background-color: #1a73e8;
47
- color: #ffffff;
48
- border: none;
49
- padding: 8px 15px;
50
- font-size: 14px;
51
- cursor: pointer;
52
- transition: background-color 0.3s;
53
- border-radius: 5px;
54
- user-select: none; /* Make text unselectable */
55
- }
56
-
57
- .textline > button:hover {
58
- background-color: #1669c1;
59
- cursor: pointer;
60
- }
61
-
62
- .textline-buttons {
63
- margin-left: auto; /* Align buttons to the right */
64
- display: flex;
65
- gap: 10px;
66
- }
67
-
68
- @media (max-width: 600px) {
69
- .textline {
70
- flex-direction: column;
71
- align-items: flex-start;
72
- }
73
- .textline-buttons{
74
- margin-top: 10px;
75
- }
76
- .textline > strong{
77
- min-width: auto;
78
- }
79
- }
80
-
81
- .initial-event {
82
- margin: 15px 0;
83
- padding: 15px;
84
- }
85
-
86
- hr.initial-events-separator {
87
- border: 0;
88
- border-top: 2px solid #aaa;
89
- margin: 20px 0;
90
- }
91
-
92
- .multi-line-checkbox {
93
- transform: scale(1.5);
94
- margin-right: 10px;
95
- background-color: #00FFFF !important; /* Cyan/Electric Blue */
96
- border: 4px solid #00FFFF; /* Keep the border the same color */
97
- }
98
-
99
- .multi-line-checkbox:checked {
100
- /* You'll likely need to target the checkmark specifically */
101
- /* Example assuming it's a pseudo-element with a font-based check: */
102
- /* &::before { */
103
- /* color: #FFFF00; /* Bright Yellow */
104
- /* } */
105
- /* If it's a background image, you might need to adjust the background or use a filter. */
106
- }
107
-
108
- </style>
109
- </head>
110
- <body>
111
- <div style="position: fixed; top: 20px; right: 20px; display: flex; gap: 10px;">
112
- <button onclick="window.location.href='/textreplacements'" style="background-color: #1a73e8; color: #ffffff; border: none; padding: 10px 20px; font-size: 12px; cursor: pointer; transition: background-color 0.3s; border-radius: 5px;">
113
- Text Replacements
114
- </button>
115
- <button id="delete-history" style="background-color: #1a73e8; color: #ffffff; border: none; padding: 10px 20px; font-size: 12px; cursor: pointer; transition: background-color 0.3s; border-radius: 5px;">
116
- Clear History
117
- </button>
118
- </div>
119
- <div id="initial-events">
120
-
121
- </div>
122
- <hr class="initial-events-separator" id="initial-events-separator" style="display: none;">
123
- <div id="session-events">
124
-
125
- </div>
126
- <script>
127
- let mainStyle = document.querySelector('head style');
128
- let deleteHistoryButton = document.getElementById('delete-history');
129
- let displayedEventIds = new Set();
130
- let isTabActive = true;
131
- let isFetching = false; // Flag to track if a fetch is in progress
132
- let intervalId = 0;
133
- const fetchInterval = 100; // Define the interval as a constant
134
- const websocketPort = {{ websocket_port }} || 55001;
135
-
136
- // Drag selection variables
137
- let isDragging = false;
138
- let dragStartCheckbox = null;
139
- let newCheckboxState = false;
140
- let hoveredCheckboxes = new Set();
141
- let checkboxes = []; // Will hold all checkbox elements
142
- let checkboxMap = {};
143
- let textLines = []; // Will hold all textline elements
144
- let textLineMap = {};
145
- let checkboxes_being_updated = new Set();
146
-
147
- // Shift click selection variable
148
- let lastChecked = null;
149
-
150
-
151
- async function fetchEvents() {
152
- if (document.hidden || isFetching) {
153
- return;
154
- }
155
- isFetching = true
156
- try {
157
- const res = await fetch('/data');
158
- if (!res.ok) {
159
- throw new Error(`HTTP error! Status: ${res.status}`);
160
- }
161
- const events = await res.json();
162
-
163
- let historyEvents = []
164
- events.forEach(ev => {
165
- if (!displayedEventIds.has(ev.id)) {
166
- if (ev.history) {
167
- historyEvents.push(ev);
168
- document.getElementById('initial-events-separator').style.display = 'block';
169
- } else {
170
- addNewEvent(ev)
171
- }
172
- }
173
- if (!ev.history) {
174
- if (!checkboxes_being_updated.has(ev.id)) {
175
- const checkbox = checkboxMap[ev.id];
176
- if (checkbox) {
177
- checkbox.checked = ev.checked;
178
- }
179
- }
180
- }
181
- });
182
- if (historyEvents.length > 0) {
183
- addEventsToHistory(historyEvents);
184
- }
185
- // checkboxes = Array.from(document.querySelectorAll('#session-events input[type="checkbox"]')); // Update checkboxes array after new events
186
- } catch (error) {
187
- console.error("Error fetching events:", error);
188
- } finally {
189
- isFetching = false;
190
- }
191
- }
192
-
193
- function addEventsToHistory(events) {
194
- const container = document.getElementById('initial-events');
195
- const fragment = document.createDocumentFragment();
196
-
197
- events.forEach(event => {
198
- displayedEventIds.add(event.id);
199
- const div = document.createElement('div');
200
- const shadowRoot = div.attachShadow({ mode: 'open' });
201
-
202
- const wrapper = document.createElement('div');
203
- wrapper.className = 'textline';
204
- wrapper.innerHTML = `<p>${event.text}</p>
205
- <em class="clock-icon">${event.time.replace(' GMT', '')}</em>
206
- `;
207
-
208
- const style = document.createElement('style');
209
- style.textContent = mainStyle.innerHTML;
210
- shadowRoot.appendChild(style);
211
- shadowRoot.appendChild(wrapper);
212
-
213
- fragment.appendChild(div);
214
- });
215
-
216
- container.appendChild(fragment);
217
- window.scrollTo({
218
- top: document.documentElement.scrollHeight,
219
- });
220
- }
221
-
222
-
223
- function addNewEvent(event) {
224
- displayedEventIds.add(event.id);
225
- const container = document.getElementById('session-events');
226
- const div = document.createElement('div');
227
- // div.className = 'textline';
228
-
229
- const shadowRoot = div.attachShadow({ mode: 'open' }); // 'open' allows access from the main DOM
230
-
231
- const wrapper = document.createElement('div');
232
- wrapper.className = 'textline';
233
- wrapper.innerHTML = `
234
- <input type="checkbox"
235
- class="multi-line-checkbox"
236
- id="multi-line-checkbox-${event.id}"
237
- ${event.checked ? 'checked' : ''}
238
- aria-label="Mark item"
239
- data-event-id="${event.id}"
240
- onchange="toggleCheckbox('${event.id}', this.checked)">
241
- <p id="textline-${event.id}" contenteditable="false" ondblclick="this.contentEditable = this.contentEditable === 'true' ? 'false' : 'true'; if (this.contentEditable === 'true') this.focus();">${event.text}</p>
242
- <div class="textline-buttons">
243
- <button onclick="buttonClick('${event.id}', 'Screenshot')" title="Screenshot" style="background-color: #333; color: #fff; border: 1px solid #555; padding: 6px 10px; font-size: 10px; border-radius: 4px; cursor: pointer; transition: background-color 0.3s;">
244
- &#x1F4F7;
245
- </button>
246
- <button onclick="buttonClick('${event.id}', 'Audio')" title="Audio" style="background-color: #333; color: #fff; border: 1px solid #555; padding: 6px 10px; font-size: 10px; border-radius: 4px; cursor: pointer; transition: background-color 0.3s;">
247
- &#x1F50A;
248
- </button>
249
- </div>
250
- `;
251
-
252
- // Apply your component's styles within the shadow DOM
253
- const style = document.createElement('style');
254
- style.textContent = mainStyle.innerHTML;
255
- shadowRoot.appendChild(style);
256
- shadowRoot.appendChild(wrapper);
257
-
258
- let checkbox = shadowRoot.querySelector('.multi-line-checkbox')
259
- checkboxes.push(checkbox);
260
- checkboxMap[event.id] = checkbox; // Store the checkbox in the map for easy access
261
-
262
- let textline = shadowRoot.querySelector('#textline-' + event.id);
263
- textLines.push(textline);
264
- textLineMap[event.id] = textline; // Store the textline in the map for easy access
265
-
266
-
267
- container.appendChild(div);
268
- window.scrollTo({
269
- top: document.documentElement.scrollHeight,
270
- });
271
- }
272
-
273
- function buttonClick(id, action) {
274
- console.log(id);
275
- const endpoint = action === 'Screenshot' ? '/get-screenshot' : '/play-audio';
276
- fetch(endpoint, {
277
- method: 'POST',
278
- headers: { 'Content-Type': 'application/json' },
279
- body: JSON.stringify({ id })
280
- })
281
- .then(response => {
282
- if (!response.ok) {
283
- throw new Error(`HTTP error! Status: ${response.status}`);
284
- }
285
- return response.json();
286
- })
287
- .then(data => {
288
- console.log(`${action} action completed for event ID: ${id}`, data);
289
- })
290
- .catch(error => {
291
- console.error(`Error performing ${action} action for event ID: ${id}`, error);
292
- });
293
- }
294
-
295
- function textDoubleClicked(id) {
296
- const textElement = textLineMap[id];
297
- console.log(textElement);
298
- textElement.contenteditable = textElement.contenteditable === "true" ? "false" : "true";
299
- }
300
-
301
- async function toggleCheckbox(id, checked) {
302
- try {
303
- checkboxes_being_updated.add(id);
304
- const res = await fetch('/update_checkbox', {
305
- method: 'POST',
306
- headers: { 'Content-Type': 'application/json' },
307
- body: JSON.stringify({ id })
308
- });
309
- checkboxes_being_updated.delete(id);
310
- if (!res.ok) {
311
- throw new Error(`HTTP error! Status: ${res.status}`);
312
- }
313
- } catch (error) {
314
- console.error("Error updating checkbox:", error);
315
- }
316
- }
317
-
318
- function handleMouseDown(e) {
319
- if (e.target.type === 'checkbox') {
320
- newCheckboxState = !e.target.checked;
321
- isDragging = true;
322
- dragStartCheckbox = e.target;
323
- hoveredCheckboxes.add(e.target)
324
- }
325
- }
326
-
327
- function handleMouseUp(e) {
328
- if (e.target === dragStartCheckbox) {
329
- isDragging = false;
330
- dragStartCheckbox = null;
331
- return;
332
- }
333
- if (isDragging) {
334
- isDragging = false;
335
-
336
- hoveredCheckboxes.forEach(checkbox => {
337
- checkbox.checked = newCheckboxState; // Set all hovered checkboxes to the new state
338
- const eventId = checkbox.dataset.eventId;
339
- toggleCheckbox(eventId, newCheckboxState);
340
- });
341
- isDragging = false;
342
- dragStartCheckbox = null;
343
- }
344
-
345
- }
346
-
347
- function handleMouseOver(e) {
348
- if (!isDragging || e.target.type !== 'checkbox' || e.target === dragStartCheckbox) {
349
- return;
350
- }
351
- e.preventDefault(); // Prevent text selection during drag
352
- if (dragStartCheckbox) {
353
- hoveredCheckboxes.add(e.target);
354
- }
355
- }
356
-
357
- function handleCheckboxClick(e) {
358
- if (!e.shiftKey) {
359
- lastChecked = e.target;
360
- return;
361
- }
362
-
363
- if (!lastChecked) return;
364
-
365
- let inBetween = false;
366
- checkboxes.forEach(checkbox => {
367
- if (checkbox === e.target || checkbox === lastChecked) {
368
- inBetween = !inBetween;
369
- }
370
-
371
- if (inBetween) {
372
- checkbox.checked = lastChecked.checked;
373
- const eventId = checkbox.dataset.eventId;
374
- toggleCheckbox(eventId, lastChecked.checked);
375
- }
376
- });
377
-
378
- lastChecked = e.target;
379
- }
380
-
381
- function deleteHistory(e) {
382
- e.preventDefault();
383
- if (confirm("Are you sure you want to delete the history? This action cannot be undone.")) {
384
- fetch('/clear_history', {
385
- method: 'POST',
386
- headers: { 'Content-Type': 'application/json' }
387
- })
388
- .then(response => {
389
- if (!response.ok) {
390
- throw new Error(`HTTP error! Status: ${response.status}`);
391
- }
392
- // Clear the displayed events
393
- displayedEventIds.clear();
394
- document.getElementById('initial-events').innerHTML = '';
395
- document.getElementById('session-events').innerHTML = '';
396
- document.getElementById('initial-events-separator').style.display = 'none';
397
- })
398
- .catch(error => {
399
- console.error("Error deleting history:", error);
400
- });
401
- }
402
- }
403
-
404
- document.addEventListener('mousedown', handleMouseDown);
405
- document.addEventListener('mouseup', handleMouseUp);
406
- document.addEventListener('mouseover', handleMouseOver);
407
- document.addEventListener('click', handleCheckboxClick);
408
- deleteHistoryButton.addEventListener('click', deleteHistory);
409
-
410
- const websocketURL = 'ws://localhost:' + websocketPort;
411
- let websocket = {};
412
- let reconnectInterval = 1000; // Time in milliseconds to wait before attempting to reconnect
413
-
414
- const connectWebSocket = () => {
415
- if (websocket && websocket.readyState === WebSocket.OPEN) {
416
- console.log('WebSocket already open, no need to reconnect.');
417
- return;
418
- }
419
- if (websocket && websocket.readyState === WebSocket.CONNECTING) {
420
- console.log('WebSocket is currently connecting, waiting...');
421
- return;
422
- }
423
-
424
- websocket = new WebSocket(websocketURL);
425
-
426
- websocket.onopen = (event) => {
427
- console.log('WebSocket connection opened');
428
- websocket.send(JSON.stringify({ type: 'initial_data_request' }));
429
- };
430
-
431
- websocket.onmessage = (event) => {
432
- const data = JSON.parse(event.data);
433
- console.log('Received message:', data);
434
- if (data.event === 'text_received') {
435
- console.log("Adding new event:", data.data);
436
- addNewEvent(data.data);
437
- } else {
438
- console.log('Other message:', data);
439
- }
440
- };
441
-
442
- websocket.onclose = (event) => {
443
- console.log(`WebSocket connection closed. Attempting to reconnect in ${reconnectInterval / 1000} seconds...`);
444
- // Only attempt to reconnect if the current websocket object is the one that closed
445
- if (websocket === event.target) {
446
- // Clear the current websocket reference to allow for a new connection
447
- websocket = null;
448
- setTimeout(connectWebSocket, reconnectInterval);
449
- }
450
- };
451
-
452
- websocket.onerror = (error) => {
453
- console.error('WebSocket error:', error);
454
- // Optionally attempt to reconnect on error as well, ensuring we don't have an active connection
455
- if (websocket === error.target || websocket === null) {
456
- console.log(`Attempting to reconnect in ${reconnectInterval / 1000} seconds...`);
457
- // Clear the current websocket reference
458
- websocket = null;
459
- setTimeout(connectWebSocket, reconnectInterval);
460
- }
461
- };
462
- return websocket;
463
- };
464
-
465
- // connectWebSocket();
466
-
467
-
468
- fetchEvents();
469
-
470
- console.log("Initial load, fetching events and starting interval...");
471
- fetchEvents();
472
- intervalId = setInterval(async () => {
473
- if (isTabActive) {
474
- await fetchEvents();
475
- }
476
- }, fetchInterval);
477
-
478
- window.scrollTo({
479
- top: document.documentElement.scrollHeight,
480
- });
481
- </script>
482
- </body>
483
- </html>