const path = require('path'); const { ipcRenderer } = require('electron'); /** * FileManager - Handles file operations */ class FileManager { constructor() { } /** * Select directory * @returns {Promise} Selection result */ async selectDirectory() { try { // Use IPC to handle directory selection const result = await ipcRenderer.invoke('select-directory'); if (result.success) { return result; } else { throw new Error(result.error); } } catch (error) { console.error('Error selecting directory:', error); return { success: false, error: error.message }; } } /** * Scan directory for media files * @param {string} directoryPath - Directory path * @returns {Promise} Scan result */ async scanDirectory(directoryPath) { try { const result = await ipcRenderer.invoke('scan-directory', directoryPath); if (result.success) { return result; } else { throw new Error(result.error); } } catch (error) { console.error('Error scanning directory:', error); return { success: false, error: error.message }; } } /** * Rename a file * @param {string} oldPath - Old file path * @param {string} newName - New file name * @returns {Promise} Rename result */ async renameFile(oldPath, newName) { try { const result = await ipcRenderer.invoke('rename-file', { oldPath: oldPath, newName: newName }); if (result.success) { return result; } else { throw new Error(result.error); } } catch (error) { console.error('Error renaming file:', error); return { success: false, error: error.message }; } } /** * Begin mapping files to Jellyfin naming convention * @param {string} directory - Directory path * @param {Array} files - Files to map * @param {string|null} tvdbId - TVDB ID * @returns {Promise} Mapping result */ async beginMapping(directory, files, tvdbId) { try { const result = await ipcRenderer.invoke('begin-mapping', { directory: directory, files: files, tvdbId: tvdbId }); if (result.success) { return result; } else { throw new Error(result.error); } } catch (error) { console.error('Mapping error:', error); return { success: false, error: error.message }; } } /** * Log audit event * @param {string} directoryPath - Directory path * @param {string} action - Action type * @param {Object} details - Event details * @returns {Promise} Audit result */ async logAuditEvent(directoryPath, action, details) { try { const result = await ipcRenderer.invoke('log-audit-event', { directoryPath: directoryPath, action: action, details: details }); return result; } catch (error) { console.error('Failed to log audit event:', error); return { success: false, error: error.message }; } } /** * Move file to folder * @param {string} filePath - File path * @param {string} folderName - Folder name * @returns {Promise} Move result */ async moveFileToFolder(filePath, folderName) { try { const result = await ipcRenderer.invoke('move-file-to-folder', { filePath: filePath, folderName: folderName }); return result; } catch (error) { console.error('Error moving file:', error); return { success: false, error: error.message }; } } /** * Log file info for debugging * @param {string} filePath - File path * @returns {Promise} File info result */ async logFileInfo(filePath) { try { const result = await ipcRenderer.invoke('log-file-info', filePath); return result; } catch (error) { console.error('Error logging file info:', error); return { success: false, error: error.message }; } } /** * Open file in player * @param {string} filePath - File path */ openFileInPlayer(filePath) { ipcRenderer.invoke('open-file-in-player', filePath); } /** * Collect file data with episode ranges from UI order * @param {HTMLElement} fileListEl - File list element * @returns {Array} Array of file data objects */ collectFileData(fileListEl) { const fileItems = fileListEl.querySelectorAll('.file-item:not(.folder-item)'); const filesToMap = []; fileItems.forEach((item, index) => { const fileNameEl = item.querySelector('.file-name'); const qualityEl = item.querySelector('.file-quality'); const episodeNumEl = item.querySelector('.episode-number'); if (fileNameEl && fileNameEl.dataset.filePath) { const episodeStart = episodeNumEl ? parseInt(episodeNumEl.dataset.episodeStart || (index + 1)) : (index + 1); const episodeEnd = episodeNumEl ? parseInt(episodeNumEl.dataset.episodeEnd || episodeStart) : episodeStart; filesToMap.push({ filePath: fileNameEl.dataset.filePath, quality: qualityEl ? qualityEl.textContent : '', episodeStart: episodeStart, episodeEnd: episodeEnd }); } }); return filesToMap; } } module.exports = FileManager;