refactor: update and remove anything to do with NFO files
Local Docker Build (Dev) / build-dev (push) Successful in 35s

moving to an all DB approach since radarr overwrites .nfo files
This commit is contained in:
2025-11-02 13:43:28 -05:00
parent 041caf0d0d
commit 97a9f3431a
13 changed files with 837 additions and 2252 deletions
+184
View File
@@ -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
@@ -1742,3 +1743,186 @@ async function bulkDeleteSelected() {
showToast(`❌ Failed to delete ${failCount} episode(s)`, 'error');
}
}
// ---------------------------
// Database Population Functions
// ---------------------------
async function handlePopulateDatabase(event) {
event.preventDefault();
const mediaType = document.getElementById('populate-media-type').value;
// Validate input
if (!mediaType) {
showToast('❌ Please select media type', 'error');
return;
}
// Confirm with user
const confirmMsg = `Are you sure you want to populate the database with ${mediaType}? This will query Radarr/Sonarr and may take several minutes.`;
if (!confirm(confirmMsg)) {
return;
}
try {
// Show populate status
showPopulateStatus();
// Start the population
showToast('🚀 Starting database population...', 'info');
const response = await fetch(`/admin/populate-database?media_type=${mediaType}`, {
method: 'POST',
credentials: 'include'
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const result = await response.json();
if (result.status === 'started') {
showToast('✅ Population started successfully', 'success');
// Start polling for status
startPopulatePolling();
} else {
showToast(`${result.message || 'Population completed'}`, 'info');
hidePopulateStatus();
}
} catch (error) {
console.error('Database population failed:', error);
showToast(`❌ Population failed: ${error.message}`, 'error');
hidePopulateStatus();
}
}
function showPopulateStatus() {
const populateStatus = document.getElementById('populate-status');
const progressBar = document.getElementById('populate-progress-bar');
const operationText = document.getElementById('populate-current-operation');
const progressText = document.getElementById('populate-progress-text');
const resultsDiv = document.getElementById('populate-results');
populateStatus.style.display = 'block';
progressBar.style.width = '0%';
operationText.textContent = 'Initializing...';
progressText.textContent = '0%';
resultsDiv.innerHTML = '';
}
function hidePopulateStatus() {
const populateStatus = document.getElementById('populate-status');
if (populateStatus) {
populateStatus.style.display = 'none';
}
}
function startPopulatePolling() {
// Poll every 2 seconds for populate status
window.populatePollingInterval = setInterval(async () => {
try {
const response = await fetch('/api/populate/status');
if (!response.ok) {
throw new Error('Failed to get populate status');
}
const status = await response.json();
updatePopulateProgress(status);
// Stop polling if population is complete
if (!status.running && status.completed) {
stopPopulatePolling();
showToast('✅ Database population completed!', 'success');
}
} catch (error) {
console.error('Failed to poll populate status:', error);
// Don't show error toast repeatedly, just stop polling
stopPopulatePolling();
}
}, 2000);
}
function stopPopulatePolling() {
if (window.populatePollingInterval) {
clearInterval(window.populatePollingInterval);
window.populatePollingInterval = null;
}
}
function updatePopulateProgress(status) {
const progressBar = document.getElementById('populate-progress-bar');
const operationText = document.getElementById('populate-current-operation');
const progressText = document.getElementById('populate-progress-text');
const resultsDiv = document.getElementById('populate-results');
if (status.error) {
progressBar.style.width = '100%';
progressBar.style.backgroundColor = '#e74c3c';
operationText.textContent = 'Error occurred';
progressText.textContent = 'Failed';
resultsDiv.innerHTML = `<p style="color: #e74c3c;">Error: ${status.error}</p>`;
return;
}
if (!status.running && status.completed) {
progressBar.style.width = '100%';
operationText.textContent = 'Population completed';
progressText.textContent = '100%';
// Display results
let resultsHTML = '<h4>Population Results:</h4>';
if (status.movies && status.movies.stats) {
const m = status.movies.stats;
resultsHTML += `
<div style="margin: 10px 0;">
<strong>Movies:</strong><br>
Total: ${m.total || 0} | Added: ${m.added || 0} | Skipped: ${m.skipped || 0} | Errors: ${m.errors || 0}<br>
Duration: ${m.duration ? m.duration.toFixed(2) : 0}s
</div>
`;
}
if (status.tv && status.tv.stats) {
const t = status.tv.stats;
resultsHTML += `
<div style="margin: 10px 0;">
<strong>TV Shows:</strong><br>
Series: ${t.total_series || 0} | Episodes: ${t.total_episodes || 0}<br>
Added: ${t.added || 0} | Skipped: ${t.skipped || 0} | Errors: ${t.errors || 0}<br>
Duration: ${t.duration ? t.duration.toFixed(2) : 0}s
</div>
`;
}
resultsDiv.innerHTML = resultsHTML;
return;
}
// Update progress based on status
let totalProgress = 0;
let progressDetails = '';
if (status.movies && status.movies.status === 'running') {
totalProgress = 50;
progressDetails = 'Processing movies...';
} else if (status.movies && status.movies.status === 'completed') {
totalProgress = 50;
progressDetails = 'Movies completed, processing TV...';
}
if (status.tv && status.tv.status === 'running') {
totalProgress = 75;
progressDetails = 'Processing TV shows...';
} else if (status.tv && status.tv.status === 'completed') {
totalProgress = 100;
progressDetails = 'Completed';
}
progressBar.style.width = `${totalProgress}%`;
operationText.textContent = progressDetails;
progressText.textContent = `${totalProgress}%`;
}