github.com/anacrolix/torrent@v1.61.0/cmd/torrent/serve.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "net/http" 6 "path/filepath" 7 8 "github.com/anacrolix/bargle" 9 "github.com/anacrolix/log" 10 11 "github.com/anacrolix/torrent" 12 "github.com/anacrolix/torrent/bencode" 13 "github.com/anacrolix/torrent/metainfo" 14 "github.com/anacrolix/torrent/storage" 15 ) 16 17 func serve() (cmd bargle.Command) { 18 var filePaths []string 19 cmd.Positionals = append(cmd.Positionals, &bargle.Positional{ 20 Value: bargle.AutoUnmarshaler(&filePaths), 21 }) 22 cmd.Desc = "creates and seeds a torrent from a filepath" 23 cmd.DefaultAction = func() error { 24 cfg := torrent.NewDefaultClientConfig() 25 cfg.Seed = true 26 cl, err := torrent.NewClient(cfg) 27 if err != nil { 28 return fmt.Errorf("new torrent client: %w", err) 29 } 30 defer cl.Close() 31 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 32 cl.WriteStatus(w) 33 }) 34 for _, filePath := range filePaths { 35 totalLength, err := totalLength(filePath) 36 if err != nil { 37 return fmt.Errorf("calculating total length of %q: %v", filePath, err) 38 } 39 pieceLength := metainfo.ChoosePieceLength(totalLength) 40 info := metainfo.Info{ 41 PieceLength: pieceLength, 42 } 43 err = info.BuildFromFilePath(filePath) 44 if err != nil { 45 return fmt.Errorf("building info from path %q: %w", filePath, err) 46 } 47 for _, fi := range info.UpvertedFiles() { 48 log.Printf("added %q", fi.BestPath()) 49 } 50 mi := metainfo.MetaInfo{ 51 InfoBytes: bencode.MustMarshal(info), 52 } 53 pc, err := storage.NewDefaultPieceCompletionForDir(".") 54 if err != nil { 55 return fmt.Errorf("new piece completion: %w", err) 56 } 57 defer pc.Close() 58 ih := mi.HashInfoBytes() 59 to, _ := cl.AddTorrentOpt(torrent.AddTorrentOpts{ 60 InfoHash: ih, 61 Storage: storage.NewFileOpts(storage.NewFileClientOpts{ 62 ClientBaseDir: filePath, 63 FilePathMaker: func(opts storage.FilePathMakerOpts) string { 64 return filepath.Join(opts.File.BestPath()...) 65 }, 66 TorrentDirMaker: nil, 67 PieceCompletion: pc, 68 }), 69 InfoBytes: mi.InfoBytes, 70 }) 71 defer to.Drop() 72 // TODO: Builtin trackers? 73 to.AddTrackers([][]string{{ 74 `wss://tracker.btorrent.xyz`, 75 `wss://tracker.openwebtorrent.com`, 76 "http://p4p.arenabg.com:1337/announce", 77 "udp://tracker.opentrackr.org:1337/announce", 78 "udp://tracker.openbittorrent.com:6969/announce", 79 }}) 80 fmt.Printf("%v: %v\n", to, to.Metainfo().Magnet(&ih, &info)) 81 } 82 select {} 83 } 84 return 85 }