import { torrentClass, TorrentClasses } from './classes';
import {
TransmissionTorrent as TorrentResponse,
TransmissionTorrentStatus as TorrentStatus
} from '@transmission/client';
// WARN typescript doesn't have a way to declare the types of
// an interface at compile time and then reference those same
// types at runtime. We're going to have to copy the two here
// and manually keep them in sync.
export const TORRENT_FIELDS: (keyof TorrentResponse)[] = [
"id",
"name",
"status",
"percentDone",
"downloadedEver",
"rateDownload",
"uploadedEver",
"rateUpload",
"eta",
"uploadRatio",
"sizeWhenDone",
"addedDate",
"error",
"trackers",
"queuePosition",
"labels",
"recheckProgress",
"doneDate",
"bandwidthPriority",
"magnetLink",
"downloadDir",
"hashString",
]
/**
* The fields we inherit from the default API response.
*/
type TorrentDefaultFields =
Pick<TorrentResponse, "name" | "status" | "percentDone" |
"downloadedEver" | "rateDownload" | "uploadedEver" | "rateUpload" |
"eta" | "uploadRatio" | "sizeWhenDone" | "addedDate" | "error" |
"trackers" | "queuePosition" | "labels" | "recheckProgress" | "doneDate" |
"bandwidthPriority" | 'magnetLink' | 'downloadDir' | 'hashString' >
/**
* The model for a single torrent.
*
* This extends the fields from a torrent response (see
* {@code TorrentDefaultFields}) with some extra useful
* parameters.
*/
export interface Torrent extends TorrentDefaultFields {
id: number
/**
* A percentage value (between 0 and 1) indicating how much of
* this torrent is completed. When regularly downloading, this
* value will just match percentageComplete. When the torrent
* is checking, it will instead match recheckProgress.
*/
progress: number
classes: number
}
/**
* A base type to supply defaults for the fields in {@code Torrent}
* that aren't in {@code TorrentDefaultFields}.
*/
export const TORRENT_BASE: Partial<Torrent> = {
classes: TorrentClasses.ALL,
}
/**
* Convert an API response that's guaranteed to have the fields in
* {@code TORRENT_FIELDS} to a Torrent instance.
*/
export function torrentFromResponse(resp: Partial<TorrentResponse>, prev?: Torrent) {
const base = prev ? prev! : TORRENT_BASE
const torrent = Object.assign({}, base, resp) as Torrent
torrent.classes = torrentClass(torrent)
if (torrent.status === TorrentStatus.CHECK ||
torrent.status === TorrentStatus.CHECK_WAIT) {
torrent.progress = torrent.recheckProgress
} else {
torrent.progress = torrent.percentDone
}
return torrent
}