1 // Downloads torrents from the command-line.
11 "github.com/prometheus/client_golang/prometheus"
12 "github.com/prometheus/client_golang/prometheus/promhttp"
13 "go.opentelemetry.io/otel"
14 "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
15 "go.opentelemetry.io/otel/sdk/trace"
17 "github.com/anacrolix/bargle"
18 "github.com/anacrolix/envpprof"
19 "github.com/anacrolix/log"
20 xprometheus "github.com/anacrolix/missinggo/v2/prometheus"
22 "github.com/anacrolix/torrent/version"
26 prometheus.MustRegister(xprometheus.NewExpvarCollector())
27 http.Handle("/metrics", promhttp.Handler())
30 func shutdownTracerProvider(ctx context.Context, tp *trace.TracerProvider) {
32 err := tp.Shutdown(ctx)
33 elapsed := time.Since(started)
34 log.Levelf(log.Error, "shutting down tracer provider (took %v): %v", elapsed, err)
38 defer stdLog.SetFlags(stdLog.Flags() | stdLog.Lshortfile)
40 ctx := context.Background()
41 tracingExporter, err := otlptracegrpc.New(ctx)
43 log.Fatalf("creating tracing exporter: %v", err)
45 tracerProvider := trace.NewTracerProvider(trace.WithBatcher(tracingExporter))
46 defer shutdownTracerProvider(ctx, tracerProvider)
47 otel.SetTracerProvider(tracerProvider)
50 main.Defer(envpprof.Stop)
51 main.Defer(func() { shutdownTracerProvider(ctx, tracerProvider) })
53 debugFlag := bargle.NewFlag(&debug)
54 debugFlag.AddLong("debug")
55 main.Options = append(main.Options, debugFlag.Make())
56 main.Positionals = append(main.Positionals,
57 bargle.Subcommand{Name: "metainfo", Command: metainfoCmd()},
58 //bargle.Subcommand{Name: "announce", Command: func() bargle.Command {
59 // var cmd AnnounceCmd
60 // err := p.NewParser().AddParams(
61 // args.Pos("tracker", &cmd.Tracker),
62 // args.Pos("infohash", &cmd.InfoHash)).Parse()
66 // return announceErr(cmd)
68 bargle.Subcommand{Name: "scrape", Command: func() bargle.Command {
69 var scrapeCfg scrapeCfg
70 cmd := bargle.FromStruct(&scrapeCfg)
71 cmd.Desc = "fetch swarm metrics for info-hashes from tracker"
72 cmd.DefaultAction = func() error {
73 return scrape(scrapeCfg)
77 bargle.Subcommand{Name: "download", Command: func() bargle.Command {
79 cmd := bargle.FromStruct(&dlc)
80 cmd.DefaultAction = func() error {
81 return downloadErr(downloadFlags{
88 //bargle.Subcommand{Name:
89 // "bencode", Command: func() bargle.Command {
90 // var print func(interface{}) error
92 // args.Subcommand("json", func(ctx args.SubCmdCtx) (err error) {
94 // je := json.NewEncoder(os.Stdout)
95 // je.SetIndent("", " ")
99 // args.Subcommand("spew", func(ctx args.SubCmdCtx) (err error) {
101 // config := spew.NewDefaultConfig()
102 // config.DisableCapacities = true
103 // config.Indent = " "
104 // print = func(v interface{}) error {
111 // return errors.New("an output type is required")
113 // d := bencode.NewDecoder(os.Stdin)
114 // p.Defer(func() error {
115 // for i := 0; ; i++ {
117 // err := d.Decode(&v)
118 // if err == io.EOF {
122 // return fmt.Errorf("decoding message index %d: %w", i, err)
130 // Desc: "reads bencoding from stdin into Go native types and spews the result",
132 bargle.Subcommand{Name: "version", Command: bargle.Command{
133 DefaultAction: func() error {
134 fmt.Printf("HTTP User-Agent: %q\n", version.DefaultHttpUserAgent)
135 fmt.Printf("Torrent client version: %q\n", version.DefaultExtendedHandshakeClientVersion)
136 fmt.Printf("Torrent version prefix: %q\n", version.DefaultBep20Prefix)
139 Desc: "prints various protocol default version strings",
141 bargle.Subcommand{Name: "serve", Command: serve()},
142 bargle.Subcommand{Name: "create", Command: create()},