]> 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 5dbd472bda965b5dbffed780ecefa3a456d13a3a..8cce3cb326f1ff3594b921338804f381d5a7e7cd 100644 (file)
--- a/spec.go
+++ b/spec.go
@@ -1,27 +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
-       // The chunk size to use for outbound requests. Defaults to 16KiB if not
-       // set.
-       ChunkSize int
-       Storage   storage.ClientImpl
+       // 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. 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
        }
@@ -29,20 +49,42 @@ func TorrentSpecFromMagnetURI(uri string) (spec *TorrentSpec, err error) {
                Trackers:    [][]string{m.Trackers},
                DisplayName: m.DisplayName,
                InfoHash:    m.InfoHash,
+               Webseeds:    m.Params["ws"],
+               Sources:     append(m.Params["xs"], m.Params["as"]...),
+               PeerAddrs:   m.Params["x.pe"], // BEP 9
+               // TODO: What's the parameter for DHT nodes?
        }
        return
 }
 
-func TorrentSpecFromMetaInfo(mi *metainfo.MetaInfo) (spec *TorrentSpec) {
-       info, _ := mi.UnmarshalInfo()
-       spec = &TorrentSpec{
-               Trackers:    mi.AnnounceList,
+// 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 {
+               err = fmt.Errorf("unmarshalling info: %w", err)
+       }
+       return &TorrentSpec{
+               Trackers:    mi.UpvertedAnnounceList(),
+               InfoHash:    mi.HashInfoBytes(),
                InfoBytes:   mi.InfoBytes,
                DisplayName: info.Name,
-               InfoHash:    mi.HashInfoBytes(),
-       }
-       if spec.Trackers == nil && mi.Announce != "" {
-               spec.Trackers = [][]string{{mi.Announce}}
+               Webseeds:    mi.UrlList,
+               DhtNodes: func() (ret []string) {
+                       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
+       return ts
 }