From 890658ef937ffaae4122c19177f5b1059319a021 Mon Sep 17 00:00:00 2001 From: Seth Hoenig Date: Sun, 3 Apr 2016 08:51:46 -0500 Subject: [PATCH] convenience function for creating magnets --- cmd/torrent-magnet/main.go | 17 +++----------- magnet.go | 25 +++++++++++++++++--- magnet_test.go | 48 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 17 deletions(-) diff --git a/cmd/torrent-magnet/main.go b/cmd/torrent-magnet/main.go index 68bae968..a68cb888 100644 --- a/cmd/torrent-magnet/main.go +++ b/cmd/torrent-magnet/main.go @@ -20,18 +20,7 @@ func main() { fmt.Fprintf(os.Stderr, "error reading metainfo from stdin: %s", err) os.Exit(1) } - ts := torrent.TorrentSpecFromMetaInfo(mi) - m := torrent.Magnet{ - InfoHash: ts.InfoHash, - Trackers: func() (ret []string) { - for _, tier := range ts.Trackers { - for _, tr := range tier { - ret = append(ret, tr) - } - } - return - }(), - DisplayName: ts.DisplayName, - } - fmt.Fprintf(os.Stdout, "%s\n", m.String()) + + magnet := torrent.Magnetize(mi) + fmt.Fprintf(os.Stdout, "%s\n", magnet.String()) } diff --git a/magnet.go b/magnet.go index b326e1fc..e7653625 100644 --- a/magnet.go +++ b/magnet.go @@ -6,8 +6,11 @@ import ( "fmt" "net/url" "strings" + + "github.com/anacrolix/torrent/metainfo" ) +// Magnet type Magnet struct { InfoHash [20]byte Trackers []string @@ -16,10 +19,10 @@ type Magnet struct { const xtPrefix = "urn:btih:" -func (m *Magnet) String() (ret string) { +func (m *Magnet) String() string { // net.URL likes to assume //, and encodes ':' on us, so we do most of // this manually. - ret = "magnet:?xt=" + ret := "magnet:?xt=" ret += xtPrefix + hex.EncodeToString(m.InfoHash[:]) if m.DisplayName != "" { ret += "&dn=" + url.QueryEscape(m.DisplayName) @@ -27,7 +30,23 @@ func (m *Magnet) String() (ret string) { for _, tr := range m.Trackers { ret += "&tr=" + url.QueryEscape(tr) } - return + return ret +} + +// Magnetize creates a Magnet from a MetaInfo +func Magnetize(mi *metainfo.MetaInfo) Magnet { + ts := TorrentSpecFromMetaInfo(mi) + trackers := []string{} + for _, tier := range ts.Trackers { + for _, tracker := range tier { + trackers = append(trackers, tracker) + } + } + return Magnet{ + InfoHash: ts.InfoHash, + Trackers: trackers, + DisplayName: ts.DisplayName, + } } // ParseMagnetURI parses Magnet-formatted URIs into a Magnet instance diff --git a/magnet_test.go b/magnet_test.go index 52a3abbf..4099c229 100644 --- a/magnet_test.go +++ b/magnet_test.go @@ -4,6 +4,8 @@ import ( "encoding/hex" "reflect" "testing" + + "github.com/anacrolix/torrent/metainfo" ) var ( @@ -66,3 +68,49 @@ func TestParseMagnetURI(t *testing.T) { } } + +func Test_Magnetize(t *testing.T) { + mi, err := metainfo.LoadFromFile("testdata/bootstrap.dat.torrent") + if err != nil { + t.Errorf("Failed to load testdata torrent: %v", err) + } + + magnet := Magnetize(mi) + + if magnet.DisplayName != "bootstrap.dat" { + t.Errorf("Magnet Dispalyname is incorrect: %s", magnet.DisplayName) + } + + ih := [20]byte{ + 54, 113, 155, 162, 206, 207, 159, 59, 215, 197, + 171, 251, 122, 136, 233, 57, 97, 27, 83, 108, + } + + if magnet.InfoHash != ih { + t.Errorf("Magnet infohash is incorrect") + } + + trackers := []string{ + "udp://tracker.openbittorrent.com:80", + "udp://tracker.openbittorrent.com:80", + "udp://tracker.publicbt.com:80", + "udp://coppersurfer.tk:6969/announce", + "udp://open.demonii.com:1337", + "http://bttracker.crunchbanglinux.org:6969/announce", + } + + for _, expected := range trackers { + if !contains(magnet.Trackers, expected) { + t.Errorf("Magnet does not contain expected tracker: %s", expected) + } + } +} + +func contains(haystack []string, needle string) bool { + for _, s := range haystack { + if s == needle { + return true + } + } + return false +}