]> Sergey Matveev's repositories - btrtrc.git/blob - cmd/tracker-announce/main.go
More sortimports
[btrtrc.git] / cmd / tracker-announce / main.go
1 package main
2
3 import (
4         "log"
5         "math"
6         "net/url"
7         "strings"
8         "sync"
9
10         "github.com/anacrolix/tagflag"
11         "github.com/davecgh/go-spew/spew"
12
13         "github.com/anacrolix/torrent"
14         "github.com/anacrolix/torrent/metainfo"
15         "github.com/anacrolix/torrent/tracker"
16 )
17
18 func argSpec(arg string) (ts *torrent.TorrentSpec, err error) {
19         if strings.HasPrefix(arg, "magnet:") {
20                 return torrent.TorrentSpecFromMagnetURI(arg)
21         }
22         mi, err := metainfo.LoadFromFile(arg)
23         if err != nil {
24                 return
25         }
26         ts = torrent.TorrentSpecFromMetaInfo(mi)
27         return
28 }
29
30 func main() {
31         flags := struct {
32                 tagflag.StartPos
33                 Torrents []string `arity:"+"`
34         }{}
35         tagflag.Parse(&flags)
36         ar := tracker.AnnounceRequest{
37                 NumWant: -1,
38                 Left:    math.MaxUint64,
39         }
40         var wg sync.WaitGroup
41         for _, arg := range flags.Torrents {
42                 ts, err := argSpec(arg)
43                 if err != nil {
44                         log.Fatal(err)
45                 }
46                 ar.InfoHash = ts.InfoHash
47                 for _, tier := range ts.Trackers {
48                         for _, tURI := range tier {
49                                 wg.Add(1)
50                                 go doTracker(tURI, wg.Done)
51                         }
52                 }
53         }
54         wg.Wait()
55 }
56
57 func doTracker(tURI string, done func()) {
58         defer done()
59         for _, res := range announces(tURI) {
60                 err := res.error
61                 resp := res.AnnounceResponse
62                 if err != nil {
63                         log.Printf("error announcing to %q: %s", tURI, err)
64                         continue
65                 }
66                 log.Printf("tracker response from %q: %s", tURI, spew.Sdump(resp))
67         }
68 }
69
70 type announceResult struct {
71         tracker.AnnounceResponse
72         error
73 }
74
75 func announces(uri string) (ret []announceResult) {
76         u, err := url.Parse(uri)
77         if err != nil {
78                 return []announceResult{{error: err}}
79         }
80         a := tracker.Announce{
81                 TrackerUrl: uri,
82         }
83         if u.Scheme == "udp" {
84                 a.UdpNetwork = "udp4"
85                 ret = append(ret, announce(a))
86                 a.UdpNetwork = "udp6"
87                 ret = append(ret, announce(a))
88                 return
89         }
90         return []announceResult{announce(a)}
91 }
92
93 func announce(a tracker.Announce) announceResult {
94         resp, err := a.Do()
95         return announceResult{resp, err}
96 }