]> Sergey Matveev's repositories - btrtrc.git/blob - cmd/torrent/serve.go
torrent serve: Add some reasonable tracker defaults
[btrtrc.git] / cmd / torrent / serve.go
1 package main
2
3 import (
4         "fmt"
5         "net/http"
6         "path/filepath"
7
8         "github.com/anacrolix/args"
9         "github.com/anacrolix/log"
10         "github.com/anacrolix/torrent"
11         "github.com/anacrolix/torrent/bencode"
12         "github.com/anacrolix/torrent/metainfo"
13         "github.com/anacrolix/torrent/storage"
14 )
15
16 func serve(ctx args.SubCmdCtx) error {
17         var filePath string
18         ctx.Parse(args.Pos("filePath", &filePath))
19         ctx.Defer(func() error {
20                 cfg := torrent.NewDefaultClientConfig()
21                 cfg.Seed = true
22                 cl, err := torrent.NewClient(cfg)
23                 if err != nil {
24                         return fmt.Errorf("new torrent client: %w", err)
25                 }
26                 defer cl.Close()
27                 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
28                         cl.WriteStatus(w)
29                 })
30                 info := metainfo.Info{
31                         PieceLength: 1 << 18,
32                 }
33                 err = info.BuildFromFilePath(filePath)
34                 if err != nil {
35                         return fmt.Errorf("building info from path %q: %w", filePath, err)
36                 }
37                 for _, fi := range info.Files {
38                         log.Printf("added %q", fi.Path)
39                 }
40                 mi := metainfo.MetaInfo{
41                         InfoBytes: bencode.MustMarshal(info),
42                 }
43                 pc, err := storage.NewDefaultPieceCompletionForDir(".")
44                 if err != nil {
45                         return fmt.Errorf("new piece completion: %w", err)
46                 }
47                 defer pc.Close()
48                 ih := mi.HashInfoBytes()
49                 to, _ := cl.AddTorrentOpt(torrent.AddTorrentOpts{
50                         InfoHash: ih,
51                         Storage: storage.NewFileOpts(storage.NewFileClientOpts{
52                                 ClientBaseDir: filePath,
53                                 FilePathMaker: func(opts storage.FilePathMakerOpts) string {
54                                         return filepath.Join(opts.File.Path...)
55                                 },
56                                 TorrentDirMaker: nil,
57                                 PieceCompletion: pc,
58                         }),
59                 })
60                 defer to.Drop()
61                 err = to.MergeSpec(&torrent.TorrentSpec{
62                         InfoBytes: mi.InfoBytes,
63                         Trackers: [][]string{{
64                                 `wss://tracker.btorrent.xyz`,
65                                 `wss://tracker.openwebtorrent.com`,
66                                 "http://p4p.arenabg.com:1337/announce",
67                                 "udp://tracker.opentrackr.org:1337/announce",
68                                 "udp://tracker.openbittorrent.com:6969/announce",
69                         }},
70                 })
71                 if err != nil {
72                         return fmt.Errorf("setting trackers: %w", err)
73                 }
74                 fmt.Printf("%v: %v\n", to, to.Metainfo().Magnet(&ih, &info))
75                 select {}
76         })
77         return nil
78 }