From fa511154e432576c484c9ca4bbdc21b6f9c5a781 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Mon, 4 Apr 2016 13:48:39 +1000 Subject: [PATCH] Move Magnet and friends into metainfo package --- client.go | 2 +- cmd/torrent-magnet/main.go | 14 +++----- metainfo/hash.go | 18 ++++++++++ magnet.go => metainfo/magnet.go | 26 +++----------- magnet_test.go => metainfo/magnet_test.go | 21 +++++------ metainfo/metainfo.go | 44 ++++++----------------- metainfo/piece.go | 24 +++++++++++++ util/dirwatch/dirwatch.go | 3 +- 8 files changed, 72 insertions(+), 80 deletions(-) create mode 100644 metainfo/hash.go rename magnet.go => metainfo/magnet.go (76%) rename magnet_test.go => metainfo/magnet_test.go (87%) create mode 100644 metainfo/piece.go diff --git a/client.go b/client.go index ee46ab20..66b2d81e 100644 --- a/client.go +++ b/client.go @@ -1889,7 +1889,7 @@ type TorrentSpec struct { } func TorrentSpecFromMagnetURI(uri string) (spec *TorrentSpec, err error) { - m, err := ParseMagnetURI(uri) + m, err := metainfo.ParseMagnetURI(uri) if err != nil { return } diff --git a/cmd/torrent-magnet/main.go b/cmd/torrent-magnet/main.go index a68cb888..18824148 100644 --- a/cmd/torrent-magnet/main.go +++ b/cmd/torrent-magnet/main.go @@ -1,26 +1,22 @@ package main import ( - "flag" "fmt" "os" - "github.com/anacrolix/torrent" + "github.com/anacrolix/tagflag" + "github.com/anacrolix/torrent/metainfo" ) func main() { - flag.Parse() - if flag.NArg() != 0 { - fmt.Fprintf(os.Stderr, "%s\n", "torrent-magnet: unexpected positional arguments") - os.Exit(2) - } + tagflag.Parse(nil) + mi, err := metainfo.Load(os.Stdin) if err != nil { fmt.Fprintf(os.Stderr, "error reading metainfo from stdin: %s", err) os.Exit(1) } - magnet := torrent.Magnetize(mi) - fmt.Fprintf(os.Stdout, "%s\n", magnet.String()) + fmt.Fprintf(os.Stdout, "%s\n", mi.Magnet().String()) } diff --git a/metainfo/hash.go b/metainfo/hash.go new file mode 100644 index 00000000..08c8e9e9 --- /dev/null +++ b/metainfo/hash.go @@ -0,0 +1,18 @@ +package metainfo + +import "fmt" + +// 20-byte SHA1 hash used for info and pieces. +type Hash [20]byte + +func (me Hash) Bytes() []byte { + return me[:] +} + +func (ih *Hash) AsString() string { + return string(ih[:]) +} + +func (ih Hash) HexString() string { + return fmt.Sprintf("%x", ih[:]) +} diff --git a/magnet.go b/metainfo/magnet.go similarity index 76% rename from magnet.go rename to metainfo/magnet.go index e7653625..2d99ccca 100644 --- a/magnet.go +++ b/metainfo/magnet.go @@ -1,4 +1,4 @@ -package torrent +package metainfo import ( "encoding/base32" @@ -6,20 +6,18 @@ import ( "fmt" "net/url" "strings" - - "github.com/anacrolix/torrent/metainfo" ) -// Magnet +// Magnet link components. type Magnet struct { - InfoHash [20]byte + InfoHash Hash Trackers []string DisplayName string } const xtPrefix = "urn:btih:" -func (m *Magnet) String() 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=" @@ -33,22 +31,6 @@ func (m *Magnet) String() string { 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 func ParseMagnetURI(uri string) (m Magnet, err error) { u, err := url.Parse(uri) diff --git a/magnet_test.go b/metainfo/magnet_test.go similarity index 87% rename from magnet_test.go rename to metainfo/magnet_test.go index 4099c229..065b662f 100644 --- a/magnet_test.go +++ b/metainfo/magnet_test.go @@ -1,11 +1,12 @@ -package torrent +package metainfo import ( "encoding/hex" "reflect" "testing" - "github.com/anacrolix/torrent/metainfo" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var ( @@ -70,23 +71,19 @@ 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) - } + mi, err := LoadFromFile("../testdata/bootstrap.dat.torrent") + require.NoError(t, err) - magnet := Magnetize(mi) + m := mi.Magnet() - if magnet.DisplayName != "bootstrap.dat" { - t.Errorf("Magnet Dispalyname is incorrect: %s", magnet.DisplayName) - } + assert.EqualValues(t, "bootstrap.dat", m.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 { + if m.InfoHash != ih { t.Errorf("Magnet infohash is incorrect") } @@ -100,7 +97,7 @@ func Test_Magnetize(t *testing.T) { } for _, expected := range trackers { - if !contains(magnet.Trackers, expected) { + if !contains(m.Trackers, expected) { t.Errorf("Magnet does not contain expected tracker: %s", expected) } } diff --git a/metainfo/metainfo.go b/metainfo/metainfo.go index bbe8652d..fbae39d1 100644 --- a/metainfo/metainfo.go +++ b/metainfo/metainfo.go @@ -156,27 +156,6 @@ func (me *Info) NumPieces() int { return len(me.Pieces) / 20 } -type Piece struct { - Info *InfoEx - i int -} - -func (me Piece) Length() int64 { - if me.i == me.Info.NumPieces()-1 { - return me.Info.TotalLength() - int64(me.i)*me.Info.PieceLength - } - return me.Info.PieceLength -} - -func (me Piece) Offset() int64 { - return int64(me.i) * me.Info.PieceLength -} - -func (me Piece) Hash() (ret Hash) { - missinggo.CopyExact(&ret, me.Info.Pieces[me.i*20:(me.i+1)*20]) - return -} - func (me *InfoEx) Piece(i int) Piece { return Piece{me, i} } @@ -257,17 +236,14 @@ func (mi *MetaInfo) SetDefaults() { mi.Info.PieceLength = 256 * 1024 } -// 20-byte SHA1 hash used for info and pieces. -type Hash [20]byte - -func (me Hash) Bytes() []byte { - return me[:] -} - -func (ih *Hash) AsString() string { - return string(ih[:]) -} - -func (ih Hash) HexString() string { - return fmt.Sprintf("%x", ih[:]) +// Magnetize creates a Magnet from a MetaInfo +func (mi *MetaInfo) Magnet() (m Magnet) { + for _, tier := range mi.AnnounceList { + for _, tracker := range tier { + m.Trackers = append(m.Trackers, tracker) + } + } + m.DisplayName = mi.Info.Name + m.InfoHash = *mi.Info.Hash + return } diff --git a/metainfo/piece.go b/metainfo/piece.go new file mode 100644 index 00000000..a3b7683c --- /dev/null +++ b/metainfo/piece.go @@ -0,0 +1,24 @@ +package metainfo + +import "github.com/anacrolix/missinggo" + +type Piece struct { + Info *InfoEx + i int +} + +func (me Piece) Length() int64 { + if me.i == me.Info.NumPieces()-1 { + return me.Info.TotalLength() - int64(me.i)*me.Info.PieceLength + } + return me.Info.PieceLength +} + +func (me Piece) Offset() int64 { + return int64(me.i) * me.Info.PieceLength +} + +func (me Piece) Hash() (ret Hash) { + missinggo.CopyExact(&ret, me.Info.Pieces[me.i*20:(me.i+1)*20]) + return +} diff --git a/util/dirwatch/dirwatch.go b/util/dirwatch/dirwatch.go index fa0edc3c..b4152294 100644 --- a/util/dirwatch/dirwatch.go +++ b/util/dirwatch/dirwatch.go @@ -12,7 +12,6 @@ import ( "github.com/anacrolix/missinggo" "github.com/go-fsnotify/fsnotify" - "github.com/anacrolix/torrent" "github.com/anacrolix/torrent/metainfo" ) @@ -117,7 +116,7 @@ func scanDir(dirName string) (ee map[metainfo.Hash]entity) { break } for _, uri := range uris { - m, err := torrent.ParseMagnetURI(uri) + m, err := metainfo.ParseMagnetURI(uri) if err != nil { log.Printf("error parsing %q in file %q: %s", uri, fullName, err) continue