]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Use higher-level API to get file
authorAlexander Baranov <scr4t@yandex.ru>
Mon, 1 Jun 2015 19:56:10 +0000 (22:56 +0300)
committerAlexander Baranov <scr4t@yandex.ru>
Mon, 1 Jun 2015 19:56:10 +0000 (22:56 +0300)
client.go
cmd/torrent-pick/main.go

index 9055955f0b279b32c967d539b11e586d397d49ce..62bfb8ee4f0610d7279e86325cee9623a0e54bb0 100644 (file)
--- a/client.go
+++ b/client.go
@@ -23,7 +23,6 @@ import (
        "strings"
        "syscall"
        "time"
-       "math"
 
        "github.com/anacrolix/sync"
        "github.com/anacrolix/utp"
@@ -2017,60 +2016,6 @@ func (t Torrent) DownloadAll() {
        t.cl.raisePiecePriority(t.torrent, t.numPieces()-1, piecePriorityReadahead)
 }
 
-// Marks the entire torrent for download. Requires the info first, see
-// GotInfo.
-func (t Torrent) DownloadFile(Path []string) {
-       t.cl.mu.Lock()
-       defer t.cl.mu.Unlock()
-
-       // log.Printf("File to Download: %s", Path)
-
-       // log.Printf("Pieces: %s", t.torrent.Info.NumPieces())
-       // log.Printf("Length: %s", t.torrent.Info.TotalLength())
-       // log.Printf("Torrent info: %s", t.torrent.Info.UpvertedFiles())
-
-       var offset int64
-       var pickedFile metainfo.FileInfo
-
-       found := false
-       pathStr := strings.Join(Path, "")
-
-       for _, file := range t.torrent.Info.UpvertedFiles() {
-               if strings.Join(file.Path, "/") ==  pathStr {
-                       log.Printf("Found file: %s", file)
-
-                       found = true
-                       pickedFile = file
-                       break
-               }
-               // log.Printf("%d %d `%s` `%s`", len(file.Path), len(Path), strings.Join(file.Path, "/"), strings.Join(Path, ""))
-               log.Printf("File: %s", strings.Join(file.Path, "/"))
-               offset += file.Length;
-       }
-
-       if !found {
-               panic(fmt.Sprintf("File not found"))
-       }
-
-       log.Printf("Donwloading file: `%s`", Path)
-       log.Printf("Calculated offset: %s", offset)
-       log.Printf("File length: %s", pickedFile.Length)
-       log.Printf("Piece length: %s", t.torrent.Info.PieceLength)
-
-
-       firstChunk := int(offset/t.torrent.Info.PieceLength)
-       nChunks := int(math.Ceil(float64(pickedFile.Length) / float64(t.torrent.Info.PieceLength)))
-
-       log.Printf("First chunk: %s", offset/t.torrent.Info.PieceLength)
-       log.Printf("Number of chunks: %s", nChunks)
-       log.Printf("Total chunks: %s", t.torrent.Info.NumPieces())
-
-
-       for chunk := firstChunk; chunk < firstChunk + nChunks; chunk++ {
-               log.Printf("Piece #%d: %s %s", chunk, t.torrent.Info.Piece(chunk).Length(), t.torrent.Info.Piece(chunk).Offset())
-               t.cl.raisePiecePriority(t.torrent, chunk, piecePriorityNormal)
-       }
-}
 
 
 // Returns nil metainfo if it isn't in the cache. Checks that the retrieved
index e882b62b4b7712156eaeb357e4baf444dbce2513..88e3c32b61f1acefca8caab938cb8c0aa5670985 100644 (file)
@@ -8,8 +8,12 @@ import (
        "net/http"
        _ "net/http/pprof"
        "os"
+       "io"
+       "io/ioutil"
        "strings"
        "time"
+       "bufio"
+
 
        _ "github.com/anacrolix/envpprof"
        "github.com/dustin/go-humanize"
@@ -69,13 +73,18 @@ func progressLine(tc *torrent.Client) string {
        return fmt.Sprintf("\033[K%s / %s\r", humanize.Bytes(uint64(bytesCompleted(tc))), humanize.Bytes(uint64(totalBytesEstimate(tc))))
 }
 
+func dstFileName(picked string) string {
+       parts := strings.Split(picked, "/")
+       return parts[len(parts)-1]
+}
+
 func main() {
        log.SetFlags(log.LstdFlags | log.Lshortfile)
        var rootGroup struct {
                Client    torrent.Config `group:"Client Options"`
                Seed      bool           `long:"seed" description:"continue seeding torrents after completed"`
                TestPeers []string       `long:"test-peer" description:"address of peer to inject to every torrent"`
-               Pick      []string       `long:"pick" description:"filename to pick"`
+               Pick      string         `long:"pick" description:"filename to pick"`
        }
        // Don't pass flags.PrintError because it's inconsistent with printing.
        // https://github.com/jessevdk/go-flags/issues/132
@@ -98,6 +107,16 @@ func main() {
                fmt.Fprintln(os.Stderr, "no torrents specified")
                return
        }
+
+       tmpdir, err := ioutil.TempDir("", "torrent-pick-")
+       if err != nil {
+               log.Fatal(err)
+       }
+
+       defer os.RemoveAll(tmpdir)
+
+       rootGroup.Client.DataDir = tmpdir
+
        client, err := torrent.NewClient(&rootGroup.Client)
        if err != nil {
                log.Fatalf("error creating client: %s", err)
@@ -106,6 +125,17 @@ func main() {
                client.WriteStatus(w)
        })
        defer client.Close()
+
+
+       dstName := dstFileName(rootGroup.Pick)
+
+       f, err := os.Create(dstName)
+       if err != nil {
+               log.Fatal(err)
+       }
+       dstWriter := bufio.NewWriter(f)
+
+
        for _, arg := range posArgs {
                t := func() torrent.Torrent {
                        if strings.HasPrefix(arg, "magnet:") {
@@ -130,11 +160,23 @@ func main() {
                if err != nil {
                        log.Fatal(err)
                }
+
                go func() {
                        <-t.GotInfo()
-                       t.DownloadFile(rootGroup.Pick)
+                       files := t.Files()
+                       for _, file := range files {
+                               if file.Path() ==  rootGroup.Pick {
+
+                                       log.Printf("Downloading file: %s", file.Path())
+
+                                       srcReader := io.NewSectionReader(t.NewReader(), file.Offset(), file.Length())
+                                       io.Copy(dstWriter, srcReader)
+                                       break
+                               }
+                       }
                }()
        }
+
        done := make(chan struct{})
        go func() {
                defer close(done)