github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/core/commands/block.go (about) 1 package commands 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "io" 8 "io/ioutil" 9 "strings" 10 11 mh "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash" 12 "github.com/ipfs/go-ipfs/blocks" 13 key "github.com/ipfs/go-ipfs/blocks/key" 14 cmds "github.com/ipfs/go-ipfs/commands" 15 u "github.com/ipfs/go-ipfs/util" 16 ) 17 18 type BlockStat struct { 19 Key string 20 Size int 21 } 22 23 func (bs BlockStat) String() string { 24 return fmt.Sprintf("Key: %s\nSize: %d\n", bs.Key, bs.Size) 25 } 26 27 var BlockCmd = &cmds.Command{ 28 Helptext: cmds.HelpText{ 29 Tagline: "Manipulate raw IPFS blocks", 30 ShortDescription: ` 31 'ipfs block' is a plumbing command used to manipulate raw ipfs blocks. 32 Reads from stdin or writes to stdout, and <key> is a base58 encoded 33 multihash. 34 `, 35 }, 36 37 Subcommands: map[string]*cmds.Command{ 38 "stat": blockStatCmd, 39 "get": blockGetCmd, 40 "put": blockPutCmd, 41 }, 42 } 43 44 var blockStatCmd = &cmds.Command{ 45 Helptext: cmds.HelpText{ 46 Tagline: "Print information of a raw IPFS block", 47 ShortDescription: ` 48 'ipfs block stat' is a plumbing command for retreiving information 49 on raw ipfs blocks. It outputs the following to stdout: 50 51 Key - the base58 encoded multihash 52 Size - the size of the block in bytes 53 54 `, 55 }, 56 57 Arguments: []cmds.Argument{ 58 cmds.StringArg("key", true, false, "The base58 multihash of an existing block to get").EnableStdin(), 59 }, 60 Run: func(req cmds.Request, res cmds.Response) { 61 b, err := getBlockForKey(req, req.Arguments()[0]) 62 if err != nil { 63 res.SetError(err, cmds.ErrNormal) 64 return 65 } 66 67 res.SetOutput(&BlockStat{ 68 Key: b.Key().Pretty(), 69 Size: len(b.Data), 70 }) 71 }, 72 Type: BlockStat{}, 73 Marshalers: cmds.MarshalerMap{ 74 cmds.Text: func(res cmds.Response) (io.Reader, error) { 75 bs := res.Output().(*BlockStat) 76 return strings.NewReader(bs.String()), nil 77 }, 78 }, 79 } 80 81 var blockGetCmd = &cmds.Command{ 82 Helptext: cmds.HelpText{ 83 Tagline: "Get a raw IPFS block", 84 ShortDescription: ` 85 'ipfs block get' is a plumbing command for retreiving raw ipfs blocks. 86 It outputs to stdout, and <key> is a base58 encoded multihash. 87 `, 88 }, 89 90 Arguments: []cmds.Argument{ 91 cmds.StringArg("key", true, false, "The base58 multihash of an existing block to get").EnableStdin(), 92 }, 93 Run: func(req cmds.Request, res cmds.Response) { 94 b, err := getBlockForKey(req, req.Arguments()[0]) 95 if err != nil { 96 res.SetError(err, cmds.ErrNormal) 97 return 98 } 99 100 res.SetOutput(bytes.NewReader(b.Data)) 101 }, 102 } 103 104 var blockPutCmd = &cmds.Command{ 105 Helptext: cmds.HelpText{ 106 Tagline: "Stores input as an IPFS block", 107 ShortDescription: ` 108 ipfs block put is a plumbing command for storing raw ipfs blocks. 109 It reads from stdin, and <key> is a base58 encoded multihash. 110 `, 111 }, 112 113 Arguments: []cmds.Argument{ 114 cmds.FileArg("data", true, false, "The data to be stored as an IPFS block").EnableStdin(), 115 }, 116 Run: func(req cmds.Request, res cmds.Response) { 117 n, err := req.InvocContext().GetNode() 118 if err != nil { 119 res.SetError(err, cmds.ErrNormal) 120 return 121 } 122 123 file, err := req.Files().NextFile() 124 if err != nil { 125 res.SetError(err, cmds.ErrNormal) 126 return 127 } 128 129 data, err := ioutil.ReadAll(file) 130 if err != nil { 131 res.SetError(err, cmds.ErrNormal) 132 return 133 } 134 135 err = file.Close() 136 if err != nil { 137 res.SetError(err, cmds.ErrNormal) 138 return 139 } 140 141 b := blocks.NewBlock(data) 142 log.Debugf("BlockPut key: '%q'", b.Key()) 143 144 k, err := n.Blocks.AddBlock(b) 145 if err != nil { 146 res.SetError(err, cmds.ErrNormal) 147 return 148 } 149 150 res.SetOutput(&BlockStat{ 151 Key: k.String(), 152 Size: len(data), 153 }) 154 }, 155 Marshalers: cmds.MarshalerMap{ 156 cmds.Text: func(res cmds.Response) (io.Reader, error) { 157 bs := res.Output().(*BlockStat) 158 return strings.NewReader(bs.Key + "\n"), nil 159 }, 160 }, 161 Type: BlockStat{}, 162 } 163 164 func getBlockForKey(req cmds.Request, skey string) (*blocks.Block, error) { 165 n, err := req.InvocContext().GetNode() 166 if err != nil { 167 return nil, err 168 } 169 170 if !u.IsValidHash(skey) { 171 return nil, errors.New("Not a valid hash") 172 } 173 174 h, err := mh.FromB58String(skey) 175 if err != nil { 176 return nil, err 177 } 178 179 k := key.Key(h) 180 b, err := n.Blocks.GetBlock(req.Context(), k) 181 if err != nil { 182 return nil, err 183 } 184 185 log.Debugf("ipfs block: got block with key: %q", b.Key()) 186 return b, nil 187 }