}
func TorrentSpecFromMagnetURI(uri string) (spec *TorrentSpec, err error) {
- m, err := ParseMagnetURI(uri)
+ m, err := metainfo.ParseMagnetURI(uri)
if err != nil {
return
}
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())
}
--- /dev/null
+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[:])
+}
-package torrent
+package metainfo
import (
"encoding/base32"
"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="
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)
-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 (
}
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")
}
}
for _, expected := range trackers {
- if !contains(magnet.Trackers, expected) {
+ if !contains(m.Trackers, expected) {
t.Errorf("Magnet does not contain expected tracker: %s", expected)
}
}
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}
}
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
}
--- /dev/null
+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
+}
"github.com/anacrolix/missinggo"
"github.com/go-fsnotify/fsnotify"
- "github.com/anacrolix/torrent"
"github.com/anacrolix/torrent/metainfo"
)
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