]> Sergey Matveev's repositories - btrtrc.git/blob - cmd/torrent/metainfo.go
Restore torrent metainfo pprint
[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{
26                         Name:  "torrent file",
27                         Value: &bargle.String{Target: &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() (cmd bargle.Command) {
48                         var flags pprintMetainfoFlags
49                         cmd = bargle.FromStruct(&flags)
50                         cmd.DefaultAction = func() (err error) {
51                                 err = pprintMetainfo(mi, flags)
52                                 if err != nil {
53                                         return
54                                 }
55                                 if !flags.JustName {
56                                         os.Stdout.WriteString("\n")
57                                 }
58                                 return
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 }