]> Sergey Matveev's repositories - btrtrc.git/blobdiff - spec.go
Drop support for go 1.20
[btrtrc.git] / spec.go
diff --git a/spec.go b/spec.go
index b5007c2612cc8619c9d47d0257ddd8d74793d66d..8cce3cb326f1ff3594b921338804f381d5a7e7cd 100644 (file)
--- a/spec.go
+++ b/spec.go
@@ -1,35 +1,47 @@
 package torrent
 
 import (
+       "fmt"
+
        "github.com/anacrolix/torrent/metainfo"
+       pp "github.com/anacrolix/torrent/peer_protocol"
        "github.com/anacrolix/torrent/storage"
 )
 
-// Specifies a new torrent for adding to a client. There are helpers for magnet URIs and torrent
-// metainfo files.
+// Specifies a new torrent for adding to a client, or additions to an existing Torrent. There are
+// constructor functions for magnet URIs and torrent metainfo files. TODO: This type should be
+// dismantled into a new Torrent option type, and separate Torrent mutate method(s).
 type TorrentSpec struct {
        // The tiered tracker URIs.
-       Trackers  [][]string
+       Trackers [][]string
+       // TODO: Move into a "new" Torrent opt type.
        InfoHash  metainfo.Hash
        InfoBytes []byte
        // The name to use if the Name field from the Info isn't available.
        DisplayName string
-       Webseeds    []string
-       DhtNodes    []string
+       // WebSeed URLs. For additional options add the URLs separately with Torrent.AddWebSeeds
+       // instead.
+       Webseeds  []string
+       DhtNodes  []string
+       PeerAddrs []string
        // The combination of the "xs" and "as" fields in magnet links, for now.
        Sources []string
 
-       // The chunk size to use for outbound requests. Defaults to 16KiB if not set.
-       ChunkSize int
-       Storage   storage.ClientImpl
+       // The chunk size to use for outbound requests. Defaults to 16KiB if not set. Can only be set
+       // for new Torrents. TODO: Move into a "new" Torrent opt type.
+       ChunkSize pp.Integer
+       // TODO: Move into a "new" Torrent opt type.
+       Storage storage.ClientImpl
+
+       DisableInitialPieceCheck bool
 
        // Whether to allow data download or upload
        DisallowDataUpload   bool
        DisallowDataDownload bool
 }
 
-func TorrentSpecFromMagnetURI(uri string) (spec *TorrentSpec, err error) {
-       m, err := metainfo.ParseMagnetURI(uri)
+func TorrentSpecFromMagnetUri(uri string) (spec *TorrentSpec, err error) {
+       m, err := metainfo.ParseMagnetUri(uri)
        if err != nil {
                return
        }
@@ -39,15 +51,18 @@ func TorrentSpecFromMagnetURI(uri string) (spec *TorrentSpec, err error) {
                InfoHash:    m.InfoHash,
                Webseeds:    m.Params["ws"],
                Sources:     append(m.Params["xs"], m.Params["as"]...),
-               // TODO: What's the parameter for DHT nodes or bootstrap peers in a magnet link?
+               PeerAddrs:   m.Params["x.pe"], // BEP 9
+               // TODO: What's the parameter for DHT nodes?
        }
        return
 }
 
-func TorrentSpecFromMetaInfo(mi *metainfo.MetaInfo) *TorrentSpec {
+// The error will be from unmarshalling the info bytes. The TorrentSpec is still filled out as much
+// as possible in this case.
+func TorrentSpecFromMetaInfoErr(mi *metainfo.MetaInfo) (*TorrentSpec, error) {
        info, err := mi.UnmarshalInfo()
        if err != nil {
-               panic(err)
+               err = fmt.Errorf("unmarshalling info: %w", err)
        }
        return &TorrentSpec{
                Trackers:    mi.UpvertedAnnounceList(),
@@ -56,11 +71,20 @@ func TorrentSpecFromMetaInfo(mi *metainfo.MetaInfo) *TorrentSpec {
                DisplayName: info.Name,
                Webseeds:    mi.UrlList,
                DhtNodes: func() (ret []string) {
-                       ret = make([]string, len(mi.Nodes))
+                       ret = make([]string, 0, len(mi.Nodes))
                        for _, node := range mi.Nodes {
                                ret = append(ret, string(node))
                        }
                        return
                }(),
+       }, err
+}
+
+// Panics if there was anything missing from the metainfo.
+func TorrentSpecFromMetaInfo(mi *metainfo.MetaInfo) *TorrentSpec {
+       ts, err := TorrentSpecFromMetaInfoErr(mi)
+       if err != nil {
+               panic(err)
        }
+       return ts
 }