func Example_fileReader() { var ( t torrent.Torrent f torrent.File ) r := t.NewReader() defer r.Close() // Access the parts of the torrent pertaining to f. Data will be // downloaded as required, per the configuration of the torrent.Reader. _ = missinggo.NewSectionReadSeeker(r, f.Offset(), f.Length()) }
func main() { log.SetFlags(log.LstdFlags | log.Lshortfile) var rootGroup struct { Client torrent.Config `group:"Client Options"` TestPeers []string `long:"test-peer" description:"address of peer to inject to every torrent"` 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 parser := flags.NewParser(&rootGroup, flags.HelpFlag|flags.PassDoubleDash) parser.Usage = "[OPTIONS] (magnet URI or .torrent file path)..." posArgs, err := parser.Parse() if err != nil { fmt.Fprintf(os.Stderr, "%s", "Download from the BitTorrent network.\n\n") fmt.Println(err) os.Exit(2) } log.Printf("File to pick: %s", rootGroup.Pick) testPeers, err := resolvedPeerAddrs(rootGroup.TestPeers) if err != nil { log.Fatal(err) } if len(posArgs) == 0 { 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) } http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { 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) done := make(chan struct{}) for _, arg := range posArgs { t := func() *torrent.Torrent { if strings.HasPrefix(arg, "magnet:") { t, err := client.AddMagnet(arg) if err != nil { log.Fatalf("error adding magnet: %s", err) } return t } else { metaInfo, err := metainfo.LoadFromFile(arg) if err != nil { log.Fatal(err) } t, err := client.AddTorrent(metaInfo) if err != nil { log.Fatal(err) } return t } }() t.AddPeers(testPeers) go func() { defer close(done) <-t.GotInfo() for _, file := range t.Files() { if file.DisplayPath() != rootGroup.Pick { continue } srcReader := missinggo.NewSectionReadSeeker(t.NewReader(), file.Offset(), file.Length()) io.Copy(dstWriter, srcReader) return } log.Print("file not found") }() } ticker := time.NewTicker(time.Second) waitDone: for { select { case <-done: break waitDone case <-ticker.C: os.Stdout.WriteString(progressLine(client)) } } if rootGroup.Client.Seed { select {} } }