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.
@@ -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.label.includes('Lines Received'))
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.label.includes('Characters Read'))
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