forked from glblduh/torrenttp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathengine.go
143 lines (119 loc) · 3.71 KB
/
engine.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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/* Contains functions for manipulating the BitTorrent client */
package main
import (
"errors"
"os"
"path/filepath"
"time"
"github.com/anacrolix/torrent"
"github.com/anacrolix/torrent/metainfo"
"github.com/dustin/go-humanize"
)
// Creates the BitTorrent client
func (Engine *btEng) initialize(opts *torrent.ClientConfig) {
// Saves the given config to the Engine
Engine.ClientConfig = opts
/* Make client with confs */
var err error
Engine.Client, err = torrent.NewClient(Engine.ClientConfig)
if err != nil {
Error.Fatalf("Cannot initialize BitTorrent client: %s", err)
}
/* Outputs the download directory and upload status */
Info.Printf("Download directory is on: %s\n", Engine.ClientConfig.DataDir)
if Engine.ClientConfig.NoUpload {
Warn.Println("Upload is disabled")
}
/* Initialize custom torrent map and speed calculator */
Engine.Torrents = make(map[string]*torrentHandle)
go btEngine.calculateSpeeds()
}
// Add torrent to client
func (Engine *btEng) addTorrent(spec *torrent.TorrentSpec, noSave bool) (*torrent.Torrent, error) {
/* Adds spec to BitTorrent client */
t, new, err := Engine.Client.AddTorrentSpec(spec)
if err != nil {
return nil, err
}
/* Check if torrent is new then save its spec for persistence */
if new && !noSave {
sserr := saveSpec(spec)
if sserr != nil {
return nil, sserr
}
}
// Wait for torrent info
<-t.GotInfo()
// Adds spec to custom torrent handler
Engine.addTorrentHandle(t, spec)
return t, nil
}
// Get *torrent.Torrent from infohash
func (Engine *btEng) getTorrHandle(infohash string) (*torrent.Torrent, error) {
/* Checks if infohash is 40 characters */
if len(infohash) != 40 {
return nil, errors.New("Invalid infohash")
}
/* Get torrent handle */
t, ok := Engine.Client.Torrent(metainfo.NewHashFromHex(infohash))
if !ok {
return nil, errors.New("Torrent not found")
}
return t, nil
}
// Removes torrent from BitTorrent client and removes it's persistence spec
func (Engine *btEng) dropTorrent(infohash string, rmfiles bool) error {
/* Get torrent handle */
t, err := Engine.getTorrHandle(infohash)
if err != nil {
return err
}
/* Remove torrent handles */
Engine.removeTorrentHandle(infohash)
t.Drop()
/* Removes torrent persistence spec */
rmerr := removeSpec(t.InfoHash().String())
if rmerr != nil {
return rmerr
}
/* Removes torrent files */
if rmfiles {
return os.RemoveAll(filepath.Join(Engine.ClientConfig.DataDir, t.Name()))
}
return nil
}
// Adds torrent handle to custom torrent handler
func (Engine *btEng) addTorrentHandle(t *torrent.Torrent, spec *torrent.TorrentSpec) {
Engine.Torrents[t.InfoHash().String()] = &torrentHandle{
Torrent: t,
Spec: spec,
}
}
// Remove torrent handle from custom torrent handle
func (Engine *btEng) removeTorrentHandle(infohash string) {
delete(Engine.Torrents, infohash)
}
func (Engine *btEng) calculateSpeeds() {
torrents := Engine.Torrents
interval := time.Second
for {
for k := range torrents {
/*
Work-around for the oddity cause by atomics
See: https://github.com/anacrolix/torrent/issues/745
*/
curstats := torrents[k].Torrent.Stats()
/* Download speed */
dlcurprog := curstats.BytesRead.Int64()
torrents[k].DlSpeedBytes = (int64(interval) * (dlcurprog - torrents[k].LastDlBytes)) / int64(interval)
torrents[k].LastDlBytes = dlcurprog
torrents[k].DlSpeedReadable = humanize.Bytes(uint64(torrents[k].DlSpeedBytes)) + "/s"
/* Upload speed */
ulcurprog := curstats.BytesWritten.Int64()
torrents[k].UlSpeedBytes = (int64(interval) * (ulcurprog - torrents[k].LastUlBytes)) / int64(interval)
torrents[k].LastUlBytes = ulcurprog
torrents[k].UlSpeedReadable = humanize.Bytes(uint64(torrents[k].UlSpeedBytes)) + "/s"
}
time.Sleep(interval)
}
}