/** * NFO Manager Module * * Handles NFO metadata operations including creating, viewing, and refreshing * NFO files for anime series. */ window.AniWorld = window.AniWorld || {}; AniWorld.NFOManager = (function() { 'use strict'; /** * Create NFO metadata for a series * @param {string} seriesKey - The unique identifier for the series * @returns {Promise} API response */ async function createNFO(seriesKey) { try { AniWorld.UI.showLoading('Creating NFO metadata...'); const response = await AniWorld.ApiClient.request( `/api/nfo/${encodeURIComponent(seriesKey)}/create`, { method: 'POST', body: JSON.stringify({ overwrite_existing: false, download_poster: true, download_logo: true, download_fanart: true }) } ); if (!response) { throw new Error('Failed to create NFO'); } const data = await response.json(); if (data && data.message) { AniWorld.UI.showToast(data.message || 'NFO created successfully', 'success'); return data; } else { throw new Error('Failed to create NFO'); } } catch (error) { console.error('Error creating NFO:', error); AniWorld.UI.showToast( 'Failed to create NFO: ' + error.message, 'error' ); throw error; } finally { AniWorld.UI.hideLoading(); } } /** * Refresh NFO metadata for a series (update existing NFO) * @param {string} seriesKey - The unique identifier for the series * @returns {Promise} API response */ async function refreshNFO(seriesKey) { try { AniWorld.UI.showLoading('Refreshing NFO metadata...'); const response = await AniWorld.ApiClient.request( `/api/nfo/${encodeURIComponent(seriesKey)}/update`, { method: 'PUT' } ); if (!response) { throw new Error('Failed to refresh NFO'); } const data = await response.json(); if (data && data.message) { AniWorld.UI.showToast(data.message || 'NFO updated successfully', 'success'); return data; } else { throw new Error('Failed to refresh NFO'); } } catch (error) { console.error('Error refreshing NFO:', error); AniWorld.UI.showToast( 'Failed to refresh NFO: ' + error.message, 'error' ); throw error; } finally { AniWorld.UI.hideLoading(); } } /** * View NFO metadata for a series * @param {string} seriesKey - The unique identifier for the series * @returns {Promise} NFO data */ async function viewNFO(seriesKey) { try { AniWorld.UI.showLoading('Loading NFO data...'); const response = await AniWorld.ApiClient.request( `/api/nfo/${encodeURIComponent(seriesKey)}/content` ); if (!response) { throw new Error('No NFO data available'); } const data = await response.json(); if (data && data.content) { return data; } else { throw new Error('No NFO data available'); } } catch (error) { console.error('Error viewing NFO:', error); AniWorld.UI.showToast( 'Failed to load NFO: ' + error.message, 'error' ); throw error; } finally { AniWorld.UI.hideLoading(); } } /** * Show NFO data in a modal * @param {string} seriesKey - The unique identifier for the series */ async function showNFOModal(seriesKey) { try { const nfoData = await viewNFO(seriesKey); // Format NFO data for display const nfoHtml = formatNFOData(nfoData); // Show modal (assuming a modal utility exists) if (AniWorld.UI.showModal) { AniWorld.UI.showModal({ title: 'NFO Metadata', content: nfoHtml, size: 'large' }); } else { // Fallback: log to console console.log('NFO Data:', nfoData); alert('NFO Data:\n' + JSON.stringify(nfoData, null, 2)); } } catch (error) { console.error('Error showing NFO modal:', error); } } /** * Format NFO data for display in HTML * @param {object} nfoData - NFO metadata object * @returns {string} HTML string */ function formatNFOData(nfoData) { let html = '
'; if (nfoData.title) { html += '
Title: ' + AniWorld.UI.escapeHtml(nfoData.title) + '
'; } if (nfoData.plot) { html += '
Plot: ' + AniWorld.UI.escapeHtml(nfoData.plot) + '
'; } if (nfoData.year) { html += '
Year: ' + nfoData.year + '
'; } if (nfoData.genre) { const genres = Array.isArray(nfoData.genre) ? nfoData.genre.join(', ') : nfoData.genre; html += '
Genre: ' + AniWorld.UI.escapeHtml(genres) + '
'; } if (nfoData.rating) { html += '
Rating: ' + nfoData.rating + '
'; } if (nfoData.tmdb_id) { html += '
TMDB ID: ' + nfoData.tmdb_id + '
'; } if (nfoData.tvdb_id) { html += '
TVDB ID: ' + nfoData.tvdb_id + '
'; } html += '
'; return html; } /** * Get series without NFO * @returns {Promise} Response with series list and statistics */ async function getSeriesWithoutNFO() { try { const response = await AniWorld.ApiClient.request('/api/nfo/missing'); if (!response) { throw new Error('Failed to get series without NFO'); } const data = await response.json(); if (data && data.series) { return data; } else { throw new Error('Failed to get series without NFO'); } } catch (error) { console.error('Error getting series without NFO:', error); throw error; } } // Public API return { createNFO: createNFO, refreshNFO: refreshNFO, viewNFO: viewNFO, showNFOModal: showNFOModal, getSeriesWithoutNFO: getSeriesWithoutNFO }; })();