Merge pull request #1554 from InterN0te/dev-addRatio

Add Torrents ratio in Torrents Queue Widget
This commit is contained in:
Tagaishi
2023-11-07 12:36:43 +01:00
committed by GitHub
3 changed files with 87 additions and 3 deletions

View File

@@ -25,13 +25,19 @@
"labelFilter": { "labelFilter": {
"label": "Label list", "label": "Label list",
"description": "When 'is whitelist' checked, this will act as a whitelist. If not checked, this is a blacklist. Will not do anything when empty" "description": "When 'is whitelist' checked, this will act as a whitelist. If not checked, this is a blacklist. Will not do anything when empty"
},
"displayRatioWithFilter": {
"label": "Display filtered torrents list ratio",
"info": "If disabled, only the global ratio will be display. The global ratio will still use the labels if set"
} }
} }
}, },
"card": { "card": {
"footer": { "footer": {
"error": "Error", "error": "Error",
"lastUpdated": "Last updated {{time}} ago" "lastUpdated": "Last updated {{time}} ago",
"ratioGlobal": "Global ratio",
"ratioWithFilter": "Ratio with filter"
}, },
"table": { "table": {
"header": { "header": {

View File

@@ -1,7 +1,7 @@
import { NormalizedTorrent, TorrentState } from '@ctrl/shared-torrent'; import { NormalizedTorrent, TorrentState } from '@ctrl/shared-torrent';
import { describe, expect, it } from 'vitest'; import { describe, expect, it } from 'vitest';
import { ITorrent, filterTorrents } from './TorrentTile'; import { ITorrent, filterTorrents, getTorrentsRatio } from './TorrentTile';
describe('TorrentTile', () => { describe('TorrentTile', () => {
it('filter torrents when stale', () => { it('filter torrents when stale', () => {
@@ -229,6 +229,43 @@ describe('TorrentTile', () => {
expect(filtered.includes(torrents[1])).toBe(false); expect(filtered.includes(torrents[1])).toBe(false);
expect(filtered.at(1)).toBe(torrents[2]); expect(filtered.at(1)).toBe(torrents[2]);
}); });
it('calcul ratio', () => {
// arrange
const widget: ITorrent = {
id: 'abc',
area: {
type: 'sidebar',
properties: {
location: 'left',
},
},
shape: {},
type: 'torrents-status',
properties: {
labelFilter: [],
labelFilterIsWhitelist: false,
displayCompletedTorrents: false,
displayActiveTorrents: false,
speedLimitOfActiveTorrents: 10,
displayStaleTorrents: true,
},
};
const torrents: NormalizedTorrent[] = [
constructTorrent('HH', 'I am completed', true, 0),
];
// act
const filtered = filterTorrents(widget, torrents);
const ratioGlobal = getTorrentsRatio(widget, torrents, false);
const ratioWithFilter = getTorrentsRatio(widget, torrents, true);
// assert
expect(filtered.length).toBe(0);
expect(filtered.includes(torrents[1])).toBe(false);
expect(ratioGlobal).toBe(378535535/23024335);
expect(ratioWithFilter).toBe(-1); //infinite ratio
});
}); });
const constructTorrent = ( const constructTorrent = (

View File

@@ -60,6 +60,11 @@ const definition = defineWidget({
type: 'multiple-text', type: 'multiple-text',
defaultValue: [] as string[], defaultValue: [] as string[],
}, },
displayRatioWithFilter: {
type: 'switch',
defaultValue: true,
info: true,
},
}, },
gridstack: { gridstack: {
minWidth: 2, minWidth: 2,
@@ -148,6 +153,9 @@ function TorrentTile({ widget }: TorrentTileProps) {
const duration = dayjs.duration(difference, 'ms'); const duration = dayjs.duration(difference, 'ms');
const humanizedDuration = duration.humanize(); const humanizedDuration = duration.humanize();
const ratioGlobal = getTorrentsRatio(widget, torrents, false);
const ratioWithFilter = getTorrentsRatio(widget, torrents, true);
return ( return (
<Flex direction="column" sx={{ height: '100%' }} ref={ref}> <Flex direction="column" sx={{ height: '100%' }} ref={ref}>
<ScrollArea sx={{ height: '100%', width: '100%' }} mb="xs"> <ScrollArea sx={{ height: '100%', width: '100%' }} mb="xs">
@@ -193,6 +201,13 @@ function TorrentTile({ widget }: TorrentTileProps) {
<Text color="dimmed" size="xs"> <Text color="dimmed" size="xs">
{t('card.footer.lastUpdated', { time: humanizedDuration })} {t('card.footer.lastUpdated', { time: humanizedDuration })}
{` - ${t('card.footer.ratioGlobal')} : ${
ratioGlobal === -1 ? '∞' : ratioGlobal.toFixed(2)
}`}
{widget.properties.displayRatioWithFilter &&
` - ${t('card.footer.ratioWithFilter')} : ${
ratioWithFilter === -1 ? '∞' : ratioWithFilter.toFixed(2)
}`}
</Text> </Text>
</Group> </Group>
</Flex> </Flex>
@@ -238,4 +253,30 @@ const filterTorrentsByLabels = (
return torrents.filter((torrent) => !labels.includes(torrent.label as string)); return torrents.filter((torrent) => !labels.includes(torrent.label as string));
}; };
export const getTorrentsRatio = (
widget: ITorrent,
torrents: NormalizedTorrent[],
applyAllFilter: boolean
) => {
if (applyAllFilter) {
torrents = filterTorrents(widget, torrents);
} else if (widget.properties.labelFilter.length > 0) {
torrents = filterTorrentsByLabels(
torrents,
widget.properties.labelFilter,
widget.properties.labelFilterIsWhitelist
);
}
let totalDownloadedSum = torrents.reduce(
(sum, torrent) => sum + torrent.totalDownloaded,
0
);
return totalDownloadedSum > 0
? torrents.reduce((sum, torrent) => sum + torrent.totalUploaded, 0) /
totalDownloadedSum
: -1;
};
export default definition; export default definition;