This commit is contained in:
@@ -77,6 +77,7 @@ function initializeEventListeners() {
|
||||
document.getElementById('edit-form').addEventListener('submit', handleEditSubmit);
|
||||
document.getElementById('bulk-update-form').addEventListener('submit', handleBulkUpdate);
|
||||
document.getElementById('manual-scan-form').addEventListener('submit', handleManualScan);
|
||||
document.getElementById('populate-form').addEventListener('submit', handlePopulateDatabase);
|
||||
}
|
||||
|
||||
// API calls
|
||||
@@ -1728,11 +1729,11 @@ async function bulkDeleteSelected() {
|
||||
// Update UI
|
||||
updateEpisodeModalCounts();
|
||||
updateBulkDeleteButton();
|
||||
|
||||
|
||||
// Reset button
|
||||
bulkDeleteButton.innerHTML = originalText;
|
||||
bulkDeleteButton.disabled = true;
|
||||
|
||||
|
||||
// Show results
|
||||
if (successCount > 0 && failCount === 0) {
|
||||
showToast(`✅ Successfully deleted ${successCount} episode(s)`, 'success');
|
||||
@@ -1742,3 +1743,212 @@ async function bulkDeleteSelected() {
|
||||
showToast(`❌ Failed to delete ${failCount} episode(s)`, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== Database Population Functions ====================
|
||||
|
||||
let populatePollingInterval = null;
|
||||
|
||||
async function handlePopulateDatabase(event) {
|
||||
event.preventDefault();
|
||||
|
||||
const mediaType = document.getElementById('populate-media-type').value;
|
||||
const submitButton = event.target.querySelector('button[type="submit"]');
|
||||
const originalText = submitButton.innerHTML;
|
||||
|
||||
// Confirm action
|
||||
const confirmMsg = mediaType === 'both'
|
||||
? 'This will populate the database with ALL movies and TV episodes from Radarr/Sonarr. Continue?'
|
||||
: mediaType === 'movies'
|
||||
? 'This will populate the database with ALL movies from Radarr. Continue?'
|
||||
: 'This will populate the database with ALL TV episodes from Sonarr. Continue?';
|
||||
|
||||
if (!confirm(confirmMsg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable button and show loading
|
||||
submitButton.disabled = true;
|
||||
submitButton.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Starting...';
|
||||
|
||||
try {
|
||||
const response = await fetch('/admin/populate-database', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ media_type: mediaType })
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.status === 'started') {
|
||||
showPopulateStatus();
|
||||
startPopulatePolling();
|
||||
} else {
|
||||
throw new Error('Failed to start population');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error starting population:', error);
|
||||
showToast('❌ Failed to start database population', 'error');
|
||||
submitButton.disabled = false;
|
||||
submitButton.innerHTML = originalText;
|
||||
}
|
||||
}
|
||||
|
||||
function showPopulateStatus() {
|
||||
const statusDiv = document.getElementById('populate-status');
|
||||
const resultsDiv = document.getElementById('populate-results');
|
||||
|
||||
if (statusDiv) {
|
||||
statusDiv.style.display = 'block';
|
||||
statusDiv.querySelector('.progress-fill').style.width = '0%';
|
||||
statusDiv.querySelector('.progress-text').textContent = 'Starting...';
|
||||
}
|
||||
|
||||
if (resultsDiv) {
|
||||
resultsDiv.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
function hidePopulateStatus() {
|
||||
const statusDiv = document.getElementById('populate-status');
|
||||
if (statusDiv) {
|
||||
statusDiv.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
function startPopulatePolling() {
|
||||
// Clear any existing interval
|
||||
if (populatePollingInterval) {
|
||||
clearInterval(populatePollingInterval);
|
||||
}
|
||||
|
||||
// Poll every 2 seconds
|
||||
populatePollingInterval = setInterval(async () => {
|
||||
try {
|
||||
const response = await fetch('/api/populate/status');
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const status = await response.json();
|
||||
updatePopulateProgress(status);
|
||||
|
||||
// Stop polling if complete or error
|
||||
if (status.status === 'completed' || status.status === 'error') {
|
||||
stopPopulatePolling();
|
||||
|
||||
// Re-enable submit button
|
||||
const submitButton = document.querySelector('#populate-form button[type="submit"]');
|
||||
if (submitButton) {
|
||||
submitButton.disabled = false;
|
||||
submitButton.innerHTML = '<i class="fas fa-play"></i> Start Population';
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error polling populate status:', error);
|
||||
stopPopulatePolling();
|
||||
|
||||
// Re-enable submit button
|
||||
const submitButton = document.querySelector('#populate-form button[type="submit"]');
|
||||
if (submitButton) {
|
||||
submitButton.disabled = false;
|
||||
submitButton.innerHTML = '<i class="fas fa-play"></i> Start Population';
|
||||
}
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
function stopPopulatePolling() {
|
||||
if (populatePollingInterval) {
|
||||
clearInterval(populatePollingInterval);
|
||||
populatePollingInterval = null;
|
||||
}
|
||||
}
|
||||
|
||||
function updatePopulateProgress(status) {
|
||||
const progressFill = document.querySelector('#populate-status .progress-fill');
|
||||
const progressText = document.querySelector('#populate-status .progress-text');
|
||||
const resultsDiv = document.getElementById('populate-results');
|
||||
|
||||
if (status.status === 'in_progress') {
|
||||
if (progressFill && progressText) {
|
||||
// Show indeterminate progress
|
||||
progressFill.style.width = '50%';
|
||||
progressText.textContent = 'Populating database...';
|
||||
}
|
||||
} else if (status.status === 'completed') {
|
||||
if (progressFill && progressText) {
|
||||
progressFill.style.width = '100%';
|
||||
progressText.textContent = 'Complete!';
|
||||
}
|
||||
|
||||
// Show results
|
||||
if (resultsDiv && status.result) {
|
||||
const result = status.result;
|
||||
let html = '<h4>Population Results</h4>';
|
||||
|
||||
// Movies
|
||||
if (result.movies) {
|
||||
const m = result.movies;
|
||||
html += '<div class="populate-section">';
|
||||
html += '<h5><i class="fas fa-film"></i> Movies</h5>';
|
||||
html += '<ul>';
|
||||
html += `<li>Total found: ${m.total || 0}</li>`;
|
||||
html += `<li>Added: ${m.added || 0}</li>`;
|
||||
html += `<li>Skipped: ${m.skipped || 0}</li>`;
|
||||
html += `<li>Errors: ${m.errors || 0}</li>`;
|
||||
html += `<li>Duration: ${(m.duration || 0).toFixed(2)}s</li>`;
|
||||
html += '</ul>';
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
// TV Episodes
|
||||
if (result.tv) {
|
||||
const tv = result.tv;
|
||||
html += '<div class="populate-section">';
|
||||
html += '<h5><i class="fas fa-tv"></i> TV Shows</h5>';
|
||||
html += '<ul>';
|
||||
html += `<li>Series: ${tv.total_series || 0}</li>`;
|
||||
html += `<li>Episodes: ${tv.total_episodes || 0}</li>`;
|
||||
html += `<li>Added: ${tv.added || 0}</li>`;
|
||||
html += `<li>Skipped: ${tv.skipped || 0}</li>`;
|
||||
html += `<li>Errors: ${tv.errors || 0}</li>`;
|
||||
html += `<li>Duration: ${(tv.duration || 0).toFixed(2)}s</li>`;
|
||||
html += '</ul>';
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
// Total duration
|
||||
if (result.total_duration) {
|
||||
html += `<p><strong>Total Duration:</strong> ${result.total_duration.toFixed(2)}s</p>`;
|
||||
}
|
||||
|
||||
resultsDiv.innerHTML = html;
|
||||
resultsDiv.style.display = 'block';
|
||||
}
|
||||
|
||||
showToast('✅ Database population completed successfully', 'success');
|
||||
|
||||
} else if (status.status === 'error') {
|
||||
if (progressFill && progressText) {
|
||||
progressFill.style.width = '100%';
|
||||
progressFill.style.backgroundColor = '#dc3545';
|
||||
progressText.textContent = 'Error!';
|
||||
}
|
||||
|
||||
const errorMsg = status.error || 'Unknown error occurred';
|
||||
showToast(`❌ Database population failed: ${errorMsg}`, 'error');
|
||||
|
||||
if (resultsDiv) {
|
||||
resultsDiv.innerHTML = `<p class="error">Error: ${errorMsg}</p>`;
|
||||
resultsDiv.style.display = 'block';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user