/
Torrent.js
130 lines (117 loc) · 3.29 KB
/
Torrent.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
export default class Torrent {
constructor(data) {
this.name = data.name
this.size = data.size
this.added_on = new Date(data.added_on * 1000).toLocaleString()
this.dlspeed = data.dlspeed
this.dloaded = data.completed
this.upspeed = data.upspeed
this.uploaded = data.uploaded
this.uploaded_session = data.uploaded_session
this.eta = this.formatEta(data.eta)
this.num_leechs = data.num_leechs
this.num_seeds = data.num_seeds
this.path = data.path === undefined ? '/downloads' : data.path
this.state = this.formatState(data.state)
this.hash = data.hash
this.available_seeds = data.num_complete
this.available_peers = data.num_incomplete
this.savePath = data.save_path
this.progress = Math.round(data.progress * 10000) / 100
this.ratio = Math.round(data.ratio * 100) / 100
this.tags = data.tags.length > 0 ? data.tags.split(', ').map(t => t.trim()) : null
this.category = data.category
this.tracker = data.tracker
this.f_l_piece_prio = data.f_l_piece_prio
this.seq_dl = data.seq_dl
this.auto_tmm = data.auto_tmm
this.dl_limit = data.dl_limit
this.up_limit = data.up_limit
this.ratio_limit = data.ratio_limit
this.availability = Math.round(data.availability * 100) / 100
this.forced = data.state.includes('forced')
this.magnet = data.magnet_uri
Object.freeze(this)
}
formatState(state) {
switch (state) {
case 'forcedDL':
case 'downloading':
return 'Downloading'
case 'metaDL':
return 'Metadata'
case 'forcedUP':
case 'uploading':
case 'stalledUP':
return 'Seeding'
case 'pausedDL':
return 'Paused'
case 'pausedUP':
return 'Done'
case 'queuedDL':
case 'queuedUP':
return 'Queued'
case 'allocating':
case 'checkingDL':
case 'checkingUP':
case 'checkingResumeData':
return 'Checking'
case 'moving':
return 'Moving'
case 'unknown':
case 'missingFiles':
return 'Fail'
case 'stalledDL':
return 'Stalled'
default:
return 'Fail'
}
}
formatEta(value) {
const options = { dayLimit: 100 }
const minute = 60
const hour = minute * 60
const day = hour * 24
const year = day * 365
const durations = [year, day, hour, minute, 1]
const units = 'ydhms'
let index = 0
let unitSize = 0
const parts = []
const defaultOptions = {
maxUnitSize: 2,
dayLimit: 0,
minUnit: 0
}
const opt = options ?
Object.assign(defaultOptions, options) :
defaultOptions
if (opt.dayLimit && value >= opt.dayLimit * day) {
return '∞'
}
while (
(!opt.maxUnitSize || unitSize !== opt.maxUnitSize) &&
index !== durations.length
) {
const duration = durations[index]
if (value < duration) {
index++
continue
} else if (
opt.minUnit &&
durations.length - index <= opt.minUnit
) {
break
}
const result = Math.floor(value / duration)
parts.push(result + units[index])
value %= duration
index++
unitSize++
}
if (!parts.length) {
return '0' + units[durations.length - 1 - opt.minUnit]
}
return parts.join(' ')
}
}