fix: SABnzbd speed assignment and size/progress parsing #24

Merged
Gandalf merged 1 commits from fix-sabnzbd-client into develop-merge 2026-05-20 21:01:23 +01:00
+21 -11
View File
@@ -58,14 +58,18 @@ class SABnzbdClient extends DownloadClient {
// Process active queue items // Process active queue items
if (queueData.queue && queueData.queue.slots) { if (queueData.queue && queueData.queue.slots) {
// Find the currently downloading slot (first one with status 'Downloading') const kbpersec = (queueData.queue && queueData.queue.kbpersec) || (clientStatus && clientStatus.kbpersec) || 0;
const activeSlot = queueData.queue.slots.find(slot => slot.status === 'Downloading'); const globalSpeed = parseFloat(kbpersec) * 1024;
const activeSpeed = activeSlot && clientStatus ? (clientStatus.kbpersec ? clientStatus.kbpersec * 1024 : 0) : 0;
logToFile(`[SABnzbd:${this.name}] Active slot: ${activeSlot ? activeSlot.nzo_id : 'none'}, Speed: ${activeSpeed}, Client status: ${clientStatus ? JSON.stringify({ kbpersec: clientStatus.kbpersec }) : 'none'}`); logToFile(`[SABnzbd:${this.name}] Global Speed: ${globalSpeed}, Client status: ${clientStatus ? JSON.stringify({ kbpersec: clientStatus.kbpersec }) : 'none'}`);
for (const slot of queueData.queue.slots) { for (const slot of queueData.queue.slots) {
const slotSpeed = activeSlot === slot ? activeSpeed : 0; let slotSpeed = 0;
if (slot.status === 'Downloading') {
slotSpeed = globalSpeed;
} else if (slot.status === 'Paused' && slot.kbpersec && parseFloat(slot.kbpersec) > 0) {
slotSpeed = globalSpeed;
}
logToFile(`[SABnzbd:${this.name}] Slot ${slot.nzo_id} status ${slot.status}, speed ${slotSpeed}`); logToFile(`[SABnzbd:${this.name}] Slot ${slot.nzo_id} status ${slot.status}, speed ${slotSpeed}`);
downloads.push(this.normalizeDownload(slot, 'queue', slotSpeed)); downloads.push(this.normalizeDownload(slot, 'queue', slotSpeed));
} }
@@ -111,8 +115,9 @@ class SABnzbdClient extends DownloadClient {
} }
} }
normalizeDownload(slot, source, speed = 0) { normalizeDownload(slot, source, speed) {
const isHistory = source === 'history'; const isHistory = source === 'history';
const finalSpeed = speed !== undefined ? speed : (slot.kbpersec ? parseFloat(slot.kbpersec) * 1024 : 0);
// Map SABnzbd statuses to normalized status // Map SABnzbd statuses to normalized status
const statusMap = { const statusMap = {
@@ -135,10 +140,15 @@ class SABnzbdClient extends DownloadClient {
let downloaded = 0; let downloaded = 0;
let size = 0; let size = 0;
if (slot.mb && slot.mbleft !== undefined) { const hasMb = slot.mb !== undefined && slot.mb !== null;
size = slot.mb * 1024 * 1024; // Convert MB to bytes const hasMbLeft = slot.mbleft !== undefined && slot.mbleft !== null;
downloaded = (slot.mb - slot.mbleft) * 1024 * 1024; const mbValue = hasMb ? parseFloat(slot.mb) : 0;
progress = slot.mb > 0 ? ((slot.mb - slot.mbleft) / slot.mb) * 100 : 0; const mbLeftValue = hasMbLeft ? parseFloat(slot.mbleft) : 0;
if (hasMb && hasMbLeft && mbValue !== 0) {
size = mbValue * 1024 * 1024; // Convert MB to bytes
downloaded = (mbValue - mbLeftValue) * 1024 * 1024;
progress = mbValue > 0 ? ((mbValue - mbLeftValue) / mbValue) * 100 : 0;
} else if (slot.size) { } else if (slot.size) {
// Try to parse size string (e.g., "1.5 GB") // Try to parse size string (e.g., "1.5 GB")
const sizeMatch = slot.size.match(/^([\d.]+)\s*(\w+)$/i); const sizeMatch = slot.size.match(/^([\d.]+)\s*(\w+)$/i);
@@ -173,7 +183,7 @@ class SABnzbdClient extends DownloadClient {
progress: Math.round(progress), progress: Math.round(progress),
size: Math.round(size), size: Math.round(size),
downloaded: Math.round(downloaded), downloaded: Math.round(downloaded),
speed: speed, speed: finalSpeed,
eta: this.calculateEta(slot.timeleft || slot.eta), eta: this.calculateEta(slot.timeleft || slot.eta),
category: slot.cat || undefined, category: slot.cat || undefined,
tags: slot.labels ? (Array.isArray(slot.labels) ? slot.labels : slot.labels.split(',')).filter(tag => tag && tag.trim()) : [], tags: slot.labels ? (Array.isArray(slot.labels) ? slot.labels : slot.labels.split(',')).filter(tag => tag && tag.trim()) : [],