GameSentenceMiner 2.16.1__py3-none-any.whl → 2.16.3__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/config_gui.py +15 -3
- GameSentenceMiner/gsm.py +0 -1
- GameSentenceMiner/locales/en_us.json +4 -0
- GameSentenceMiner/locales/ja_jp.json +4 -0
- GameSentenceMiner/locales/zh_cn.json +4 -0
- GameSentenceMiner/util/configuration.py +5 -0
- GameSentenceMiner/util/db.py +33 -0
- GameSentenceMiner/util/get_overlay_coords.py +59 -2
- GameSentenceMiner/vad.py +2 -2
- GameSentenceMiner/web/database_api.py +170 -5
- GameSentenceMiner/web/static/js/shared.js +67 -0
- GameSentenceMiner/web/static/js/stats.js +141 -2
- GameSentenceMiner/web/templates/anki_stats.html +4 -0
- GameSentenceMiner/web/templates/components/navigation.html +4 -1
- GameSentenceMiner/web/templates/database.html +3 -0
- GameSentenceMiner/web/templates/index.html +12 -12
- GameSentenceMiner/web/templates/search.html +3 -0
- GameSentenceMiner/web/templates/stats.html +36 -0
- GameSentenceMiner/web/texthooking_page.py +7 -1
- {gamesentenceminer-2.16.1.dist-info → gamesentenceminer-2.16.3.dist-info}/METADATA +1 -1
- {gamesentenceminer-2.16.1.dist-info → gamesentenceminer-2.16.3.dist-info}/RECORD +25 -25
- {gamesentenceminer-2.16.1.dist-info → gamesentenceminer-2.16.3.dist-info}/WHEEL +0 -0
- {gamesentenceminer-2.16.1.dist-info → gamesentenceminer-2.16.3.dist-info}/entry_points.txt +0 -0
- {gamesentenceminer-2.16.1.dist-info → gamesentenceminer-2.16.3.dist-info}/licenses/LICENSE +0 -0
- {gamesentenceminer-2.16.1.dist-info → gamesentenceminer-2.16.3.dist-info}/top_level.txt +0 -0
@@ -725,12 +725,12 @@ document.addEventListener('DOMContentLoaded', function () {
|
|
725
725
|
// Filter datasets for each chart
|
726
726
|
const linesData = {
|
727
727
|
labels: data.labels,
|
728
|
-
datasets: data.datasets.filter(d => d.
|
728
|
+
datasets: data.datasets.filter(d => d.for === "Lines Received")
|
729
729
|
};
|
730
730
|
|
731
731
|
const charsData = {
|
732
732
|
labels: data.labels,
|
733
|
-
datasets: data.datasets.filter(d => d.
|
733
|
+
datasets: data.datasets.filter(d => d.for === 'Characters Read')
|
734
734
|
};
|
735
735
|
|
736
736
|
// Remove the 'hidden' property so they appear on their own charts
|
@@ -1424,4 +1424,143 @@ document.addEventListener('DOMContentLoaded', function () {
|
|
1424
1424
|
if (document.getElementById('gamesTableBody')) {
|
1425
1425
|
new GameDeletionManager();
|
1426
1426
|
}
|
1427
|
+
|
1428
|
+
// ExStatic Import Functionality
|
1429
|
+
const exstaticFileInput = document.getElementById('exstaticFile');
|
1430
|
+
const importExstaticBtn = document.getElementById('importExstaticBtn');
|
1431
|
+
const importProgress = document.getElementById('importProgress');
|
1432
|
+
const importProgressBar = document.getElementById('importProgressBar');
|
1433
|
+
const importProgressText = document.getElementById('importProgressText');
|
1434
|
+
const importStatus = document.getElementById('importStatus');
|
1435
|
+
|
1436
|
+
if (exstaticFileInput && importExstaticBtn) {
|
1437
|
+
// Enable/disable import button based on file selection
|
1438
|
+
exstaticFileInput.addEventListener('change', function(e) {
|
1439
|
+
const file = e.target.files[0];
|
1440
|
+
if (file && file.type === 'text/csv' && file.name.toLowerCase().endsWith('.csv')) {
|
1441
|
+
importExstaticBtn.disabled = false;
|
1442
|
+
importExstaticBtn.style.background = '#2980b9';
|
1443
|
+
importExstaticBtn.style.cursor = 'pointer';
|
1444
|
+
showImportStatus('', 'info', false);
|
1445
|
+
} else {
|
1446
|
+
importExstaticBtn.disabled = true;
|
1447
|
+
importExstaticBtn.style.background = '#666';
|
1448
|
+
importExstaticBtn.style.cursor = 'not-allowed';
|
1449
|
+
if (file) {
|
1450
|
+
showImportStatus('Please select a valid CSV file.', 'error', true);
|
1451
|
+
}
|
1452
|
+
}
|
1453
|
+
});
|
1454
|
+
|
1455
|
+
// Handle import button click
|
1456
|
+
importExstaticBtn.addEventListener('click', function() {
|
1457
|
+
const file = exstaticFileInput.files[0];
|
1458
|
+
if (!file) {
|
1459
|
+
showImportStatus('Please select a CSV file first.', 'error', true);
|
1460
|
+
return;
|
1461
|
+
}
|
1462
|
+
|
1463
|
+
importExstaticData(file);
|
1464
|
+
});
|
1465
|
+
}
|
1466
|
+
|
1467
|
+
function showImportStatus(message, type, show) {
|
1468
|
+
if (!importStatus) return;
|
1469
|
+
|
1470
|
+
if (show && message) {
|
1471
|
+
importStatus.textContent = message;
|
1472
|
+
importStatus.style.display = 'block';
|
1473
|
+
|
1474
|
+
// Set appropriate styling based on type
|
1475
|
+
if (type === 'error') {
|
1476
|
+
importStatus.style.background = 'var(--danger-color)';
|
1477
|
+
importStatus.style.color = 'white';
|
1478
|
+
} else if (type === 'success') {
|
1479
|
+
importStatus.style.background = 'var(--success-color)';
|
1480
|
+
importStatus.style.color = 'white';
|
1481
|
+
} else if (type === 'info') {
|
1482
|
+
importStatus.style.background = 'var(--primary-color)';
|
1483
|
+
importStatus.style.color = 'white';
|
1484
|
+
} else {
|
1485
|
+
importStatus.style.background = 'var(--bg-tertiary)';
|
1486
|
+
importStatus.style.color = 'var(--text-primary)';
|
1487
|
+
}
|
1488
|
+
} else {
|
1489
|
+
importStatus.style.display = 'none';
|
1490
|
+
}
|
1491
|
+
}
|
1492
|
+
|
1493
|
+
function showImportProgress(show, percentage = 0) {
|
1494
|
+
if (!importProgress || !importProgressBar || !importProgressText) return;
|
1495
|
+
|
1496
|
+
if (show) {
|
1497
|
+
importProgress.style.display = 'block';
|
1498
|
+
importProgressBar.style.width = percentage + '%';
|
1499
|
+
importProgressText.textContent = Math.round(percentage) + '%';
|
1500
|
+
} else {
|
1501
|
+
importProgress.style.display = 'none';
|
1502
|
+
}
|
1503
|
+
}
|
1504
|
+
|
1505
|
+
async function importExstaticData(file) {
|
1506
|
+
try {
|
1507
|
+
// Disable import button and show progress
|
1508
|
+
importExstaticBtn.disabled = true;
|
1509
|
+
showImportProgress(true, 0);
|
1510
|
+
showImportStatus('Preparing import...', 'info', true);
|
1511
|
+
|
1512
|
+
// Create FormData and append the file
|
1513
|
+
const formData = new FormData();
|
1514
|
+
formData.append('file', file);
|
1515
|
+
|
1516
|
+
// Show upload progress
|
1517
|
+
showImportProgress(true, 25);
|
1518
|
+
showImportStatus('Uploading file...', 'info', true);
|
1519
|
+
|
1520
|
+
// Send file to backend
|
1521
|
+
const response = await fetch('/api/import-exstatic', {
|
1522
|
+
method: 'POST',
|
1523
|
+
body: formData
|
1524
|
+
});
|
1525
|
+
|
1526
|
+
showImportProgress(true, 75);
|
1527
|
+
showImportStatus('Processing data...', 'info', true);
|
1528
|
+
|
1529
|
+
const result = await response.json();
|
1530
|
+
|
1531
|
+
showImportProgress(true, 100);
|
1532
|
+
|
1533
|
+
if (response.ok) {
|
1534
|
+
// Success
|
1535
|
+
const message = `Successfully imported ${result.imported_count || 0} lines from ${result.games_count || 0} games.`;
|
1536
|
+
showImportStatus(message, 'success', true);
|
1537
|
+
|
1538
|
+
// Reset file input and button
|
1539
|
+
exstaticFileInput.value = '';
|
1540
|
+
importExstaticBtn.disabled = true;
|
1541
|
+
|
1542
|
+
// Hide progress after a delay
|
1543
|
+
setTimeout(() => {
|
1544
|
+
showImportProgress(false);
|
1545
|
+
// Optionally refresh the page to show new data
|
1546
|
+
if (result.imported_count > 0) {
|
1547
|
+
setTimeout(() => {
|
1548
|
+
window.location.reload();
|
1549
|
+
}, 2000);
|
1550
|
+
}
|
1551
|
+
}, 1500);
|
1552
|
+
} else {
|
1553
|
+
// Error
|
1554
|
+
showImportStatus(result.error || 'Import failed. Please try again.', 'error', true);
|
1555
|
+
showImportProgress(false);
|
1556
|
+
}
|
1557
|
+
} catch (error) {
|
1558
|
+
console.error('Import error:', error);
|
1559
|
+
showImportStatus('Import failed due to network error. Please try again.', 'error', true);
|
1560
|
+
showImportProgress(false);
|
1561
|
+
} finally {
|
1562
|
+
// Re-enable import button only if a file is still selected
|
1563
|
+
importExstaticBtn.disabled = !(exstaticFileInput && exstaticFileInput.files && exstaticFileInput.files.length > 0);
|
1564
|
+
}
|
1565
|
+
}
|
1427
1566
|
});
|
@@ -4,6 +4,10 @@
|
|
4
4
|
<meta charset="UTF-8">
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
6
|
<title>Anki vs GSM Kanji Stats</title>
|
7
|
+
|
8
|
+
<!-- Include html2canvas for screenshot functionality -->
|
9
|
+
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
|
10
|
+
|
7
11
|
<!-- Include Chart.js from a CDN -->
|
8
12
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
9
13
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<!-- Navigation Component -->
|
2
2
|
<div class="navigation" style="display: flex; justify-content: center; align-items: center; margin-bottom: 30px; padding: 15px; background: var(--bg-secondary); border-radius: 8px; box-shadow: 0 2px 8px var(--shadow-color); border: 1px solid var(--border-color);">
|
3
3
|
<div style="display: flex; gap: 15px;">
|
4
|
-
<a href="/" class="nav-link">Home</a>
|
4
|
+
<!-- <a href="/" class="nav-link">Home</a> -->
|
5
5
|
<a href="/stats" class="nav-link">Statistics</a>
|
6
6
|
<a href="/search" class="nav-link">Search</a>
|
7
7
|
<a href="/database" class="nav-link">Database Management</a>
|
@@ -10,6 +10,9 @@
|
|
10
10
|
<button class="theme-toggle" id="settingsToggle" title="Settings">
|
11
11
|
<span id="settingsIcon">⚙️</span>
|
12
12
|
</button>
|
13
|
+
<button class="theme-toggle" id="screenshotToggle" title="Take screenshot">
|
14
|
+
<span id="screenshotIcon">📷</span>
|
15
|
+
</button>
|
13
16
|
<button class="theme-toggle" id="themeToggle" title="Toggle dark mode">
|
14
17
|
<span id="themeIcon">🌙</span>
|
15
18
|
</button>
|
@@ -6,6 +6,9 @@
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
7
7
|
<title>GSM Database Management</title>
|
8
8
|
|
9
|
+
<!-- Include html2canvas for screenshot functionality -->
|
10
|
+
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
|
11
|
+
|
9
12
|
<!-- Include shared theme styles -->
|
10
13
|
{% include 'components/theme-styles.html' %}
|
11
14
|
|