forked from boypt/simple-torrent
/
torrent.go
122 lines (106 loc) · 2.61 KB
/
torrent.go
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
package engine
import (
"time"
"github.com/anacrolix/torrent"
)
type Torrent struct {
//anacrolix/torrent
InfoHash string
Name string
Magnet string
Loaded bool
Downloaded int64
Uploaded int64
Size int64
Files []*File
//cloud torrent
Started bool
Done bool
DoneCmdCalled bool
Percent float32
DownloadRate float32
UploadRate float32
SeedRatio float32
AddedAt time.Time
StartedAt time.Time
Stats torrent.TorrentStats
t *torrent.Torrent
dropWait chan struct{}
updatedAt time.Time
}
type File struct {
//anacrolix/torrent
Path string
Size int64
Completed int64
Done bool
DoneCmdCalled bool
//cloud torrent
Started bool
Percent float32
f *torrent.File
}
// Update retrive info from torrent.Torrent
func (torrent *Torrent) Update(t *torrent.Torrent) {
torrent.Name = t.Name()
if t.Info() != nil {
torrent.Loaded = true
torrent.updateLoaded(t)
}
if torrent.Magnet == "" {
meta := t.Metainfo()
m := meta.Magnet(t.Name(), t.InfoHash())
torrent.Magnet = m.String()
}
torrent.t = t
}
func (torrent *Torrent) updateLoaded(t *torrent.Torrent) {
torrent.Size = t.Length()
tfiles := t.Files()
if len(tfiles) > 0 && torrent.Files == nil {
torrent.Files = make([]*File, len(tfiles))
}
//merge in files
for i, f := range tfiles {
path := f.Path()
file := torrent.Files[i]
if file == nil {
file = &File{Path: path, Started: torrent.Started}
torrent.Files[i] = file
}
file.Size = f.Length()
file.Completed = f.BytesCompleted()
file.Percent = percent(file.Completed, file.Size)
file.Done = (file.Completed == file.Size)
file.f = f
}
torrent.Stats = t.Stats()
now := time.Now()
bytes := t.BytesCompleted()
ulbytes := torrent.Stats.BytesWrittenData.Int64()
// calculate rate
if !torrent.updatedAt.IsZero() {
dtinv := float32(time.Second) / float32(now.Sub(torrent.updatedAt))
dldb := float32(bytes - torrent.Downloaded)
torrent.DownloadRate = dldb * dtinv
uldb := float32(ulbytes - torrent.Uploaded)
torrent.UploadRate = uldb * dtinv
}
torrent.Downloaded = bytes
torrent.Uploaded = ulbytes
torrent.updatedAt = now
torrent.Percent = percent(bytes, torrent.Size)
torrent.Done = (bytes == torrent.Size)
// calculate ratio
bRead := torrent.Stats.BytesReadData.Int64()
bWrite := torrent.Stats.BytesWritten.Int64()
if bRead > 0 {
torrent.SeedRatio = float32(bWrite) / float32(bRead)
}
}
func percent(n, total int64) float32 {
if total == 0 {
return float32(0)
}
return float32(int(float64(10000)*(float64(n)/float64(total)))) / 100
}