Transmission RSS Manager

Dashboard

Loading system status...

Quick Actions

RSS Manager

Manage your RSS feeds and automatic downloads

Post-Processing

Process completed downloads to your media library

Add New Torrent

Add a torrent URL directly to Transmission

RSS Feeds

Manage your RSS feeds and download filters

Loading feeds...

Available Items

Browse and download items from your RSS feeds

Loading items...

Active Torrents

Loading torrents...

Media Library

Loading media library...

Transmission Settings

Post-Processing Settings

Seeding Requirements

Media Paths

Archive Processing

File Organization

RSS Settings

('Error loading status:', error); }); } function loadTorrentsData() { fetch('/api/transmission/torrents') .then(response => response.json()) .then(data => { if (!data.success) { document.getElementById('torrents-container').innerHTML = `

${data.message}

`; return; } if (!data.data || data.data.length === 0) { document.getElementById('torrents-container').innerHTML = `

No active torrents.

`; return; } let html = ` `; data.data.forEach(torrent => { const status = getTorrentStatus(torrent); const progressPercent = Math.round(torrent.percentDone * 100); const size = formatBytes(torrent.totalSize); html += ` `; }); html += `
Name Status Progress Size Ratio Actions
${torrent.name} ${status} ${progressPercent}% ${size} ${torrent.uploadRatio.toFixed(2)} ${torrent.status === 0 ? `` : `` }
`; document.getElementById('torrents-container').innerHTML = html; }) .catch(error => { document.getElementById('torrents-container').innerHTML = `

Error loading torrents: ${error.message}

`; console.error('Error loading torrents:', error); }); } function getTorrentStatus(torrent) { const statusMap = { 0: 'Stopped', 1: 'Check Waiting', 2: 'Checking', 3: 'Download Waiting', 4: 'Downloading', 5: 'Seed Waiting', 6: 'Seeding' }; return statusMap[torrent.status] || 'Unknown'; } function formatBytes(bytes, decimals = 2) { if (bytes === 0) return '0 Bytes'; const k = 1024; const dm = decimals < 0 ? 0 : decimals; const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; } function loadRssData() { // Load RSS feeds fetch('/api/rss/feeds') .then(response => response.json()) .then(data => { if (!data.success) { document.getElementById('feeds-container').innerHTML = `

${data.message}

`; return; } if (!data.data || data.data.length === 0) { document.getElementById('feeds-container').innerHTML = `

No RSS feeds configured. Click "Add New Feed" to add one.

`; return; } let html = ` `; data.data.forEach(feed => { html += ` `; }); html += `
Name URL Auto-Download Actions
${feed.name} ${feed.url} ${feed.autoDownload ? 'Yes' : 'No'}
`; document.getElementById('feeds-container').innerHTML = html; }) .catch(error => { document.getElementById('feeds-container').innerHTML = `

Error loading feeds: ${error.message}

`; console.error('Error loading feeds:', error); }); // Load RSS items const itemFilter = document.querySelector('input[name="item-filter"]:checked').value; fetch(`/api/rss/items?filter=${itemFilter}`) .then(response => response.json()) .then(data => { if (!data.success) { document.getElementById('items-container').innerHTML = `

${data.message}

`; return; } if (!data.data || data.data.length === 0) { document.getElementById('items-container').innerHTML = `

No items found.

`; return; } let html = ` `; data.data.forEach(item => { const feed = data.data.find(f => f.id === item.feedId); const feedName = feed ? feed.name : 'Unknown'; const size = item.size ? formatBytes(item.size) : 'Unknown'; const date = new Date(item.pubDate).toLocaleDateString(); html += ` `; }); html += `
Title Feed Size Date Actions
${item.title} ${feedName} ${size} ${date}
`; document.getElementById('items-container').innerHTML = html; }) .catch(error => { document.getElementById('items-container').innerHTML = `

Error loading items: ${error.message}

`; console.error