]> Sergey Matveev's repositories - btrtrc.git/commitdiff
AddTorrentSpec now merges in new information an existing torrent didn't have
authorMatt Joiner <anacrolix@gmail.com>
Fri, 27 Mar 2015 15:50:55 +0000 (02:50 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Fri, 27 Mar 2015 15:50:55 +0000 (02:50 +1100)
client.go
client_test.go

index 30e6aa30c6317527d38339a683d9218fd0b7c8f7..8b21c44ce66d5a917888794bb6f5197bffda315f 100644 (file)
--- a/client.go
+++ b/client.go
@@ -2258,59 +2258,69 @@ func TorrentSpecFromMetaInfo(mi *metainfo.MetaInfo) (spec *TorrentSpec) {
        return
 }
 
+// Add or merge a torrent spec. If the torrent is already present, the
+// trackers will be merged with the existing ones. If the Info isn't yet
+// known, it will be set. The display name is replaced if the new spec
+// provides one. Returns new if the torrent wasn't already in the client.
 func (cl *Client) AddTorrentSpec(spec *TorrentSpec) (T Torrent, new bool, err error) {
        T.cl = cl
        cl.mu.Lock()
        defer cl.mu.Unlock()
 
        t, ok := cl.torrents[spec.InfoHash]
-       if ok {
-               T.torrent = t
-               return
-       }
-
-       new = true
+       if !ok {
+               new = true
 
-       if _, ok := cl.bannedTorrents[spec.InfoHash]; ok {
-               err = errors.New("banned torrent")
-               return
-       }
+               if _, ok := cl.bannedTorrents[spec.InfoHash]; ok {
+                       err = errors.New("banned torrent")
+                       return
+               }
 
-       t, err = newTorrent(spec.InfoHash)
-       if err != nil {
-               return
+               t, err = newTorrent(spec.InfoHash)
+               if err != nil {
+                       return
+               }
        }
        if spec.DisplayName != "" {
                t.DisplayName = spec.DisplayName
        }
-       if spec.Info != nil {
-               err = cl.setMetaData(t, &spec.Info.Info, spec.Info.Bytes)
-       } else {
-               var mi *metainfo.MetaInfo
-               mi, err = cl.torrentCacheMetaInfo(spec.InfoHash)
-               if err != nil {
-                       log.Printf("error getting cached metainfo: %s", err)
-               } else if mi != nil {
-                       t.addTrackers(mi.AnnounceList)
-                       err = cl.setMetaData(t, &mi.Info.Info, mi.Info.Bytes)
+       // Try to merge in info we have on the torrent. Any err left will
+       // terminate the function.
+       if t.Info == nil {
+               if spec.Info != nil {
+                       err = cl.setMetaData(t, &spec.Info.Info, spec.Info.Bytes)
+               } else {
+                       var mi *metainfo.MetaInfo
+                       mi, err = cl.torrentCacheMetaInfo(spec.InfoHash)
+                       if err != nil {
+                               log.Printf("error getting cached metainfo: %s", err)
+                               err = nil
+                       } else if mi != nil {
+                               t.addTrackers(mi.AnnounceList)
+                               err = cl.setMetaData(t, &mi.Info.Info, mi.Info.Bytes)
+                       }
                }
        }
        if err != nil {
                return
        }
+       t.addTrackers(spec.Trackers)
 
        cl.torrents[spec.InfoHash] = t
        T.torrent = t
 
-       T.torrent.pruneTimer = time.AfterFunc(0, func() {
-               cl.pruneConnectionsUnlocked(T.torrent)
-       })
-       t.addTrackers(spec.Trackers)
-       if !cl.disableTrackers {
-               go cl.announceTorrentTrackers(T.torrent)
-       }
-       if cl.dHT != nil {
-               go cl.announceTorrentDHT(T.torrent, true)
+       // From this point onwards, we can consider the torrent a part of the
+       // client.
+       if new {
+               t.pruneTimer = time.AfterFunc(0, func() {
+                       cl.pruneConnectionsUnlocked(T.torrent)
+               })
+               if !cl.disableTrackers {
+                       go cl.announceTorrentTrackers(T.torrent)
+               }
+               if cl.dHT != nil {
+                       go cl.announceTorrentDHT(T.torrent, true)
+               }
        }
        return
 }
index 447d941487449edb28393cf338b3dcdf842e71f7..08dbc80cd8b655647a35be4fbf58ec1e1b481ebc 100644 (file)
@@ -14,6 +14,7 @@ import (
        "github.com/anacrolix/libtorgo/bencode"
        "github.com/anacrolix/utp"
        "github.com/bradfitz/iter"
+       "gopkg.in/check.v1"
 
        "github.com/anacrolix/torrent/data/blob"
        "github.com/anacrolix/torrent/internal/testutil"
@@ -299,3 +300,20 @@ func TestReadaheadPieces(t *testing.T) {
                }
        }
 }
+
+func (suite) TestMergingTrackersByAddingSpecs(c *check.C) {
+       cl, _ := NewClient(&TestingConfig)
+       defer cl.Close()
+       spec := TorrentSpec{}
+       T, new, _ := cl.AddTorrentSpec(&spec)
+       if !new {
+               c.FailNow()
+       }
+       spec.Trackers = [][]string{{"http://a"}, {"udp://b"}}
+       _, new, _ = cl.AddTorrentSpec(&spec)
+       if new {
+               c.FailNow()
+       }
+       c.Assert(T.Trackers[0][0].URL(), check.Equals, "http://a")
+       c.Assert(T.Trackers[1][0].URL(), check.Equals, "udp://b")
+}