From 11446e00dba772ea0e715319a5bc2c329d1eae22 Mon Sep 17 00:00:00 2001 From: Kobe Date: Wed, 28 May 2025 10:06:30 +0200 Subject: [PATCH] debugger cleanup --- static/js/debugging.js | 221 +++++++++++++++++++++++++ templates/settings/tabs/debugging.html | 219 +----------------------- 2 files changed, 222 insertions(+), 218 deletions(-) create mode 100644 static/js/debugging.js diff --git a/static/js/debugging.js b/static/js/debugging.js new file mode 100644 index 0000000..3c59623 --- /dev/null +++ b/static/js/debugging.js @@ -0,0 +1,221 @@ +// File system sync functionality +document.getElementById('syncFilesBtn').addEventListener('click', async function() { + const btn = this; + const status = document.getElementById('syncStatus'); + + // Disable button and show loading state + btn.disabled = true; + btn.innerHTML = ' Syncing...'; + status.textContent = 'Syncing file system...'; + + try { + const response = await fetch('/api/admin/sync-files', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').getAttribute('content') + } + }); + + console.log('Sync response status:', response.status); + console.log('Sync response headers:', Object.fromEntries(response.headers.entries())); + + const responseText = await response.text(); + console.log('Sync response text:', responseText); + + let data; + try { + data = JSON.parse(responseText); + console.log('Parsed sync response:', data); + } catch (parseError) { + console.error('JSON parse error:', parseError); + throw new Error('Invalid response format from server'); + } + + if (response.ok) { + status.textContent = 'Sync completed successfully!'; + status.className = 'text-success small'; + } else { + throw new Error(data.error || 'Sync failed'); + } + } catch (error) { + console.error('Sync error:', error); + status.textContent = error.message; + status.className = 'text-danger small'; + } finally { + // Reset button state + btn.disabled = false; + btn.innerHTML = ' Sync File System'; + + // Clear status after 5 seconds + setTimeout(() => { + status.textContent = ''; + status.className = 'text-muted small'; + }, 5000); + } +}); + +// Database verification functionality +document.getElementById('verifyDbBtn').addEventListener('click', async function() { + const btn = this; + const status = document.getElementById('verifyStatus'); + const results = document.getElementById('verificationResults'); + + // Disable button and show loading state + btn.disabled = true; + btn.innerHTML = ' Verifying...'; + status.textContent = 'Verifying database state...'; + results.style.display = 'none'; + + try { + const response = await fetch('/api/admin/verify-db-state', { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').getAttribute('content') + } + }); + + const data = await response.json(); + console.log('Verification response:', data); + + if (!response.ok) { + throw new Error(data.error || 'Verification failed'); + } + + // Update summary + const summary = document.getElementById('verificationSummary'); + const totalIssues = (data.files_in_db_not_fs?.length || 0) + + (data.files_in_fs_not_db?.length || 0) + + (data.size_mismatches?.length || 0) + + (data.modified_time_mismatches?.length || 0); + + summary.textContent = `Found ${totalIssues} issues across ${data.rooms_checked || 0} rooms.`; + + // Update counts and lists + updateMismatchSection('dbNotFs', data.files_in_db_not_fs || []); + updateMismatchSection('fsNotDb', data.files_in_fs_not_db || []); + updateMismatchSection('sizeMismatch', data.size_mismatches || []); + updateMismatchSection('timeMismatch', data.modified_time_mismatches || []); + + // Show results + results.style.display = 'block'; + status.textContent = 'Verification completed!'; + status.className = 'text-success small'; + } catch (error) { + console.error('Verification error:', error); + status.textContent = error.message; + status.className = 'text-danger small'; + } finally { + // Reset button state + btn.disabled = false; + btn.innerHTML = ' Verify Database State'; + } +}); + +// Cleanup orphaned records functionality +document.getElementById('cleanupOrphanedBtn').addEventListener('click', async function() { + const btn = this; + const status = document.getElementById('verifyStatus'); + + // Disable button and show loading state + btn.disabled = true; + btn.innerHTML = ' Cleaning up...'; + status.textContent = 'Cleaning up orphaned records...'; + + try { + const response = await fetch('/api/admin/cleanup-orphaned-records', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').getAttribute('content') + } + }); + + const data = await response.json(); + + if (!response.ok) { + throw new Error(data.error || 'Cleanup failed'); + } + + status.textContent = data.message; + status.className = 'text-success small'; + + // If there were cleaned records, trigger a verification + if (data.cleaned_records && data.cleaned_records.length > 0) { + document.getElementById('verifyDbBtn').click(); + } + } catch (error) { + console.error('Cleanup error:', error); + status.textContent = error.message; + status.className = 'text-danger small'; + } finally { + // Reset button state + btn.disabled = false; + btn.innerHTML = ' Cleanup Orphaned Records'; + + // Clear status after 5 seconds + setTimeout(() => { + status.textContent = ''; + status.className = 'text-muted small'; + }, 5000); + } +}); + +// Helper function to update mismatch sections +function updateMismatchSection(sectionId, items) { + const count = document.getElementById(`${sectionId}Count`); + const list = document.getElementById(`${sectionId}List`); + + if (!count || !list) { + console.error(`Missing elements for section ${sectionId}`); + return; + } + + count.textContent = items.length; + + if (items.length === 0) { + list.innerHTML = '
No issues found
'; + return; + } + + list.innerHTML = items.map(item => ` +
+
+
+ ${item.name || 'Unknown'} +
+ Room: ${item.room_name || 'Unknown'} + ${item.path ? `
Path: ${item.path}` : ''} +
+
+
+ ${item.type === 'file' ? 'File' : 'Folder'} +
+
+ ${item.fs_size !== undefined ? ` +
+ Size mismatch: +
Filesystem: ${formatSize(item.fs_size)} +
Database: ${formatSize(item.db_size)} +
+ ` : ''} + ${item.fs_modified !== undefined ? ` +
+ Time mismatch: +
Filesystem: ${new Date(item.fs_modified * 1000).toLocaleString()} +
Database: ${new Date(item.db_modified * 1000).toLocaleString()} +
+ ` : ''} +
+ `).join(''); +} + +// Helper function to format file sizes +function formatSize(bytes) { + if (bytes === 0) return '0 B'; + const k = 1024; + const sizes = ['B', 'KB', 'MB', 'GB', 'TB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; +} \ No newline at end of file diff --git a/templates/settings/tabs/debugging.html b/templates/settings/tabs/debugging.html index c82c7d5..a0111e0 100644 --- a/templates/settings/tabs/debugging.html +++ b/templates/settings/tabs/debugging.html @@ -111,222 +111,5 @@ - + {% endmacro %} \ No newline at end of file