From: Alexander Baranov Date: Mon, 1 Jun 2015 19:56:10 +0000 (+0300) Subject: Use higher-level API to get file X-Git-Tag: v1.0.0~1163^2^2~3 X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=577b129df540730d6e21c2f77469c3549557abfa;p=btrtrc.git Use higher-level API to get file --- diff --git a/client.go b/client.go index 9055955f..62bfb8ee 100644 --- 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 diff --git a/cmd/torrent-pick/main.go b/cmd/torrent-pick/main.go index e882b62b..88e3c32b 100644 --- a/cmd/torrent-pick/main.go +++ b/cmd/torrent-pick/main.go @@ -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)