]> Sergey Matveev's repositories - btrtrc.git/blob - cmd/torrent/metainfo.go
4cca795453fccde7ce2f52fe3f00ab586d4715b2
[btrtrc.git] / cmd / torrent / metainfo.go
1 package main
2
3 import (
4         "encoding/hex"
5         "encoding/json"
6         "fmt"
7         "os"
8
9         "github.com/anacrolix/bargle"
10         "github.com/anacrolix/torrent/metainfo"
11         "github.com/bradfitz/iter"
12 )
13
14 type pprintMetainfoFlags struct {
15         JustName    bool
16         PieceHashes bool
17         Files       bool
18 }
19
20 func metainfoCmd() (cmd bargle.Command) {
21         var metainfoPath string
22         var mi *metainfo.MetaInfo
23         // TODO: Test if bargle treats no subcommand as a failure.
24         cmd.Positionals = append(cmd.Positionals,
25                 &bargle.Positional[*string]{
26                         Name:  "torrent file",
27                         Value: &metainfoPath,
28                         AfterParseFunc: func(ctx bargle.Context) error {
29                                 ctx.AfterParse(func() (err error) {
30                                         mi, err = metainfo.LoadFromFile(metainfoPath)
31                                         return
32                                 })
33                                 return nil
34                         },
35                 },
36                 bargle.Subcommand{Name: "magnet", Command: func() (cmd bargle.Command) {
37                         cmd.DefaultAction = func() (err error) {
38                                 info, err := mi.UnmarshalInfo()
39                                 if err != nil {
40                                         return
41                                 }
42                                 fmt.Fprintf(os.Stdout, "%s\n", mi.Magnet(nil, &info).String())
43                                 return nil
44                         }
45                         return
46                 }()},
47                 //bargle.Subcommand{Name: "pprint", Command: func(ctx args.SubCmdCtx) (err error) {
48                 //      var flags pprintMetainfoFlags
49                 //      err = ctx.NewParser().AddParams(args.FromStruct(&flags)...).Parse()
50                 //      if err != nil {
51                 //              return
52                 //      }
53                 //      err = pprintMetainfo(mi, flags)
54                 //      if err != nil {
55                 //              return
56                 //      }
57                 //      if !flags.JustName {
58                 //              os.Stdout.WriteString("\n")
59                 //      }
60                 //      return
61                 //}},
62                 //bargle.Subcommand{Name: "infohash", Command: func(ctx args.SubCmdCtx) (err error) {
63                 //      fmt.Printf("%s: %s\n", mi.HashInfoBytes().HexString(), metainfoPath)
64                 //      return nil
65                 //}},
66                 //bargle.Subcommand{Name: "list-files", Command: func(ctx args.SubCmdCtx) (err error) {
67                 //      info, err := mi.UnmarshalInfo()
68                 //      if err != nil {
69                 //              return fmt.Errorf("unmarshalling info from metainfo at %q: %v", metainfoPath, err)
70                 //      }
71                 //      for _, f := range info.UpvertedFiles() {
72                 //              fmt.Println(f.DisplayPath(&info))
73                 //      }
74                 //      return nil
75                 //}},
76         )
77         return
78 }
79
80 func pprintMetainfo(metainfo *metainfo.MetaInfo, flags pprintMetainfoFlags) error {
81         info, err := metainfo.UnmarshalInfo()
82         if err != nil {
83                 return fmt.Errorf("error unmarshalling info: %s", err)
84         }
85         if flags.JustName {
86                 fmt.Printf("%s\n", info.Name)
87                 return nil
88         }
89         d := map[string]interface{}{
90                 "Name":         info.Name,
91                 "Name.Utf8":    info.NameUtf8,
92                 "NumPieces":    info.NumPieces(),
93                 "PieceLength":  info.PieceLength,
94                 "InfoHash":     metainfo.HashInfoBytes().HexString(),
95                 "NumFiles":     len(info.UpvertedFiles()),
96                 "TotalLength":  info.TotalLength(),
97                 "Announce":     metainfo.Announce,
98                 "AnnounceList": metainfo.AnnounceList,
99                 "UrlList":      metainfo.UrlList,
100         }
101         if len(metainfo.Nodes) > 0 {
102                 d["Nodes"] = metainfo.Nodes
103         }
104         if flags.Files {
105                 d["Files"] = info.UpvertedFiles()
106         }
107         if flags.PieceHashes {
108                 d["PieceHashes"] = func() (ret []string) {
109                         for i := range iter.N(info.NumPieces()) {
110                                 ret = append(ret, hex.EncodeToString(info.Pieces[i*20:(i+1)*20]))
111                         }
112                         return
113                 }()
114         }
115         b, _ := json.MarshalIndent(d, "", "  ")
116         _, err = os.Stdout.Write(b)
117         return err
118 }