// Copyright (c) 2026 Gordon Bolton. MIT License. // Legacy compatibility layer - delegates to new DownloadClient system const { logToFile } = require('./logger'); const { initializeClients, getClientsByType } = require('./downloadClients'); /** * Legacy function for backward compatibility * Returns all torrents from all qBittorrent instances */ async function getAllTorrents() { try { await initializeClients(); const clients = getClientsByType('qbittorrent'); if (clients.length === 0) { logToFile('[qBittorrent] No instances configured'); return []; } const results = await Promise.all( clients.map(client => client.getActiveDownloads().catch(err => { logToFile(`[qBittorrent] Error from ${client.name}: ${err.message}`); return []; })) ); const allTorrents = results.flat(); // Convert back to legacy format for backward compatibility const legacyTorrents = allTorrents.map(download => download.raw); logToFile(`[qBittorrent] Total torrents from all instances: ${legacyTorrents.length}`); return legacyTorrents; } catch (error) { logToFile(`[qBittorrent] Error in getAllTorrents: ${error.message}`); return []; } } /** * Legacy function for backward compatibility */ function getClients() { logToFile('[qBittorrent] getClients() called - delegating to new system'); return []; // Not used in new system } function formatBytes(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]; } function formatSpeed(bytesPerSecond) { return formatBytes(bytesPerSecond) + '/s'; } function formatEta(seconds) { if (seconds < 0 || seconds === 8640000) return '∞'; // qBittorrent uses 8640000 for unknown const days = Math.floor(seconds / 86400); const hours = Math.floor((seconds % 86400) / 3600); const minutes = Math.floor((seconds % 3600) / 60); if (days > 0) return `${days}d ${hours}h ${minutes}m`; if (hours > 0) return `${hours}h ${minutes}m`; return `${minutes}m`; } function mapTorrentToDownload(torrent) { const totalSize = torrent.size; const downloadedSize = torrent.completed; const progress = torrent.progress * 100; // Map qBittorrent states to our status const stateMap = { 'downloading': 'Downloading', 'stalledDL': 'Downloading', 'metaDL': 'Downloading', 'forcedDL': 'Downloading', 'allocating': 'Downloading', 'uploading': 'Seeding', 'stalledUP': 'Seeding', 'forcedUP': 'Seeding', 'queuedUP': 'Queued', 'queuedDL': 'Queued', 'checkingUP': 'Checking', 'checkingDL': 'Checking', 'checkingResumeData': 'Checking', 'moving': 'Moving', 'pausedUP': 'Paused', 'pausedDL': 'Paused', 'stoppedUP': 'Stopped', 'stoppedDL': 'Stopped', 'error': 'Error', 'missingFiles': 'Error', 'unknown': 'Unknown' }; const status = stateMap[torrent.state] || torrent.state; return { type: 'torrent', title: torrent.name, instanceName: torrent.instanceName, status: status, progress: progress.toFixed(1), size: formatBytes(totalSize), rawSize: totalSize, rawDownloaded: downloadedSize, speed: formatSpeed(torrent.dlspeed), rawSpeed: torrent.dlspeed, eta: formatEta(torrent.eta), rawEta: torrent.eta, seeds: torrent.num_seeds, peers: torrent.num_leechs, availability: (torrent.availability * 100).toFixed(1), hash: torrent.hash, category: torrent.category, tags: torrent.tags, savePath: torrent.content_path || torrent.save_path || null, addedOn: torrent.added_on || null, qbittorrent: true }; } module.exports = { getTorrents: getAllTorrents, getClients, mapTorrentToDownload, formatBytes, formatSpeed, formatEta, QBittorrentClient };