github.com/zignig/go-ipfs@v0.0.0-20141111235910-c9e5fdf55a52/core/commands2/block.go (about)

     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  	Description: "Manipulate raw IPFS blocks",
    26  	Help: `'ipfs block' is a plumbing command used to manipulate raw ipfs blocks.
    27  Reads from stdin or writes to stdout, and <key> is a base58 encoded
    28  multihash.`,
    29  	Subcommands: map[string]*cmds.Command{
    30  		"get": blockGetCmd,
    31  		"put": blockPutCmd,
    32  	},
    33  }
    34  
    35  var blockGetCmd = &cmds.Command{
    36  	Description: "Get a raw IPFS block",
    37  	Help: `ipfs block get is a plumbing command for retreiving raw ipfs blocks.
    38  It outputs to stdout, and <key> is a base58 encoded multihash.`,
    39  
    40  	Arguments: []cmds.Argument{
    41  		cmds.StringArg("key", true, false, "The base58 multihash of an existing block to get"),
    42  	},
    43  	Run: func(req cmds.Request) (interface{}, error) {
    44  		n := req.Context().Node
    45  
    46  		key, ok := req.Arguments()[0].(string)
    47  		if !ok {
    48  			return nil, errors.New("cast error")
    49  		}
    50  
    51  		if !u.IsValidHash(key) {
    52  			return nil, cmds.Error{"Not a valid hash", cmds.ErrClient}
    53  		}
    54  
    55  		h, err := mh.FromB58String(key)
    56  		if err != nil {
    57  			return nil, err
    58  		}
    59  
    60  		k := u.Key(h)
    61  		ctx, _ := context.WithTimeout(context.TODO(), time.Second*5)
    62  		b, err := n.Blocks.GetBlock(ctx, k)
    63  		if err != nil {
    64  			return nil, err
    65  		}
    66  
    67  		return bytes.NewReader(b.Data), nil
    68  	},
    69  }
    70  
    71  var blockPutCmd = &cmds.Command{
    72  	Description: "Stores input as an IPFS block",
    73  	Help: `ipfs block put is a plumbing command for storing raw ipfs blocks.
    74  It reads from stdin, and <key> is a base58 encoded multihash.`,
    75  
    76  	Arguments: []cmds.Argument{
    77  		cmds.FileArg("data", true, false, "The data to be stored as an IPFS block"),
    78  	},
    79  	Run: func(req cmds.Request) (interface{}, error) {
    80  		n := req.Context().Node
    81  
    82  		in, ok := req.Arguments()[0].(io.Reader)
    83  		if !ok {
    84  			return nil, errors.New("cast error")
    85  		}
    86  
    87  		data, err := ioutil.ReadAll(in)
    88  		if err != nil {
    89  			return nil, err
    90  		}
    91  
    92  		b := blocks.NewBlock(data)
    93  		log.Debugf("BlockPut key: '%q'", b.Key())
    94  
    95  		k, err := n.Blocks.AddBlock(b)
    96  		if err != nil {
    97  			return nil, err
    98  		}
    99  
   100  		return &Block{
   101  			Key:    k.String(),
   102  			Length: len(data),
   103  		}, nil
   104  	},
   105  	Type: &Block{},
   106  	Marshallers: map[cmds.EncodingType]cmds.Marshaller{
   107  		cmds.Text: func(res cmds.Response) ([]byte, error) {
   108  			block := res.Output().(*Block)
   109  			s := fmt.Sprintf("Block added (%v bytes): %s\n", block.Length, block.Key)
   110  			return []byte(s), nil
   111  		},
   112  	},
   113  }