Track latest bargle
This commit is contained in:
parent
a5877a938c
commit
5c2f1ed307
|
@ -2,132 +2,111 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
stdLog "log"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/anacrolix/args"
|
||||
"github.com/anacrolix/bargle"
|
||||
"github.com/anacrolix/envpprof"
|
||||
"github.com/anacrolix/log"
|
||||
xprometheus "github.com/anacrolix/missinggo/v2/prometheus"
|
||||
"github.com/anacrolix/torrent/bencode"
|
||||
"github.com/anacrolix/torrent/version"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := mainErr(); err != nil {
|
||||
log.Printf("error in main: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
prometheus.MustRegister(xprometheus.NewExpvarCollector())
|
||||
http.Handle("/metrics", promhttp.Handler())
|
||||
}
|
||||
|
||||
func mainErr() error {
|
||||
defer envpprof.Stop()
|
||||
stdLog.SetFlags(stdLog.Flags() | stdLog.Lshortfile)
|
||||
debug := args.Flag(args.FlagOpt{Long: "debug"})
|
||||
return args.ParseMain(
|
||||
debug,
|
||||
args.Subcommand("metainfo", metainfoCmd),
|
||||
args.Subcommand("announce", func(p args.SubCmdCtx) error {
|
||||
var cmd AnnounceCmd
|
||||
err := p.NewParser().AddParams(
|
||||
args.Pos("tracker", &cmd.Tracker),
|
||||
args.Pos("infohash", &cmd.InfoHash)).Parse()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return announceErr(cmd)
|
||||
}),
|
||||
args.Subcommand("scrape", func(p args.SubCmdCtx) error {
|
||||
var cmd ScrapeCmd
|
||||
err := p.NewParser().AddParams(
|
||||
args.Pos("tracker", &cmd.Tracker),
|
||||
args.Pos("infohash", &cmd.InfoHashes, args.Arity('+'))).Parse()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return scrape(cmd)
|
||||
}),
|
||||
args.Subcommand("download", func(p args.SubCmdCtx) error {
|
||||
func main() {
|
||||
defer stdLog.SetFlags(stdLog.Flags() | stdLog.Lshortfile)
|
||||
main := bargle.Main{}
|
||||
main.Defer(envpprof.Stop)
|
||||
debug := false
|
||||
main.Options = append(main.Options, bargle.Flag{Longs: []string{"debug"}, Value: &debug})
|
||||
main.Positionals = append(main.Positionals,
|
||||
bargle.Subcommand{Name: "metainfo", Command: metainfoCmd()},
|
||||
//bargle.Subcommand{Name: "announce", Command: func() bargle.Command {
|
||||
// var cmd AnnounceCmd
|
||||
// err := p.NewParser().AddParams(
|
||||
// args.Pos("tracker", &cmd.Tracker),
|
||||
// args.Pos("infohash", &cmd.InfoHash)).Parse()
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return announceErr(cmd)
|
||||
//}()},
|
||||
//bargle.Subcommand{Name: "scrape", Command: func() bargle.Command {
|
||||
// var cmd ScrapeCmd
|
||||
// err := p.NewParser().AddParams(
|
||||
// args.Pos("tracker", &cmd.Tracker),
|
||||
// args.Pos("infohash", &cmd.InfoHashes, args.Arity('+'))).Parse()
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return scrape(cmd)
|
||||
//}()},
|
||||
bargle.Subcommand{Name: "download", Command: func() bargle.Command {
|
||||
var dlc DownloadCmd
|
||||
err := p.NewParser().AddParams(
|
||||
append(args.FromStruct(&dlc), debug)...,
|
||||
).Parse()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dlf := downloadFlags{
|
||||
Debug: debug.Bool(),
|
||||
DownloadCmd: dlc,
|
||||
}
|
||||
p.Defer(func() error {
|
||||
return downloadErr(dlf)
|
||||
})
|
||||
return nil
|
||||
}),
|
||||
args.Subcommand(
|
||||
"bencode",
|
||||
func(p args.SubCmdCtx) error {
|
||||
var print func(interface{}) error
|
||||
if !p.Parse(
|
||||
args.Subcommand("json", func(ctx args.SubCmdCtx) (err error) {
|
||||
ctx.Parse()
|
||||
je := json.NewEncoder(os.Stdout)
|
||||
je.SetIndent("", " ")
|
||||
print = je.Encode
|
||||
return nil
|
||||
}),
|
||||
args.Subcommand("spew", func(ctx args.SubCmdCtx) (err error) {
|
||||
ctx.Parse()
|
||||
config := spew.NewDefaultConfig()
|
||||
config.DisableCapacities = true
|
||||
config.Indent = " "
|
||||
print = func(v interface{}) error {
|
||||
config.Dump(v)
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}),
|
||||
).RanSubCmd {
|
||||
return errors.New("an output type is required")
|
||||
}
|
||||
d := bencode.NewDecoder(os.Stdin)
|
||||
p.Defer(func() error {
|
||||
for i := 0; ; i++ {
|
||||
var v interface{}
|
||||
err := d.Decode(&v)
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("decoding message index %d: %w", i, err)
|
||||
}
|
||||
print(v)
|
||||
}
|
||||
return nil
|
||||
cmd := bargle.FromStruct(&dlc)
|
||||
cmd.DefaultAction = func() error {
|
||||
return downloadErr(downloadFlags{
|
||||
Debug: debug,
|
||||
DownloadCmd: dlc,
|
||||
})
|
||||
return nil
|
||||
},
|
||||
args.Help("reads bencoding from stdin into Go native types and spews the result"),
|
||||
),
|
||||
args.Subcommand("version", func(p args.SubCmdCtx) error {
|
||||
fmt.Printf("HTTP User-Agent: %q\n", version.DefaultHttpUserAgent)
|
||||
fmt.Printf("Torrent client version: %q\n", version.DefaultExtendedHandshakeClientVersion)
|
||||
fmt.Printf("Torrent version prefix: %q\n", version.DefaultBep20Prefix)
|
||||
return nil
|
||||
}),
|
||||
args.Subcommand("serve", serve, args.Help("creates and seeds a torrent from a filepath")),
|
||||
}
|
||||
return cmd
|
||||
}()},
|
||||
//bargle.Subcommand{Name:
|
||||
// "bencode", Command: func() bargle.Command {
|
||||
// var print func(interface{}) error
|
||||
// if !p.Parse(
|
||||
// args.Subcommand("json", func(ctx args.SubCmdCtx) (err error) {
|
||||
// ctx.Parse()
|
||||
// je := json.NewEncoder(os.Stdout)
|
||||
// je.SetIndent("", " ")
|
||||
// print = je.Encode
|
||||
// return nil
|
||||
// }),
|
||||
// args.Subcommand("spew", func(ctx args.SubCmdCtx) (err error) {
|
||||
// ctx.Parse()
|
||||
// config := spew.NewDefaultConfig()
|
||||
// config.DisableCapacities = true
|
||||
// config.Indent = " "
|
||||
// print = func(v interface{}) error {
|
||||
// config.Dump(v)
|
||||
// return nil
|
||||
// }
|
||||
// return nil
|
||||
// }),
|
||||
// ).RanSubCmd {
|
||||
// return errors.New("an output type is required")
|
||||
// }
|
||||
// d := bencode.NewDecoder(os.Stdin)
|
||||
// p.Defer(func() error {
|
||||
// for i := 0; ; i++ {
|
||||
// var v interface{}
|
||||
// err := d.Decode(&v)
|
||||
// if err == io.EOF {
|
||||
// break
|
||||
// }
|
||||
// if err != nil {
|
||||
// return fmt.Errorf("decoding message index %d: %w", i, err)
|
||||
// }
|
||||
// print(v)
|
||||
// }
|
||||
// return nil
|
||||
// })
|
||||
// return nil
|
||||
// }(),
|
||||
// Desc: "reads bencoding from stdin into Go native types and spews the result",
|
||||
//},
|
||||
//bargle.Subcommand{Name: "version", Command: func() bargle.Command {
|
||||
// fmt.Printf("HTTP User-Agent: %q\n", version.DefaultHttpUserAgent)
|
||||
// fmt.Printf("Torrent client version: %q\n", version.DefaultExtendedHandshakeClientVersion)
|
||||
// fmt.Printf("Torrent version prefix: %q\n", version.DefaultBep20Prefix)
|
||||
// return nil
|
||||
//}()},
|
||||
bargle.Subcommand{Name: "serve", Command: serve(), Desc: "creates and seeds a torrent from a filepath"},
|
||||
)
|
||||
main.Run()
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/anacrolix/args"
|
||||
"github.com/anacrolix/bargle"
|
||||
"github.com/anacrolix/torrent/metainfo"
|
||||
"github.com/bradfitz/iter"
|
||||
)
|
||||
|
@ -17,53 +17,64 @@ type pprintMetainfoFlags struct {
|
|||
Files bool
|
||||
}
|
||||
|
||||
func metainfoCmd(ctx args.SubCmdCtx) (err error) {
|
||||
func metainfoCmd() (cmd bargle.Command) {
|
||||
var metainfoPath string
|
||||
var mi *metainfo.MetaInfo
|
||||
// TODO: Treat no subcommand as a failure.
|
||||
return ctx.NewParser().AddParams(
|
||||
args.Pos("torrent file", &metainfoPath, args.AfterParse(func() (err error) {
|
||||
mi, err = metainfo.LoadFromFile(metainfoPath)
|
||||
return
|
||||
})),
|
||||
args.Subcommand("magnet", func(ctx args.SubCmdCtx) (err error) {
|
||||
info, err := mi.UnmarshalInfo()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(os.Stdout, "%s\n", mi.Magnet(nil, &info).String())
|
||||
return nil
|
||||
}),
|
||||
args.Subcommand("pprint", func(ctx args.SubCmdCtx) (err error) {
|
||||
var flags pprintMetainfoFlags
|
||||
err = ctx.NewParser().AddParams(args.FromStruct(&flags)...).Parse()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = pprintMetainfo(mi, flags)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if !flags.JustName {
|
||||
os.Stdout.WriteString("\n")
|
||||
// TODO: Test if bargle treats no subcommand as a failure.
|
||||
cmd.Positionals = append(cmd.Positionals,
|
||||
&bargle.Positional[*string]{
|
||||
Name: "torrent file",
|
||||
Value: &metainfoPath,
|
||||
AfterParseFunc: func(ctx bargle.Context) error {
|
||||
ctx.AfterParse(func() (err error) {
|
||||
mi, err = metainfo.LoadFromFile(metainfoPath)
|
||||
return
|
||||
})
|
||||
return nil
|
||||
},
|
||||
},
|
||||
bargle.Subcommand{Name: "magnet", Command: func() (cmd bargle.Command) {
|
||||
cmd.DefaultAction = func() (err error) {
|
||||
info, err := mi.UnmarshalInfo()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(os.Stdout, "%s\n", mi.Magnet(nil, &info).String())
|
||||
return nil
|
||||
}
|
||||
return
|
||||
}),
|
||||
args.Subcommand("infohash", func(ctx args.SubCmdCtx) (err error) {
|
||||
fmt.Printf("%s: %s\n", mi.HashInfoBytes().HexString(), metainfoPath)
|
||||
return nil
|
||||
}),
|
||||
args.Subcommand("list-files", func(ctx args.SubCmdCtx) (err error) {
|
||||
info, err := mi.UnmarshalInfo()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unmarshalling info from metainfo at %q: %v", metainfoPath, err)
|
||||
}
|
||||
for _, f := range info.UpvertedFiles() {
|
||||
fmt.Println(f.DisplayPath(&info))
|
||||
}
|
||||
return nil
|
||||
}),
|
||||
).Parse()
|
||||
}()},
|
||||
//bargle.Subcommand{Name: "pprint", Command: func(ctx args.SubCmdCtx) (err error) {
|
||||
// var flags pprintMetainfoFlags
|
||||
// err = ctx.NewParser().AddParams(args.FromStruct(&flags)...).Parse()
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
// err = pprintMetainfo(mi, flags)
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
// if !flags.JustName {
|
||||
// os.Stdout.WriteString("\n")
|
||||
// }
|
||||
// return
|
||||
//}},
|
||||
//bargle.Subcommand{Name: "infohash", Command: func(ctx args.SubCmdCtx) (err error) {
|
||||
// fmt.Printf("%s: %s\n", mi.HashInfoBytes().HexString(), metainfoPath)
|
||||
// return nil
|
||||
//}},
|
||||
//bargle.Subcommand{Name: "list-files", Command: func(ctx args.SubCmdCtx) (err error) {
|
||||
// info, err := mi.UnmarshalInfo()
|
||||
// if err != nil {
|
||||
// return fmt.Errorf("unmarshalling info from metainfo at %q: %v", metainfoPath, err)
|
||||
// }
|
||||
// for _, f := range info.UpvertedFiles() {
|
||||
// fmt.Println(f.DisplayPath(&info))
|
||||
// }
|
||||
// return nil
|
||||
//}},
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
func pprintMetainfo(metainfo *metainfo.MetaInfo, flags pprintMetainfoFlags) error {
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"net/http"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/anacrolix/args"
|
||||
"github.com/anacrolix/bargle"
|
||||
"github.com/anacrolix/log"
|
||||
"github.com/anacrolix/torrent"
|
||||
"github.com/anacrolix/torrent/bencode"
|
||||
|
@ -13,10 +13,10 @@ import (
|
|||
"github.com/anacrolix/torrent/storage"
|
||||
)
|
||||
|
||||
func serve(ctx args.SubCmdCtx) error {
|
||||
var filePath string
|
||||
ctx.Parse(args.Pos("filePath", &filePath))
|
||||
ctx.Defer(func() error {
|
||||
func serve() (cmd bargle.Command) {
|
||||
filePath := &bargle.Positional[string]{}
|
||||
cmd.Positionals = append(cmd.Positionals, filePath)
|
||||
cmd.DefaultAction = func() error {
|
||||
cfg := torrent.NewDefaultClientConfig()
|
||||
cfg.Seed = true
|
||||
cl, err := torrent.NewClient(cfg)
|
||||
|
@ -35,9 +35,9 @@ func serve(ctx args.SubCmdCtx) error {
|
|||
info := metainfo.Info{
|
||||
PieceLength: pieceLength,
|
||||
}
|
||||
err = info.BuildFromFilePath(filePath)
|
||||
err = info.BuildFromFilePath(filePath.Value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("building info from path %q: %w", filePath, err)
|
||||
return fmt.Errorf("building info from path %q: %w", filePath.Value, err)
|
||||
}
|
||||
for _, fi := range info.Files {
|
||||
log.Printf("added %q", fi.Path)
|
||||
|
@ -54,7 +54,7 @@ func serve(ctx args.SubCmdCtx) error {
|
|||
to, _ := cl.AddTorrentOpt(torrent.AddTorrentOpts{
|
||||
InfoHash: ih,
|
||||
Storage: storage.NewFileOpts(storage.NewFileClientOpts{
|
||||
ClientBaseDir: filePath,
|
||||
ClientBaseDir: filePath.Value,
|
||||
FilePathMaker: func(opts storage.FilePathMakerOpts) string {
|
||||
return filepath.Join(opts.File.Path...)
|
||||
},
|
||||
|
@ -78,6 +78,6 @@ func serve(ctx args.SubCmdCtx) error {
|
|||
}
|
||||
fmt.Printf("%v: %v\n", to, to.Metainfo().Magnet(&ih, &info))
|
||||
select {}
|
||||
})
|
||||
return nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
1
go.mod
1
go.mod
|
@ -51,6 +51,7 @@ require (
|
|||
require (
|
||||
github.com/alecthomas/atomic v0.1.0-alpha2 // indirect
|
||||
github.com/alexflint/go-scalar v1.1.0 // indirect
|
||||
github.com/anacrolix/bargle v0.0.0-20220620083758-c3885e1796d1 // indirect
|
||||
github.com/anacrolix/mmsg v1.0.0 // indirect
|
||||
github.com/anacrolix/stm v0.4.0 // indirect
|
||||
github.com/benbjohnson/immutable v0.3.0 // indirect
|
||||
|
|
2
go.sum
2
go.sum
|
@ -64,6 +64,8 @@ github.com/alexflint/go-scalar v1.1.0 h1:aaAouLLzI9TChcPXotr6gUhq+Scr8rl0P9P4Pnl
|
|||
github.com/alexflint/go-scalar v1.1.0/go.mod h1:LoFvNMqS1CPrMVltza4LvnGKhaSpc3oyLEBUZVhhS2o=
|
||||
github.com/anacrolix/args v0.5.1-0.20220509024600-c3b77d0b61ac h1:XWoepbk3zgOQ8jMO3vpOnohd6MfENPbFZPivB2L7myc=
|
||||
github.com/anacrolix/args v0.5.1-0.20220509024600-c3b77d0b61ac/go.mod h1:Fj/N2PehEwTBE5t/V/9xgTcxDkuYQ+5IBoFw/8gkldI=
|
||||
github.com/anacrolix/bargle v0.0.0-20220620083758-c3885e1796d1 h1:RijTNFCxug0EBODz/AmqJDA3Ow700v5jJZQL1j+RLvI=
|
||||
github.com/anacrolix/bargle v0.0.0-20220620083758-c3885e1796d1/go.mod h1:cC/kX8wL4i1n+63lOrXhPQQlsoxCo0EqV88fGExQwcY=
|
||||
github.com/anacrolix/chansync v0.3.0 h1:lRu9tbeuw3wl+PhMu/r+JJCRu5ArFXIluOgdF0ao6/U=
|
||||
github.com/anacrolix/chansync v0.3.0/go.mod h1:DZsatdsdXxD0WiwcGl0nJVwyjCKMDv+knl1q2iBjA2k=
|
||||
github.com/anacrolix/dht/v2 v2.18.0 h1:btjVjzjKqO5nKGbJHJ2UmuwiRx+EgX3e+OCHC9+WRz8=
|
||||
|
|
Loading…
Reference in New Issue