github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/core/commands/publish.go (about)

     1  package commands
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io"
     7  	"strings"
     8  
     9  	context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
    10  
    11  	key "github.com/ipfs/go-ipfs/blocks/key"
    12  	cmds "github.com/ipfs/go-ipfs/commands"
    13  	core "github.com/ipfs/go-ipfs/core"
    14  	crypto "github.com/ipfs/go-ipfs/p2p/crypto"
    15  	path "github.com/ipfs/go-ipfs/path"
    16  )
    17  
    18  var errNotOnline = errors.New("This command must be run in online mode. Try running 'ipfs daemon' first.")
    19  
    20  var PublishCmd = &cmds.Command{
    21  	Helptext: cmds.HelpText{
    22  		Tagline: "Publish an object to IPNS",
    23  		ShortDescription: `
    24  IPNS is a PKI namespace, where names are the hashes of public keys, and
    25  the private key enables publishing new (signed) values. In publish, the
    26  default value of <name> is your own identity public key.
    27  `,
    28  		LongDescription: `
    29  IPNS is a PKI namespace, where names are the hashes of public keys, and
    30  the private key enables publishing new (signed) values. In publish, the
    31  default value of <name> is your own identity public key.
    32  
    33  Examples:
    34  
    35  Publish an <ipfs-path> to your identity name:
    36  
    37    > ipfs name publish /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
    38    Published to QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n: /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
    39  
    40  Publish an <ipfs-path> to another public key (not implemented):
    41  
    42    > ipfs name publish /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n
    43    Published to QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n: /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
    44  
    45  `,
    46  	},
    47  
    48  	Arguments: []cmds.Argument{
    49  		cmds.StringArg("name", false, false, "The IPNS name to publish to. Defaults to your node's peerID"),
    50  		cmds.StringArg("ipfs-path", true, false, "IPFS path of the obejct to be published at <name>").EnableStdin(),
    51  	},
    52  	Run: func(req cmds.Request, res cmds.Response) {
    53  		log.Debug("Begin Publish")
    54  		n, err := req.InvocContext().GetNode()
    55  		if err != nil {
    56  			res.SetError(err, cmds.ErrNormal)
    57  			return
    58  		}
    59  
    60  		if !n.OnlineMode() {
    61  			err := n.SetupOfflineRouting()
    62  			if err != nil {
    63  				res.SetError(err, cmds.ErrNormal)
    64  				return
    65  			}
    66  		}
    67  
    68  		args := req.Arguments()
    69  
    70  		if n.Identity == "" {
    71  			res.SetError(errors.New("Identity not loaded!"), cmds.ErrNormal)
    72  			return
    73  		}
    74  
    75  		var name string
    76  		var pstr string
    77  
    78  		switch len(args) {
    79  		case 2:
    80  			name = args[0]
    81  			pstr = args[1]
    82  			if name != n.Identity.Pretty() {
    83  				res.SetError(errors.New("keychains not yet implemented"), cmds.ErrNormal)
    84  				return
    85  			}
    86  		case 1:
    87  			// name = n.Identity.Pretty()
    88  			pstr = args[0]
    89  		}
    90  
    91  		// TODO n.Keychain.Get(name).PrivKey
    92  		// TODO(cryptix): is req.Context().Context a child of n.Context()?
    93  		output, err := publish(req.Context(), n, n.PrivateKey, path.Path(pstr))
    94  		if err != nil {
    95  			res.SetError(err, cmds.ErrNormal)
    96  			return
    97  		}
    98  		res.SetOutput(output)
    99  	},
   100  	Marshalers: cmds.MarshalerMap{
   101  		cmds.Text: func(res cmds.Response) (io.Reader, error) {
   102  			v := res.Output().(*IpnsEntry)
   103  			s := fmt.Sprintf("Published to %s: %s\n", v.Name, v.Value)
   104  			return strings.NewReader(s), nil
   105  		},
   106  	},
   107  	Type: IpnsEntry{},
   108  }
   109  
   110  func publish(ctx context.Context, n *core.IpfsNode, k crypto.PrivKey, ref path.Path) (*IpnsEntry, error) {
   111  	// First, verify the path exists
   112  	_, err := core.Resolve(ctx, n, ref)
   113  	if err != nil {
   114  		return nil, err
   115  	}
   116  
   117  	err = n.Namesys.Publish(ctx, k, ref)
   118  	if err != nil {
   119  		return nil, err
   120  	}
   121  
   122  	hash, err := k.GetPublic().Hash()
   123  	if err != nil {
   124  		return nil, err
   125  	}
   126  
   127  	return &IpnsEntry{
   128  		Name:  key.Key(hash).String(),
   129  		Value: ref.String(),
   130  	}, nil
   131  }