GameSentenceMiner 2.18.6__py3-none-any.whl → 2.18.7__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.
- GameSentenceMiner/anki.py +21 -18
- GameSentenceMiner/locales/en_us.json +3 -3
- GameSentenceMiner/locales/ja_jp.json +4 -4
- GameSentenceMiner/locales/zh_cn.json +3 -3
- GameSentenceMiner/ui/anki_confirmation.py +72 -17
- GameSentenceMiner/ui/config_gui.py +16 -13
- GameSentenceMiner/util/audio_player.py +220 -0
- GameSentenceMiner/util/configuration.py +22 -3
- GameSentenceMiner/util/get_overlay_coords.py +93 -36
- GameSentenceMiner/vad.py +18 -12
- GameSentenceMiner/web/service.py +68 -17
- GameSentenceMiner/web/static/js/overview.js +253 -33
- GameSentenceMiner/web/templates/overview.html +38 -0
- GameSentenceMiner/web/texthooking_page.py +17 -2
- {gamesentenceminer-2.18.6.dist-info → gamesentenceminer-2.18.7.dist-info}/METADATA +1 -1
- {gamesentenceminer-2.18.6.dist-info → gamesentenceminer-2.18.7.dist-info}/RECORD +20 -19
- {gamesentenceminer-2.18.6.dist-info → gamesentenceminer-2.18.7.dist-info}/WHEEL +0 -0
- {gamesentenceminer-2.18.6.dist-info → gamesentenceminer-2.18.7.dist-info}/entry_points.txt +0 -0
- {gamesentenceminer-2.18.6.dist-info → gamesentenceminer-2.18.7.dist-info}/licenses/LICENSE +0 -0
- {gamesentenceminer-2.18.6.dist-info → gamesentenceminer-2.18.7.dist-info}/top_level.txt +0 -0
|
@@ -773,6 +773,49 @@ document.addEventListener('DOMContentLoaded', function () {
|
|
|
773
773
|
fromDateInput.addEventListener("change", handleDateChange);
|
|
774
774
|
toDateInput.addEventListener("change", handleDateChange);
|
|
775
775
|
|
|
776
|
+
// Session navigation button handlers
|
|
777
|
+
const prevSessionBtn = document.querySelector('.prev-session-btn');
|
|
778
|
+
const nextSessionBtn = document.querySelector('.next-session-btn');
|
|
779
|
+
|
|
780
|
+
function updateSessionNavigationButtons() {
|
|
781
|
+
if (!window.todaySessionDetails || window.todaySessionDetails.length === 0) {
|
|
782
|
+
prevSessionBtn.disabled = true;
|
|
783
|
+
nextSessionBtn.disabled = true;
|
|
784
|
+
return;
|
|
785
|
+
}
|
|
786
|
+
prevSessionBtn.disabled = window.currentSessionIndex <= 0;
|
|
787
|
+
nextSessionBtn.disabled = window.currentSessionIndex >= window.todaySessionDetails.length - 1;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
function showSessionAtIndex(index) {
|
|
791
|
+
if (!window.todaySessionDetails || window.todaySessionDetails.length === 0) return;
|
|
792
|
+
if (index < 0 || index >= window.todaySessionDetails.length) return;
|
|
793
|
+
window.currentSessionIndex = index;
|
|
794
|
+
updateCurrentSessionOverview(window.todaySessionDetails, index);
|
|
795
|
+
updateSessionNavigationButtons();
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
prevSessionBtn.addEventListener('click', () => {
|
|
799
|
+
if (!window.todaySessionDetails) return;
|
|
800
|
+
let idx = window.currentSessionIndex || 0;
|
|
801
|
+
if (idx > 0) {
|
|
802
|
+
showSessionAtIndex(idx - 1);
|
|
803
|
+
}
|
|
804
|
+
});
|
|
805
|
+
|
|
806
|
+
nextSessionBtn.addEventListener('click', () => {
|
|
807
|
+
if (!window.todaySessionDetails) return;
|
|
808
|
+
let idx = window.currentSessionIndex || 0;
|
|
809
|
+
if (idx < window.todaySessionDetails.length - 1) {
|
|
810
|
+
showSessionAtIndex(idx + 1);
|
|
811
|
+
}
|
|
812
|
+
});
|
|
813
|
+
|
|
814
|
+
// Update navigation buttons whenever sessions are loaded
|
|
815
|
+
document.addEventListener('datesSet', () => {
|
|
816
|
+
setTimeout(updateSessionNavigationButtons, 1200);
|
|
817
|
+
});
|
|
818
|
+
|
|
776
819
|
initializeDates();
|
|
777
820
|
|
|
778
821
|
// Popup close button
|
|
@@ -821,6 +864,61 @@ document.addEventListener('DOMContentLoaded', function () {
|
|
|
821
864
|
window.loadStatsData = loadStatsData;
|
|
822
865
|
window.loadGoalProgress = loadGoalProgress;
|
|
823
866
|
|
|
867
|
+
function updateCurrentSessionOverview(sessionDetails, index = sessionDetails.length - 1) {
|
|
868
|
+
window.currentSessionIndex = index; // Store globally for potential future use
|
|
869
|
+
console.log('Updating current session overview:', sessionDetails);
|
|
870
|
+
// Get the session at index
|
|
871
|
+
const lastSession = sessionDetails && sessionDetails.length > 0 ? sessionDetails[index] : null;
|
|
872
|
+
|
|
873
|
+
if (!lastSession) {
|
|
874
|
+
// No current session
|
|
875
|
+
document.getElementById('currentSessionStatus').textContent = 'No active session';
|
|
876
|
+
document.getElementById('currentSessionTotalHours').textContent = '-';
|
|
877
|
+
document.getElementById('currentSessionTotalChars').textContent = '-';
|
|
878
|
+
document.getElementById('currentSessionStartTime').textContent = '-';
|
|
879
|
+
document.getElementById('currentSessionEndTime').textContent = '-';
|
|
880
|
+
document.getElementById('currentSessionCharsPerHour').textContent = '-';
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
// Update session status (show game name if available)
|
|
885
|
+
const statusText = lastSession.gameName ? `Playing: ${lastSession.gameName}` : 'Active session';
|
|
886
|
+
document.getElementById('currentSessionStatus').textContent = statusText;
|
|
887
|
+
|
|
888
|
+
// Format session duration
|
|
889
|
+
let hoursDisplay = '-';
|
|
890
|
+
const sessionHours = lastSession.totalSeconds / 3600;
|
|
891
|
+
if (sessionHours > 0) {
|
|
892
|
+
const h = Math.floor(sessionHours);
|
|
893
|
+
const m = Math.round((sessionHours - h) * 60);
|
|
894
|
+
hoursDisplay = h > 0 ? `${h}h${m > 0 ? ' ' + m + 'm' : ''}` : `${m}m`;
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
// Format start time
|
|
898
|
+
const startTimeDisplay = new Date(lastSession.startTime * 1000).toLocaleTimeString('en-US', {
|
|
899
|
+
hour: '2-digit',
|
|
900
|
+
minute: '2-digit',
|
|
901
|
+
hour12: false
|
|
902
|
+
});
|
|
903
|
+
|
|
904
|
+
const endTimeDisplay = new Date(lastSession.endTime * 1000).toLocaleTimeString('en-US', {
|
|
905
|
+
hour: '2-digit',
|
|
906
|
+
minute: '2-digit',
|
|
907
|
+
hour12: false
|
|
908
|
+
});
|
|
909
|
+
|
|
910
|
+
// Update the DOM elements
|
|
911
|
+
document.getElementById('currentSessionTotalHours').textContent = hoursDisplay;
|
|
912
|
+
document.getElementById('currentSessionTotalChars').textContent = lastSession.totalChars.toLocaleString();
|
|
913
|
+
document.getElementById('currentSessionStartTime').textContent = startTimeDisplay;
|
|
914
|
+
if (index === sessionDetails.length - 1) {
|
|
915
|
+
document.getElementById('currentSessionEndTime').textContent = 'Now';
|
|
916
|
+
} else {
|
|
917
|
+
document.getElementById('currentSessionEndTime').textContent = endTimeDisplay;
|
|
918
|
+
}
|
|
919
|
+
document.getElementById('currentSessionCharsPerHour').textContent = lastSession.readSpeed !== '-' ? lastSession.readSpeed.toLocaleString() : '-';
|
|
920
|
+
}
|
|
921
|
+
|
|
824
922
|
// Dashboard functionality
|
|
825
923
|
function loadDashboardData(data = null, end_timestamp = null) {
|
|
826
924
|
function updateTodayOverview(allLinesData) {
|
|
@@ -849,27 +947,84 @@ document.addEventListener('DOMContentLoaded', function () {
|
|
|
849
947
|
// Calculate sessions (count gaps > session threshold as new sessions)
|
|
850
948
|
let sessions = 0;
|
|
851
949
|
let sessionGap = window.statsConfig ? window.statsConfig.sessionGapSeconds : 3600;
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
950
|
+
let minimumSessionLength = 300; // 5 minutes minimum session length
|
|
951
|
+
let sessionDetails = [];
|
|
952
|
+
if (todayLines.length > 0) {
|
|
953
|
+
// Sort lines by timestamp
|
|
954
|
+
const sortedLines = todayLines.slice().sort((a, b) => parseFloat(a.timestamp) - parseFloat(b.timestamp));
|
|
955
|
+
let currentSession = null;
|
|
956
|
+
let lastTimestamp = null;
|
|
957
|
+
let lastGameName = null;
|
|
958
|
+
|
|
959
|
+
for (let i = 0; i < sortedLines.length; i++) {
|
|
960
|
+
const line = sortedLines[i];
|
|
961
|
+
const ts = parseFloat(line.timestamp);
|
|
962
|
+
const gameName = line.game_name || '';
|
|
963
|
+
const chars = Number(line.characters) || 0;
|
|
964
|
+
|
|
965
|
+
// Determine if new session: gap or new game
|
|
966
|
+
const isNewSession =
|
|
967
|
+
(lastTimestamp !== null && ts - lastTimestamp > sessionGap) ||
|
|
968
|
+
(lastGameName !== null && gameName !== lastGameName);
|
|
969
|
+
|
|
970
|
+
if (!currentSession || isNewSession) {
|
|
971
|
+
// Finish previous session
|
|
972
|
+
if (currentSession) {
|
|
973
|
+
// Calculate read speed for session
|
|
974
|
+
if (currentSession.totalSeconds > 0) {
|
|
975
|
+
currentSession.readSpeed = Math.round(currentSession.totalChars / (currentSession.totalSeconds / 3600));
|
|
976
|
+
} else {
|
|
977
|
+
currentSession.readSpeed = '-';
|
|
978
|
+
}
|
|
979
|
+
// Only add session if it meets minimum length requirement
|
|
980
|
+
if (currentSession.totalSeconds >= minimumSessionLength) {
|
|
981
|
+
sessionDetails.push(currentSession);
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
// Start new session
|
|
985
|
+
currentSession = {
|
|
986
|
+
startTime: ts,
|
|
987
|
+
endTime: ts,
|
|
988
|
+
gameName: gameName,
|
|
989
|
+
totalChars: chars,
|
|
990
|
+
totalSeconds: 0,
|
|
991
|
+
lines: [line]
|
|
992
|
+
};
|
|
993
|
+
} else {
|
|
994
|
+
// Continue current session
|
|
995
|
+
currentSession.endTime = ts;
|
|
996
|
+
currentSession.totalChars += chars;
|
|
997
|
+
currentSession.lines.push(line);
|
|
998
|
+
if (lastTimestamp !== null) {
|
|
999
|
+
let afkTimerSeconds = window.statsConfig ? window.statsConfig.afkTimerSeconds : 120;
|
|
1000
|
+
currentSession.totalSeconds += Math.min(ts - lastTimestamp, afkTimerSeconds);
|
|
866
1001
|
}
|
|
867
1002
|
}
|
|
868
|
-
|
|
869
|
-
|
|
1003
|
+
|
|
1004
|
+
lastTimestamp = ts;
|
|
1005
|
+
lastGameName = gameName;
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
// Push last session
|
|
1009
|
+
if (currentSession) {
|
|
1010
|
+
if (currentSession.totalSeconds > 0) {
|
|
1011
|
+
currentSession.readSpeed = Math.round(currentSession.totalChars / (currentSession.totalSeconds / 3600));
|
|
1012
|
+
} else {
|
|
1013
|
+
currentSession.readSpeed = '-';
|
|
1014
|
+
}
|
|
1015
|
+
sessionDetails.push(currentSession);
|
|
870
1016
|
}
|
|
1017
|
+
|
|
1018
|
+
sessions = sessionDetails.length;
|
|
1019
|
+
} else {
|
|
1020
|
+
sessions = 0;
|
|
1021
|
+
sessionDetails = [];
|
|
871
1022
|
}
|
|
872
1023
|
|
|
1024
|
+
// Optionally, you can expose sessionDetails for debugging or further UI use:
|
|
1025
|
+
console.log(sessionDetails);
|
|
1026
|
+
window.todaySessionDetails = sessionDetails;
|
|
1027
|
+
|
|
873
1028
|
// Calculate total reading time (reuse AFK logic from calculateHeatmapStreaks)
|
|
874
1029
|
let totalSeconds = 0;
|
|
875
1030
|
const timestamps = todayLines
|
|
@@ -908,6 +1063,9 @@ document.addEventListener('DOMContentLoaded', function () {
|
|
|
908
1063
|
document.getElementById('todayTotalChars').textContent = totalChars.toLocaleString();
|
|
909
1064
|
document.getElementById('todaySessions').textContent = sessions;
|
|
910
1065
|
document.getElementById('todayCharsPerHour').textContent = charsPerHour;
|
|
1066
|
+
|
|
1067
|
+
// Update current session overview with the last session
|
|
1068
|
+
showSessionAtIndex(sessionDetails.length - 1);
|
|
911
1069
|
}
|
|
912
1070
|
|
|
913
1071
|
function updateOverviewForEndDay(allLinesData, endTimestamp) {
|
|
@@ -936,29 +1094,89 @@ document.addEventListener('DOMContentLoaded', function () {
|
|
|
936
1094
|
return sum + (isNaN(chars) ? 0 : chars);
|
|
937
1095
|
}, 0);
|
|
938
1096
|
|
|
939
|
-
// Determine session gap (from settings or default)
|
|
940
|
-
let sessionGap = window.statsConfig?.sessionGapSeconds || 3600;
|
|
941
|
-
|
|
942
|
-
// Calculate sessions
|
|
943
1097
|
let sessions = 0;
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
1098
|
+
let sessionGap = window.statsConfig ? window.statsConfig.sessionGapSeconds : 3600;
|
|
1099
|
+
let minimumSessionLength = 300; // 5 minutes minimum session length
|
|
1100
|
+
let sessionDetails = [];
|
|
1101
|
+
if (targetLines.length > 0) {
|
|
1102
|
+
// Sort lines by timestamp
|
|
1103
|
+
const sortedLines = targetLines.slice().sort((a, b) => parseFloat(a.timestamp) - parseFloat(b.timestamp));
|
|
1104
|
+
let currentSession = null;
|
|
1105
|
+
let lastTimestamp = null;
|
|
1106
|
+
let lastGameName = null;
|
|
1107
|
+
|
|
1108
|
+
for (let i = 0; i < sortedLines.length; i++) {
|
|
1109
|
+
const line = sortedLines[i];
|
|
1110
|
+
const ts = parseFloat(line.timestamp);
|
|
1111
|
+
const gameName = line.game_name || '';
|
|
1112
|
+
const chars = Number(line.characters) || 0;
|
|
1113
|
+
|
|
1114
|
+
// Determine if new session: gap or new game
|
|
1115
|
+
const isNewSession =
|
|
1116
|
+
(lastTimestamp !== null && ts - lastTimestamp > sessionGap) ||
|
|
1117
|
+
(lastGameName !== null && gameName !== lastGameName);
|
|
1118
|
+
|
|
1119
|
+
if (!currentSession || isNewSession) {
|
|
1120
|
+
// Finish previous session
|
|
1121
|
+
if (currentSession) {
|
|
1122
|
+
// Calculate read speed for session
|
|
1123
|
+
if (currentSession.totalSeconds > 0) {
|
|
1124
|
+
currentSession.readSpeed = Math.round(currentSession.totalChars / (currentSession.totalSeconds / 3600));
|
|
1125
|
+
} else {
|
|
1126
|
+
currentSession.readSpeed = '-';
|
|
1127
|
+
}
|
|
1128
|
+
// Only add session if it meets minimum length requirement
|
|
1129
|
+
if (currentSession.totalSeconds >= minimumSessionLength) {
|
|
1130
|
+
sessionDetails.push(currentSession);
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
// Start new session
|
|
1134
|
+
currentSession = {
|
|
1135
|
+
startTime: ts,
|
|
1136
|
+
endTime: ts,
|
|
1137
|
+
gameName: gameName,
|
|
1138
|
+
totalChars: chars,
|
|
1139
|
+
totalSeconds: 0,
|
|
1140
|
+
lines: [line]
|
|
1141
|
+
};
|
|
1142
|
+
} else {
|
|
1143
|
+
// Continue current session
|
|
1144
|
+
currentSession.endTime = ts;
|
|
1145
|
+
currentSession.totalChars += chars;
|
|
1146
|
+
currentSession.lines.push(line);
|
|
1147
|
+
if (lastTimestamp !== null) {
|
|
1148
|
+
let afkTimerSeconds = window.statsConfig ? window.statsConfig.afkTimerSeconds : 120;
|
|
1149
|
+
currentSession.totalSeconds += Math.min(ts - lastTimestamp, afkTimerSeconds);
|
|
957
1150
|
}
|
|
958
1151
|
}
|
|
1152
|
+
|
|
1153
|
+
lastTimestamp = ts;
|
|
1154
|
+
lastGameName = gameName;
|
|
959
1155
|
}
|
|
1156
|
+
|
|
1157
|
+
// Push last session
|
|
1158
|
+
if (currentSession) {
|
|
1159
|
+
if (currentSession.totalSeconds > 0) {
|
|
1160
|
+
currentSession.readSpeed = Math.round(currentSession.totalChars / (currentSession.totalSeconds / 3600));
|
|
1161
|
+
} else {
|
|
1162
|
+
currentSession.readSpeed = '-';
|
|
1163
|
+
}
|
|
1164
|
+
// Only add session if it meets minimum length requirement
|
|
1165
|
+
if (currentSession.totalSeconds >= minimumSessionLength) {
|
|
1166
|
+
sessionDetails.push(currentSession);
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
sessions = sessionDetails.length;
|
|
1171
|
+
} else {
|
|
1172
|
+
sessions = 0;
|
|
1173
|
+
sessionDetails = [];
|
|
960
1174
|
}
|
|
961
1175
|
|
|
1176
|
+
// Optionally, you can expose sessionDetails for debugging or further UI use:
|
|
1177
|
+
console.log(sessionDetails);
|
|
1178
|
+
window.todaySessionDetails = sessionDetails;
|
|
1179
|
+
|
|
962
1180
|
// Calculate total reading time
|
|
963
1181
|
let totalSeconds = 0;
|
|
964
1182
|
const timestamps = targetLines
|
|
@@ -999,6 +1217,8 @@ document.addEventListener('DOMContentLoaded', function () {
|
|
|
999
1217
|
document.getElementById('todayTotalChars').textContent = totalChars.toLocaleString();
|
|
1000
1218
|
document.getElementById('todaySessions').textContent = sessions;
|
|
1001
1219
|
document.getElementById('todayCharsPerHour').textContent = charsPerHour;
|
|
1220
|
+
|
|
1221
|
+
showSessionAtIndex(sessionDetails.length - 1);
|
|
1002
1222
|
}
|
|
1003
1223
|
|
|
1004
1224
|
if (data && data.currentGameStats && data.allGamesStats) {
|
|
@@ -219,6 +219,44 @@
|
|
|
219
219
|
</div>
|
|
220
220
|
</div>
|
|
221
221
|
|
|
222
|
+
<!-- Today's Sessions Overview Card -->
|
|
223
|
+
<div class="dashboard-card current-session-overview" id="currentSessionOverviewCard" style="margin-bottom: 24px;">
|
|
224
|
+
<div class="dashboard-card-header">
|
|
225
|
+
<h3 class="dashboard-card-title">
|
|
226
|
+
<span class="dashboard-card-icon">🔄</span>
|
|
227
|
+
Today's Sessions
|
|
228
|
+
</h3>
|
|
229
|
+
<p class="dashboard-card-subtitle" id="currentSessionStatus">Loading...</p>
|
|
230
|
+
<!-- Two Arrow Keys To Navigate Between Sessions -->
|
|
231
|
+
<div class="session-navigation">
|
|
232
|
+
<button class="prev-session-btn" data-action="prevSession">←</button>
|
|
233
|
+
<button class="next-session-btn" data-action="nextSession">→</button>
|
|
234
|
+
</div>
|
|
235
|
+
</div>
|
|
236
|
+
<div class="dashboard-stats-grid" id="currentSessionStats">
|
|
237
|
+
<div class="dashboard-stat-item tooltip" data-tooltip="Total hours spent reading in latest session">
|
|
238
|
+
<span class="dashboard-stat-value" id="currentSessionTotalHours">-</span>
|
|
239
|
+
<span class="dashboard-stat-label">Hours Spent</span>
|
|
240
|
+
</div>
|
|
241
|
+
<div class="dashboard-stat-item tooltip" data-tooltip="Total characters read in latest session">
|
|
242
|
+
<span class="dashboard-stat-value" id="currentSessionTotalChars">-</span>
|
|
243
|
+
<span class="dashboard-stat-label">Characters</span>
|
|
244
|
+
</div>
|
|
245
|
+
<div class="dashboard-stat-item tooltip" data-tooltip="Session start time">
|
|
246
|
+
<span class="dashboard-stat-value" id="currentSessionStartTime">-</span>
|
|
247
|
+
<span class="dashboard-stat-label">Started</span>
|
|
248
|
+
</div>
|
|
249
|
+
<div class="dashboard-stat-item tooltip" data-tooltip="Session end time">
|
|
250
|
+
<span class="dashboard-stat-value" id="currentSessionEndTime">-</span>
|
|
251
|
+
<span class="dashboard-stat-label">Ended</span>
|
|
252
|
+
</div>
|
|
253
|
+
<div class="dashboard-stat-item tooltip" data-tooltip="Average reading speed in latest session">
|
|
254
|
+
<span class="dashboard-stat-value" id="currentSessionCharsPerHour">-</span>
|
|
255
|
+
<span class="dashboard-stat-label">Chars/Hour</span>
|
|
256
|
+
</div>
|
|
257
|
+
</div>
|
|
258
|
+
</div>
|
|
259
|
+
|
|
222
260
|
<div class="chart-container">
|
|
223
261
|
<h2>Activity Heatmap</h2>
|
|
224
262
|
<div id="heatmapContainer"></div>
|
|
@@ -179,7 +179,10 @@ def get_screenshot():
|
|
|
179
179
|
event_id = data.get('id')
|
|
180
180
|
if event_id is None:
|
|
181
181
|
return jsonify({'error': 'Missing id'}), 400
|
|
182
|
-
|
|
182
|
+
line = get_line_by_id(event_id)
|
|
183
|
+
if not line:
|
|
184
|
+
return jsonify({'error': 'Invalid id'}), 400
|
|
185
|
+
gsm_state.line_for_screenshot = line
|
|
183
186
|
if gsm_state.previous_line_for_screenshot and gsm_state.line_for_screenshot == gsm_state.previous_line_for_screenshot or gsm_state.previous_line_for_audio and gsm_state.line_for_screenshot == gsm_state.previous_line_for_audio:
|
|
184
187
|
handle_texthooker_button(gsm_state.previous_replay)
|
|
185
188
|
else:
|
|
@@ -195,7 +198,10 @@ def play_audio():
|
|
|
195
198
|
if event_id is None:
|
|
196
199
|
return jsonify({'error': 'Missing id'}), 400
|
|
197
200
|
print(f"Playing audio for event ID: {event_id}")
|
|
198
|
-
|
|
201
|
+
line = get_line_by_id(event_id)
|
|
202
|
+
if not line:
|
|
203
|
+
return jsonify({'error': 'Invalid id'}), 400
|
|
204
|
+
gsm_state.line_for_audio = line
|
|
199
205
|
print(f"gsm_state.line_for_audio: {gsm_state.line_for_audio}")
|
|
200
206
|
if gsm_state.previous_line_for_audio and gsm_state.line_for_audio == gsm_state.previous_line_for_audio or gsm_state.previous_line_for_screenshot and gsm_state.line_for_audio == gsm_state.previous_line_for_screenshot:
|
|
201
207
|
handle_texthooker_button(gsm_state.previous_replay)
|
|
@@ -212,6 +218,8 @@ def translate_line():
|
|
|
212
218
|
if event_id is None:
|
|
213
219
|
return jsonify({'error': 'Missing id'}), 400
|
|
214
220
|
line = get_line_by_id(event_id)
|
|
221
|
+
if line is None:
|
|
222
|
+
return jsonify({'error': 'Invalid id'}), 400
|
|
215
223
|
line_to_translate = text if text else line.text
|
|
216
224
|
translation = get_ai_prompt_result(get_all_lines(), line_to_translate,
|
|
217
225
|
line, get_current_game())
|
|
@@ -384,6 +392,13 @@ def reset_checked_lines():
|
|
|
384
392
|
})
|
|
385
393
|
event_manager.reset_checked_lines()
|
|
386
394
|
asyncio.run(send_reset_message())
|
|
395
|
+
|
|
396
|
+
def reset_buttons():
|
|
397
|
+
async def send_reset_message():
|
|
398
|
+
await websocket_server_thread.send_text({
|
|
399
|
+
'event': 'reset_buttons',
|
|
400
|
+
})
|
|
401
|
+
asyncio.run(send_reset_message())
|
|
387
402
|
|
|
388
403
|
|
|
389
404
|
def open_texthooker():
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
GameSentenceMiner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
GameSentenceMiner/anki.py,sha256=
|
|
2
|
+
GameSentenceMiner/anki.py,sha256=XHsLU_uhTA9qO6TfX8NwkHEy7dyfD6rHlvG37u2-x1E,31251
|
|
3
3
|
GameSentenceMiner/gametext.py,sha256=FBL3kgJ71hCg5Nczuo9dAEi_sLGdVIGgvc62bT5KhCc,10691
|
|
4
4
|
GameSentenceMiner/gsm.py,sha256=0hEpEBDbI9FtiKtHeyrSLKV1nys-mKTKfxLY0Dk7mOQ,36387
|
|
5
5
|
GameSentenceMiner/obs.py,sha256=tyiZhVTGxWUsc_L1A5PmmSxHuWILx-B_QnW5TKbcf4A,36873
|
|
6
|
-
GameSentenceMiner/vad.py,sha256=
|
|
6
|
+
GameSentenceMiner/vad.py,sha256=I9ySJkblBmLaNumK77yZcQ7xM7DjLhGP2hNosBtNfjQ,21289
|
|
7
7
|
GameSentenceMiner/ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
8
|
GameSentenceMiner/ai/ai_prompting.py,sha256=mq9Odv_FpohXagU-OoSZbLWttdrEl1M1NiqnodeUpD8,29126
|
|
9
9
|
GameSentenceMiner/assets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -14,9 +14,9 @@ GameSentenceMiner/assets/icon32.png,sha256=Kww0hU_qke9_22wBuO_Nq0Dv2SfnOLwMhCyGg
|
|
|
14
14
|
GameSentenceMiner/assets/icon512.png,sha256=HxUj2GHjyQsk8NV433256UxU9phPhtjCY-YB_7W4sqs,192487
|
|
15
15
|
GameSentenceMiner/assets/icon64.png,sha256=N8xgdZXvhqVQP9QUK3wX5iqxX9LxHljD7c-Bmgim6tM,9301
|
|
16
16
|
GameSentenceMiner/assets/pickaxe.png,sha256=VfIGyXyIZdzEnVcc4PmG3wszPMO1W4KCT7Q_nFK6eSE,1403829
|
|
17
|
-
GameSentenceMiner/locales/en_us.json,sha256=
|
|
18
|
-
GameSentenceMiner/locales/ja_jp.json,sha256=
|
|
19
|
-
GameSentenceMiner/locales/zh_cn.json,sha256=
|
|
17
|
+
GameSentenceMiner/locales/en_us.json,sha256=SzkTPoCTXqX0utPiSVUE8Unv_27ehuMHOBQzT9t8pMo,28152
|
|
18
|
+
GameSentenceMiner/locales/ja_jp.json,sha256=ekgfTyPPVn1rFZlgE70Gc07SDicIBsJ3A8qHUw9yCZg,30194
|
|
19
|
+
GameSentenceMiner/locales/zh_cn.json,sha256=aa7IdLCYEXB05TpXdIGXJFyfVaJOABIdXwYKwpYyB1Y,26144
|
|
20
20
|
GameSentenceMiner/ocr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
21
|
GameSentenceMiner/ocr/gsm_ocr_config.py,sha256=Ov04c-nKzh3sADxO-5JyZWVe4DlrHM9edM9tc7-97Jo,5970
|
|
22
22
|
GameSentenceMiner/ocr/ocrconfig.py,sha256=_tY8mjnzHMJrLS8E5pHqYXZjMuLoGKYgJwdhYgN-ny4,6466
|
|
@@ -36,15 +36,16 @@ GameSentenceMiner/tools/furigana_filter_preview.py,sha256=BXv7FChPEJW_VeG5XYt6su
|
|
|
36
36
|
GameSentenceMiner/tools/ss_selector.py,sha256=ob2oJdiYreDMMau7CvsglpnhZ1CDnJqop3lV54-PjRo,4782
|
|
37
37
|
GameSentenceMiner/tools/window_transparency.py,sha256=GtbxbmZg0-UYPXhfHff-7IKZyY2DKe4B9GdyovfmpeM,8166
|
|
38
38
|
GameSentenceMiner/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
|
-
GameSentenceMiner/ui/anki_confirmation.py,sha256=
|
|
40
|
-
GameSentenceMiner/ui/config_gui.py,sha256=
|
|
39
|
+
GameSentenceMiner/ui/anki_confirmation.py,sha256=fAPdZ_nfpSCuhLBim7jpHNXCnlODWwQs-c8qAS-brwU,10699
|
|
40
|
+
GameSentenceMiner/ui/config_gui.py,sha256=4baqfL33oMshmqm903GZok32Y4JIEV-3K9gf5gxAJDU,152131
|
|
41
41
|
GameSentenceMiner/ui/screenshot_selector.py,sha256=AKML87MpgYQeSuj1F10GngpNrn9qp06zLLzNRwrQWM8,8900
|
|
42
42
|
GameSentenceMiner/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
|
-
GameSentenceMiner/util/
|
|
43
|
+
GameSentenceMiner/util/audio_player.py,sha256=-yFsf0qoTSS1ga5rCmEJZJGUSJzXCvfZHY3t0NxycDk,7896
|
|
44
|
+
GameSentenceMiner/util/configuration.py,sha256=lwo73S3xnIMPq8lWSWM6N0pd08A4-JvrejypT3ZvTr8,47483
|
|
44
45
|
GameSentenceMiner/util/db.py,sha256=1DjGjlwWnPefmQfzvMqqFPW0a0qeO-fIXE1YqKiok18,32000
|
|
45
46
|
GameSentenceMiner/util/electron_config.py,sha256=KfeJToeFFVw0IR5MKa-gBzpzaGrU-lyJbR9z-sDEHYU,8767
|
|
46
47
|
GameSentenceMiner/util/ffmpeg.py,sha256=cAzztfY36Xf2WvsJDjavoiMOvA9ac2GVdCrSB4LzHk4,29007
|
|
47
|
-
GameSentenceMiner/util/get_overlay_coords.py,sha256=
|
|
48
|
+
GameSentenceMiner/util/get_overlay_coords.py,sha256=4V04RNVSIoiGrxRbYgzec2r29L8s7kmOjI_tuwfjLhI,24592
|
|
48
49
|
GameSentenceMiner/util/gsm_utils.py,sha256=mASECTmN10c2yPL4NEfLg0Y0YWwFso1i6r_hhJPR3MY,10974
|
|
49
50
|
GameSentenceMiner/util/model.py,sha256=R-_RYTYLSDNgBoVTPuPBcIHeOznIqi_vBzQ7VQ20WYk,6727
|
|
50
51
|
GameSentenceMiner/util/notification.py,sha256=YBhf_mSo_i3cjBz-pmeTPx3wchKiG9BK2VBdZSa2prQ,4597
|
|
@@ -62,9 +63,9 @@ GameSentenceMiner/web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
|
|
|
62
63
|
GameSentenceMiner/web/database_api.py,sha256=Ph30uGAJFSxRkBdrZglXKsuwuKP46RxjzGODMO5aaLc,84827
|
|
63
64
|
GameSentenceMiner/web/events.py,sha256=6Vyz5c9MdpMIa7Zqljqhap2XFQnAVYJ0CdQV64TSZsA,5119
|
|
64
65
|
GameSentenceMiner/web/gsm_websocket.py,sha256=B0VKpxmsRu0WRh5nFWlpDPBQ6-K2ed7TEIa0O6YWeoo,4166
|
|
65
|
-
GameSentenceMiner/web/service.py,sha256=
|
|
66
|
+
GameSentenceMiner/web/service.py,sha256=6cgUmDgtp3ZKzuPFszowjPoq-BDtC1bS3ux6sykeaqo,6662
|
|
66
67
|
GameSentenceMiner/web/stats.py,sha256=zIK0ZzyInvvlJh87KhAKYl2CCuMJWW6Wyv7UssURFbE,22366
|
|
67
|
-
GameSentenceMiner/web/texthooking_page.py,sha256=
|
|
68
|
+
GameSentenceMiner/web/texthooking_page.py,sha256=IHRy3VTMAwJeGjTNr3TgjHgxe--g5jZcnHmNzxILXQE,15698
|
|
68
69
|
GameSentenceMiner/web/static/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
69
70
|
GameSentenceMiner/web/static/apple-touch-icon.png,sha256=OcMI8af_68DA_tweOsQ5LytTyMwm7-hPW07IfrOVgEs,46132
|
|
70
71
|
GameSentenceMiner/web/static/favicon-96x96.png,sha256=lOePzjiKl1JY2J1kT_PMdyEnrlJmi5GWbmXJunM12B4,16502
|
|
@@ -85,7 +86,7 @@ GameSentenceMiner/web/static/js/anki_stats.js,sha256=ZZqvqvePan9w17Nry7ui1ozR0SM
|
|
|
85
86
|
GameSentenceMiner/web/static/js/database.js,sha256=Yz72C0u2KbL8w9mkenNzeBi_v8mZrMyM3dEsxps7r5E,31133
|
|
86
87
|
GameSentenceMiner/web/static/js/goals.js,sha256=PaJNS1jR1pIpBxYrI8Gog6XFQNPrnbaNWZ1QX7JVlAo,30938
|
|
87
88
|
GameSentenceMiner/web/static/js/kanji-grid.js,sha256=k9y25X4TvFYi2CEO7cusrcFVSQRBFWAT1LQ3zJhewYc,16365
|
|
88
|
-
GameSentenceMiner/web/static/js/overview.js,sha256=
|
|
89
|
+
GameSentenceMiner/web/static/js/overview.js,sha256=X2zYM0FOxZ3rO9MIor1KBp7Wbffq7yFypHzoBXv6sG8,62410
|
|
89
90
|
GameSentenceMiner/web/static/js/search.js,sha256=QrjsVXf90c1LzD09TPaK93RbIN9yEiXF8IKAKrDY4hw,10482
|
|
90
91
|
GameSentenceMiner/web/static/js/shared.js,sha256=ZNibQkJxdypg93uMhmr_NEgoT5hJfxikzF6RKGz5Wy0,20416
|
|
91
92
|
GameSentenceMiner/web/static/js/stats.js,sha256=kfJ756a9JPK8l9S8YUldxXuICAGMIHMGaDoJCKpjfEs,35604
|
|
@@ -93,7 +94,7 @@ GameSentenceMiner/web/templates/anki_stats.html,sha256=0Y5lT-wGlliqgWHx9bgRZyiT_
|
|
|
93
94
|
GameSentenceMiner/web/templates/database.html,sha256=fwqNfS4yX_LOXAMCSL3ieuuvzWz8KuwXizFplPFyzSs,17972
|
|
94
95
|
GameSentenceMiner/web/templates/goals.html,sha256=kYUIteYzIArDWyZguuNzJScwMrrezWjFXxreU-LzzRk,21755
|
|
95
96
|
GameSentenceMiner/web/templates/index.html,sha256=y1mrlcKWRdwmfBP8B06p1CBk1avAJOr32388nX8YX4A,229074
|
|
96
|
-
GameSentenceMiner/web/templates/overview.html,sha256=
|
|
97
|
+
GameSentenceMiner/web/templates/overview.html,sha256=bzV28od9JyrQYD2M2O4rnRSrw0H7Atr7XoeQ8XSSpCQ,26327
|
|
97
98
|
GameSentenceMiner/web/templates/search.html,sha256=nao3M_hAbm5ftzThi91NtQ3ZiINMPUNx4ngFmqLnLQ4,4060
|
|
98
99
|
GameSentenceMiner/web/templates/stats.html,sha256=IOOFK3DXa3UVSrTLR_kLLNl6iy3ei-_C4EGqdbvZCos,22811
|
|
99
100
|
GameSentenceMiner/web/templates/utility.html,sha256=KtqnZUMAYs5XsEdC9Tlsd40NKAVic0mu6sh-ReMDJpU,16940
|
|
@@ -124,9 +125,9 @@ GameSentenceMiner/web/templates/components/kanji_grid/thousand_character_classic
|
|
|
124
125
|
GameSentenceMiner/web/templates/components/kanji_grid/wanikani_levels.json,sha256=8wjnnaYQqmho6t5tMxrIAc03512A2tYhQh5dfsQnfAM,11372
|
|
125
126
|
GameSentenceMiner/web/templates/components/kanji_grid/words_hk_frequency_list.json,sha256=wRkqZNPzz6DT9OTPHpXwfqW96Qb96stCQNNgOL-ZdKk,17535
|
|
126
127
|
GameSentenceMiner/wip/__init___.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
127
|
-
gamesentenceminer-2.18.
|
|
128
|
-
gamesentenceminer-2.18.
|
|
129
|
-
gamesentenceminer-2.18.
|
|
130
|
-
gamesentenceminer-2.18.
|
|
131
|
-
gamesentenceminer-2.18.
|
|
132
|
-
gamesentenceminer-2.18.
|
|
128
|
+
gamesentenceminer-2.18.7.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
129
|
+
gamesentenceminer-2.18.7.dist-info/METADATA,sha256=tSdKTLxo7GQEm-9Zea4mSZs_2Z1unk-1jPRF3BXEM_Q,7487
|
|
130
|
+
gamesentenceminer-2.18.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
131
|
+
gamesentenceminer-2.18.7.dist-info/entry_points.txt,sha256=2APEP25DbfjSxGeHtwBstMH8mulVhLkqF_b9bqzU6vQ,65
|
|
132
|
+
gamesentenceminer-2.18.7.dist-info/top_level.txt,sha256=V1hUY6xVSyUEohb0uDoN4UIE6rUZ_JYx8yMyPGX4PgQ,18
|
|
133
|
+
gamesentenceminer-2.18.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|