/**
* Here we distinguish between the torrent states offered by transmission
* and the torrent *classes* offered by puddle. The classes here are used by
* puddle to filter torrents, the states in {@code TransmissionTorrentStates}
* just indicate what a given torrent is doing at some point in time.
*
*/
import { Torrent } from './torrent';
import {
TransmissionTorrentStatus as TorrentStatus
} from '@transmission';
import { Predicate } from '@client/utils/types';
export enum TorrentClasses {
ALL = 0b0000001,
DOWNLOADING = 0b0000010,
COMPLETE = 0b0000100,
STOPPED = 0b0001000,
ACTIVE = 0b0010000,
INACTIVE = 0b0100000,
ERROR = 0b1000000,
}
// can't enumerate enums, so store copy of flag values here :sad:.
export const TorrentClassFlags =
Object.values(TorrentClasses)
.filter(i => !isNaN(i as number)) as Array<TorrentClasses>
// Mappings from known torrent states to checkers.
const classMatchers: { [key in TorrentClasses]: Predicate<Torrent> } = {
[TorrentClasses.ALL]: () => true,
[TorrentClasses.DOWNLOADING]: (torrent) => {
// NOTE we may be able to optimize this sort of status check
// by converting transmission torrent states to flags.
return [TorrentStatus.DOWNLOAD_WAIT,
TorrentStatus.DOWNLOAD].includes(torrent.status)
},
[TorrentClasses.COMPLETE]: (torrent) => torrent.percentDone === 1,
[TorrentClasses.STOPPED]: (torrent) =>
TorrentStatus.STOPPED === torrent.status,
[TorrentClasses.ACTIVE]: (torrent) => {
return [TorrentStatus.CHECK,
TorrentStatus.DOWNLOAD,
TorrentStatus.SEED].includes(torrent.status)
},
[TorrentClasses.INACTIVE]: (torrent) => {
return [TorrentStatus.STOPPED,
TorrentStatus.CHECK_WAIT,
TorrentStatus.DOWNLOAD_WAIT,
TorrentStatus.SEED_WAIT].includes(torrent.status)
},
[TorrentClasses.ERROR]: (torrent) => torrent.error !== 0
}
/**
* Given a torrent, return a number indicating the subset
* of supported torrent classes the torrent has.
*/
export function torrentClass(torrent: Torrent): number {
return TorrentClassFlags.reduce((acc, flag) => {
if (classMatchers[flag](torrent)) {
acc |= flag
}
return acc
}, 0);
}