core/commands2: Added 'block' command
Matt Bell committed
Nov 6, 2014 at 01:52 UTC
18cce63ab6952984072a04ed157b5c235287d737
2 files changed
+123
core/commands2/block.go
new
+122
@@ -0,0 +1,122 @@
1
+package commands
2
+
3
+import (
4
+ "bytes"
5
+ "errors"
6
+ "fmt"
7
+ "io"
8
+ "io/ioutil"
9
+ "time"
10
+
11
+ "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
12
+
13
+ mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
14
+ "github.com/jbenet/go-ipfs/blocks"
15
+ cmds "github.com/jbenet/go-ipfs/commands"
16
+ u "github.com/jbenet/go-ipfs/util"
17
+)
18
+
19
+type Block struct {
20
+ Key string
21
+ Length int
22
+}
23
+
24
+var blockCmd = &cmds.Command{
25
+ Help: `ipfs block - manipulate raw ipfs blocks
26
+
27
+ ipfs block get <key> - get and output block named by <key>
28
+ ipfs block put - store stdin as a block, outputs <key>
29
+
30
+ipfs block is a plumbing command used to manipulate raw ipfs blocks.
31
+Reads from stdin or writes to stdout, and <key> is a base58 encoded
32
+multihash.`,
33
+ Subcommands: map[string]*cmds.Command{
34
+ "get": blockGetCmd,
35
+ "put": blockPutCmd,
36
+ },
37
+}
38
+
39
+var blockGetCmd = &cmds.Command{
40
+ Arguments: []cmds.Argument{
41
+ cmds.Argument{"key", cmds.ArgString, true, false},
42
+ },
43
+ Help: `ipfs get <key> - gets and outputs block named by <key>
44
+
45
+'ipfs block get' is a plumbing command for retreiving raw ipfs blocks.
46
+<key> is a base58 encoded multihash`,
47
+ Run: func(res cmds.Response, req cmds.Request) {
48
+ n := req.Context().Node
49
+
50
+ key, ok := req.Arguments()[0].(string)
51
+ if !ok {
52
+ res.SetError(errors.New("cast error"), cmds.ErrNormal)
53
+ return
54
+ }
55
+
56
+ if !u.IsValidHash(key) {
57
+ res.SetError(errors.New("Not a valid hash"), cmds.ErrClient)
58
+ return
59
+ }
60
+
61
+ h, err := mh.FromB58String(key)
62
+ if err != nil {
63
+ res.SetError(err, cmds.ErrNormal)
64
+ return
65
+ }
66
+
67
+ k := u.Key(h)
68
+ ctx, _ := context.WithTimeout(context.TODO(), time.Second*5)
69
+ b, err := n.Blocks.GetBlock(ctx, k)
70
+ if err != nil {
71
+ res.SetError(err, cmds.ErrNormal)
72
+ return
73
+ }
74
+
75
+ res.SetOutput(bytes.NewReader(b.Data))
76
+ },
77
+}
78
+
79
+var blockPutCmd = &cmds.Command{
80
+ Arguments: []cmds.Argument{
81
+ cmds.Argument{"data", cmds.ArgFile, true, false},
82
+ },
83
+ Help: `ipfs put - stores input as a block, outputs its key
84
+
85
+ipfs block put is a plumbing command for storing raw ipfs blocks.`,
86
+ Run: func(res cmds.Response, req cmds.Request) {
87
+ n := req.Context().Node
88
+
89
+ in, ok := req.Arguments()[0].(io.Reader)
90
+ if !ok {
91
+ res.SetError(errors.New("cast error"), cmds.ErrNormal)
92
+ return
93
+ }
94
+
95
+ data, err := ioutil.ReadAll(in)
96
+ if err != nil {
97
+ res.SetError(err, cmds.ErrNormal)
98
+ return
99
+ }
100
+
101
+ b := blocks.NewBlock(data)
102
+
103
+ k, err := n.Blocks.AddBlock(b)
104
+ if err != nil {
105
+ res.SetError(err, cmds.ErrNormal)
106
+ return
107
+ }
108
+
109
+ res.SetOutput(&Block{
110
+ Key: k.String(),
111
+ Length: len(data),
112
+ })
113
+ },
114
+ Type: &Block{},
115
+ Marshallers: map[cmds.EncodingType]cmds.Marshaller{
116
+ cmds.Text: func(res cmds.Response) ([]byte, error) {
117
+ block := res.Output().(*Block)
118
+ s := fmt.Sprintf("Block added (%v bytes): %s\n", block.Length, block.Key)
119
+ return []byte(s), nil
120
+ },
121
+ },
122
+}
core/commands2/root.go
+1
@@ -69,6 +69,7 @@ var rootSubcommands = map[string]*cmds.Command{
69
"config": configCmd,
70
"bootstrap": bootstrapCmd,
71
"mount": mountCmd,
72
+ "block": blockCmd,
73
74
// test subcommands
75
// TODO: remove these when we don't need them anymore