client.go | 2 +- cmd/torrent-magnet/main.go | 14 +++++--------- magnet.go => metainfo/magnet.go | 26 ++++---------------------- magnet_test.go => metainfo/magnet_test.go | 21 +++++++++------------ metainfo/hash.go | 18 ++++++++++++++++++ metainfo/metainfo.go | 44 ++++++++++---------------------------------- metainfo/piece.go | 24 ++++++++++++++++++++++++ util/dirwatch/dirwatch.go | 3 +-- diff --git a/client.go b/client.go index ee46ab2095d61dc16596e943b895ac2ad286096b..66b2d81ebcecc0bcdd95c5ca5d4a7d175849f6a3 100644 --- a/client.go +++ b/client.go @@ -1889,7 +1889,7 @@ Storage storage.I } 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 a68cb888ca35144bef1356d299ff3b5b92c3b6b7..18824148ddf6f228104e242f1ac0ec81df73b7cc 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/magnet.go b/metainfo/magnet.go rename from magnet.go rename to metainfo/magnet.go index e7653625bb57e35726ddc1414f3998a593456ba6..2d99cccaebd37592d15f3c07f9b645981268d97a 100644 --- a/magnet.go +++ b/metainfo/magnet.go @@ -1,4 +1,4 @@ -package torrent +package metainfo import ( "encoding/base32" @@ -6,20 +6,18 @@ "encoding/hex" "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=" @@ -31,22 +29,6 @@ for _, tr := range m.Trackers { ret += "&tr=" + url.QueryEscape(tr) } 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/metainfo/magnet_test.go rename from magnet_test.go rename to metainfo/magnet_test.go index 4099c229d179960e5d37beaaf3ad653a5f17faf8..065b662ffe6eb65f56f096f59735ac4872fae18a 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 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 @@ "http://bttracker.crunchbanglinux.org:6969/announce", } 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/hash.go b/metainfo/hash.go new file mode 100644 index 0000000000000000000000000000000000000000..08c8e9e924311a9642446519210c31f5c8eb2ac6 --- /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/metainfo/metainfo.go b/metainfo/metainfo.go index bbe8652d3e1a0474951b9a0b100937b11d6d965c..fbae39d1de03c8b6d6571f5d7ba88662afb74c3b 100644 --- a/metainfo/metainfo.go +++ b/metainfo/metainfo.go @@ -156,27 +156,6 @@ } 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 @@ mi.CreationDate = time.Now().Unix() 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 0000000000000000000000000000000000000000..a3b7683c342a79ff621bbd2d6706c5df9d5d4473 --- /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 fa0edc3c321e74a852fade6a9d4d8c68f2b412c0..b4152294f50b665552b1b3819bbe6a3540ef2382 100644 --- a/util/dirwatch/dirwatch.go +++ b/util/dirwatch/dirwatch.go @@ -12,7 +12,6 @@ "github.com/anacrolix/missinggo" "github.com/go-fsnotify/fsnotify" - "github.com/anacrolix/torrent" "github.com/anacrolix/torrent/metainfo" ) @@ -117,7 +116,7 @@ log.Print(err) 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