]> Sergey Matveev's repositories - btrtrc.git/blob - cmd/torrent/main.go
cmd/torrent: Restore the announce and bencode subcommands
[btrtrc.git] / cmd / torrent / main.go
1 // Downloads torrents from the command-line.
2 package main
3
4 import (
5         "encoding/json"
6         "fmt"
7         "io"
8         stdLog "log"
9         "net/http"
10         "os"
11
12         "github.com/davecgh/go-spew/spew"
13         "github.com/prometheus/client_golang/prometheus"
14         "github.com/prometheus/client_golang/prometheus/promhttp"
15
16         "github.com/anacrolix/bargle"
17         "github.com/anacrolix/envpprof"
18         xprometheus "github.com/anacrolix/missinggo/v2/prometheus"
19
20         "github.com/anacrolix/torrent/bencode"
21         "github.com/anacrolix/torrent/version"
22 )
23
24 func init() {
25         prometheus.MustRegister(xprometheus.NewExpvarCollector())
26         http.Handle("/metrics", promhttp.Handler())
27 }
28
29 func main() {
30         defer stdLog.SetFlags(stdLog.Flags() | stdLog.Lshortfile)
31         main := bargle.Main{}
32         main.Defer(envpprof.Stop)
33         debug := false
34         debugFlag := bargle.NewFlag(&debug)
35         debugFlag.AddLong("debug")
36         main.Options = append(main.Options, debugFlag.Make())
37         main.Positionals = append(main.Positionals,
38                 bargle.Subcommand{Name: "metainfo", Command: metainfoCmd()},
39                 bargle.Subcommand{Name: "announce", Command: func() bargle.Command {
40                         var ac AnnounceCmd
41                         cmd := bargle.FromStruct(&ac)
42                         cmd.DefaultAction = func() error {
43                                 return announceErr(ac)
44                         }
45                         return cmd
46                 }()},
47                 bargle.Subcommand{Name: "scrape", Command: func() bargle.Command {
48                         var scrapeCfg scrapeCfg
49                         cmd := bargle.FromStruct(&scrapeCfg)
50                         cmd.Desc = "fetch swarm metrics for info-hashes from tracker"
51                         cmd.DefaultAction = func() error {
52                                 return scrape(scrapeCfg)
53                         }
54                         return cmd
55                 }()},
56                 bargle.Subcommand{Name: "download", Command: func() bargle.Command {
57                         var dlc DownloadCmd
58                         cmd := bargle.FromStruct(&dlc)
59                         cmd.DefaultAction = func() error {
60                                 return downloadErr(downloadFlags{
61                                         Debug:       debug,
62                                         DownloadCmd: dlc,
63                                 })
64                         }
65                         return cmd
66                 }()},
67                 bargle.Subcommand{
68                         Name: "bencode",
69                         Command: func() (cmd bargle.Command) {
70                                 var print func(interface{}) error
71                                 cmd.Positionals = append(cmd.Positionals,
72                                         bargle.Subcommand{Name: "json", Command: func() (cmd bargle.Command) {
73                                                 cmd.DefaultAction = func() error {
74                                                         je := json.NewEncoder(os.Stdout)
75                                                         je.SetIndent("", "  ")
76                                                         print = je.Encode
77                                                         return nil
78                                                 }
79                                                 return
80                                         }()},
81                                         bargle.Subcommand{Name: "spew", Command: func() (cmd bargle.Command) {
82                                                 cmd.DefaultAction = func() error {
83                                                         config := spew.NewDefaultConfig()
84                                                         config.DisableCapacities = true
85                                                         config.Indent = "  "
86                                                         print = func(v interface{}) error {
87                                                                 config.Dump(v)
88                                                                 return nil
89                                                         }
90                                                         return nil
91                                                 }
92                                                 return
93                                         }()})
94                                 d := bencode.NewDecoder(os.Stdin)
95                                 cmd.AfterParseFunc = func(ctx bargle.Context) error {
96                                         ctx.AfterParse(func() error {
97                                                 for i := 0; ; i++ {
98                                                         var v interface{}
99                                                         err := d.Decode(&v)
100                                                         if err == io.EOF {
101                                                                 break
102                                                         }
103                                                         if err != nil {
104                                                                 return fmt.Errorf("decoding message index %d: %w", i, err)
105                                                         }
106                                                         print(v)
107                                                 }
108                                                 return nil
109                                         })
110                                         return nil
111                                 }
112                                 cmd.Desc = "reads bencoding from stdin into Go native types and spews the result"
113                                 return
114                         }(),
115                 },
116                 bargle.Subcommand{Name: "version", Command: bargle.Command{
117                         DefaultAction: func() error {
118                                 fmt.Printf("HTTP User-Agent: %q\n", version.DefaultHttpUserAgent)
119                                 fmt.Printf("Torrent client version: %q\n", version.DefaultExtendedHandshakeClientVersion)
120                                 fmt.Printf("Torrent version prefix: %q\n", version.DefaultBep20Prefix)
121                                 return nil
122                         },
123                         Desc: "prints various protocol default version strings",
124                 }},
125                 bargle.Subcommand{Name: "serve", Command: serve()},
126                 bargle.Subcommand{Name: "create", Command: create()},
127         )
128         main.Run()
129 }