2022-05-26 19:45:18 +02:00
|
|
|
import { Loader, Table, Text, Tooltip, Title, Group, Progress, Center } from '@mantine/core';
|
2022-05-26 18:19:12 +02:00
|
|
|
import { Download } from 'tabler-icons-react';
|
|
|
|
|
import { useEffect, useState } from 'react';
|
|
|
|
|
import axios from 'axios';
|
|
|
|
|
import { NormalizedTorrent } from '@ctrl/shared-torrent';
|
|
|
|
|
import { IModule } from '../modules';
|
|
|
|
|
import { useConfig } from '../../../tools/state';
|
|
|
|
|
import { AddItemShelfButton } from '../../AppShelf/AddAppShelfItem';
|
|
|
|
|
|
|
|
|
|
export const DownloadsModule: IModule = {
|
2022-05-26 19:45:18 +02:00
|
|
|
title: 'Torrent',
|
2022-05-26 18:19:12 +02:00
|
|
|
description: 'Show the current download speed of supported services',
|
|
|
|
|
icon: Download,
|
|
|
|
|
component: DownloadComponent,
|
|
|
|
|
options: {
|
|
|
|
|
hidecomplete: {
|
|
|
|
|
name: 'Hide completed torrents',
|
|
|
|
|
value: false,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default function DownloadComponent() {
|
|
|
|
|
const { config } = useConfig();
|
|
|
|
|
const qBittorrentService = config.services
|
|
|
|
|
.filter((service) => service.type === 'qBittorrent')
|
|
|
|
|
.at(0);
|
2022-05-26 21:08:16 +02:00
|
|
|
const delugeService = config.services.filter((service) => service.type === 'Deluge').at(0);
|
2022-05-26 18:19:12 +02:00
|
|
|
const hideComplete: boolean =
|
|
|
|
|
(config?.modules?.[DownloadsModule.title]?.options?.hidecomplete?.value as boolean) ?? false;
|
|
|
|
|
|
2022-05-26 21:08:16 +02:00
|
|
|
const [delugeTorrents, setDelugeTorrents] = useState<NormalizedTorrent[]>([]);
|
|
|
|
|
const [qBittorrentTorrents, setqBittorrentTorrents] = useState<NormalizedTorrent[]>([]);
|
2022-05-26 18:19:12 +02:00
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (qBittorrentService) {
|
|
|
|
|
setInterval(() => {
|
2022-05-26 21:08:16 +02:00
|
|
|
axios
|
|
|
|
|
.post('/api/modules/downloads?dlclient=qbit', { ...qBittorrentService })
|
|
|
|
|
.then((res) => {
|
|
|
|
|
setqBittorrentTorrents(res.data.torrents);
|
|
|
|
|
});
|
|
|
|
|
}, 3000);
|
|
|
|
|
}
|
|
|
|
|
if (delugeService) {
|
|
|
|
|
setInterval(() => {
|
|
|
|
|
axios.post('/api/modules/downloads?dlclient=deluge', { ...delugeService }).then((res) => {
|
|
|
|
|
setDelugeTorrents(res.data.torrents);
|
2022-05-26 18:19:12 +02:00
|
|
|
});
|
|
|
|
|
}, 3000);
|
|
|
|
|
}
|
2022-05-26 19:45:18 +02:00
|
|
|
}, [config.modules]);
|
2022-05-26 18:19:12 +02:00
|
|
|
|
2022-05-26 21:08:16 +02:00
|
|
|
if (!qBittorrentService && !delugeService) {
|
2022-05-26 18:19:12 +02:00
|
|
|
return (
|
|
|
|
|
<Group direction="column">
|
2022-05-26 21:08:16 +02:00
|
|
|
<Title>Critical: No qBittorrent/Deluge instance found in services.</Title>
|
2022-05-26 18:19:12 +02:00
|
|
|
<Group>
|
2022-05-26 21:08:16 +02:00
|
|
|
<Title order={3}>Add a qBittorrent/Deluge service to view current downloads</Title>
|
2022-05-26 18:19:12 +02:00
|
|
|
<AddItemShelfButton />
|
|
|
|
|
</Group>
|
|
|
|
|
</Group>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-26 21:08:16 +02:00
|
|
|
if (qBittorrentTorrents.length === 0 && delugeTorrents.length === 0) {
|
2022-05-26 19:45:18 +02:00
|
|
|
return (
|
|
|
|
|
<Center>
|
|
|
|
|
<Loader />
|
|
|
|
|
</Center>
|
|
|
|
|
);
|
2022-05-26 18:19:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const ths = (
|
|
|
|
|
<tr>
|
|
|
|
|
<th>Name</th>
|
|
|
|
|
<th>Download</th>
|
|
|
|
|
<th>Upload</th>
|
|
|
|
|
<th>Progress</th>
|
|
|
|
|
</tr>
|
|
|
|
|
);
|
2022-05-26 21:08:16 +02:00
|
|
|
// Loop over qBittorrent torrents merging with deluge torrents
|
|
|
|
|
const torrents: NormalizedTorrent[] = [];
|
2022-05-27 09:45:51 +02:00
|
|
|
delugeTorrents.forEach((delugeTorrent) =>
|
|
|
|
|
torrents.push({ ...delugeTorrent, progress: delugeTorrent.progress / 100 })
|
|
|
|
|
);
|
2022-05-26 21:08:16 +02:00
|
|
|
qBittorrentTorrents.forEach((torrent) => torrents.push(torrent));
|
2022-05-26 18:19:12 +02:00
|
|
|
|
|
|
|
|
const rows = torrents.map((torrent) => {
|
|
|
|
|
if (torrent.progress === 1 && hideComplete) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
const downloadSpeed = torrent.downloadSpeed / 1024 / 1024;
|
|
|
|
|
const uploadSpeed = torrent.uploadSpeed / 1024 / 1024;
|
|
|
|
|
return (
|
|
|
|
|
<tr key={torrent.id}>
|
|
|
|
|
<td>
|
|
|
|
|
<Tooltip position="top" label={torrent.name}>
|
|
|
|
|
<Text
|
|
|
|
|
style={{
|
|
|
|
|
maxWidth: '30vw',
|
|
|
|
|
}}
|
|
|
|
|
size="xs"
|
|
|
|
|
lineClamp={1}
|
|
|
|
|
>
|
|
|
|
|
{torrent.name}
|
|
|
|
|
</Text>
|
|
|
|
|
</Tooltip>
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
|
|
|
|
<Text size="xs">{downloadSpeed > 0 ? `${downloadSpeed.toFixed(1)} Mb/s` : '-'}</Text>
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
|
|
|
|
<Text size="xs">{uploadSpeed > 0 ? `${uploadSpeed.toFixed(1)} Mb/s` : '-'}</Text>
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
|
|
|
|
<Text>{(torrent.progress * 100).toFixed(1)}%</Text>
|
|
|
|
|
<Progress
|
|
|
|
|
radius="lg"
|
|
|
|
|
color={torrent.progress === 1 ? 'green' : 'blue'}
|
|
|
|
|
value={torrent.progress * 100}
|
2022-05-26 19:14:36 +02:00
|
|
|
size="lg"
|
2022-05-26 18:19:12 +02:00
|
|
|
/>
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Group noWrap direction="column">
|
2022-05-26 19:45:18 +02:00
|
|
|
<Title order={4}>Your torrents</Title>
|
2022-05-26 18:19:12 +02:00
|
|
|
<Table highlightOnHover>
|
|
|
|
|
<thead>{ths}</thead>
|
|
|
|
|
<tbody>{rows}</tbody>
|
|
|
|
|
</Table>
|
|
|
|
|
</Group>
|
|
|
|
|
);
|
|
|
|
|
}
|