github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/cmd/swarm/upload.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 12:09:31</date>
    10  //</624342606494568448>
    11  
    12  
    13  //
    14  package main
    15  
    16  import (
    17  	"errors"
    18  	"fmt"
    19  	"io"
    20  	"io/ioutil"
    21  	"mime"
    22  	"net/http"
    23  	"os"
    24  	"os/user"
    25  	"path"
    26  	"path/filepath"
    27  	"strings"
    28  
    29  	"github.com/ethereum/go-ethereum/cmd/utils"
    30  	swarm "github.com/ethereum/go-ethereum/swarm/api/client"
    31  	"gopkg.in/urfave/cli.v1"
    32  )
    33  
    34  func upload(ctx *cli.Context) {
    35  
    36  	args := ctx.Args()
    37  	var (
    38  		bzzapi       = strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/")
    39  		recursive    = ctx.GlobalBool(SwarmRecursiveFlag.Name)
    40  		wantManifest = ctx.GlobalBoolT(SwarmWantManifestFlag.Name)
    41  		defaultPath  = ctx.GlobalString(SwarmUploadDefaultPath.Name)
    42  		fromStdin    = ctx.GlobalBool(SwarmUpFromStdinFlag.Name)
    43  		mimeType     = ctx.GlobalString(SwarmUploadMimeType.Name)
    44  		client       = swarm.NewClient(bzzapi)
    45  		toEncrypt    = ctx.Bool(SwarmEncryptedFlag.Name)
    46  		file         string
    47  	)
    48  
    49  	if len(args) != 1 {
    50  		if fromStdin {
    51  			tmp, err := ioutil.TempFile("", "swarm-stdin")
    52  			if err != nil {
    53  				utils.Fatalf("error create tempfile: %s", err)
    54  			}
    55  			defer os.Remove(tmp.Name())
    56  			n, err := io.Copy(tmp, os.Stdin)
    57  			if err != nil {
    58  				utils.Fatalf("error copying stdin to tempfile: %s", err)
    59  			} else if n == 0 {
    60  				utils.Fatalf("error reading from stdin: zero length")
    61  			}
    62  			file = tmp.Name()
    63  		} else {
    64  			utils.Fatalf("Need filename as the first and only argument")
    65  		}
    66  	} else {
    67  		file = expandPath(args[0])
    68  	}
    69  
    70  	if !wantManifest {
    71  		f, err := swarm.Open(file)
    72  		if err != nil {
    73  			utils.Fatalf("Error opening file: %s", err)
    74  		}
    75  		defer f.Close()
    76  		hash, err := client.UploadRaw(f, f.Size, toEncrypt)
    77  		if err != nil {
    78  			utils.Fatalf("Upload failed: %s", err)
    79  		}
    80  		fmt.Println(hash)
    81  		return
    82  	}
    83  
    84  	stat, err := os.Stat(file)
    85  	if err != nil {
    86  		utils.Fatalf("Error opening file: %s", err)
    87  	}
    88  
    89  //
    90  //根据上传文件的类型
    91  	var doUpload func() (hash string, err error)
    92  	if stat.IsDir() {
    93  		doUpload = func() (string, error) {
    94  			if !recursive {
    95  				return "", errors.New("Argument is a directory and recursive upload is disabled")
    96  			}
    97  			if defaultPath != "" {
    98  //构造绝对默认路径
    99  				absDefaultPath, _ := filepath.Abs(defaultPath)
   100  				absFile, _ := filepath.Abs(file)
   101  //
   102  //从绝对默认路径修剪它并获取相对默认路径
   103  				absFile = strings.TrimRight(absFile, "/") + "/"
   104  				if absDefaultPath != "" && absFile != "" && strings.HasPrefix(absDefaultPath, absFile) {
   105  					defaultPath = strings.TrimPrefix(absDefaultPath, absFile)
   106  				}
   107  			}
   108  			return client.UploadDirectory(file, defaultPath, "", toEncrypt)
   109  		}
   110  	} else {
   111  		doUpload = func() (string, error) {
   112  			f, err := swarm.Open(file)
   113  			if err != nil {
   114  				return "", fmt.Errorf("error opening file: %s", err)
   115  			}
   116  			defer f.Close()
   117  			if mimeType == "" {
   118  				mimeType = detectMimeType(file)
   119  			}
   120  			f.ContentType = mimeType
   121  			return client.Upload(f, "", toEncrypt)
   122  		}
   123  	}
   124  	hash, err := doUpload()
   125  	if err != nil {
   126  		utils.Fatalf("Upload failed: %s", err)
   127  	}
   128  	fmt.Println(hash)
   129  }
   130  
   131  //展开文件路径
   132  //1。用用户主目录替换tilde
   133  //2。扩展嵌入的环境变量
   134  //三。清理路径,例如/a/b/。/c->/a/c
   135  //注意,它有局限性,例如~someuser/tmp将不会扩展
   136  func expandPath(p string) string {
   137  	if strings.HasPrefix(p, "~/") || strings.HasPrefix(p, "~\\") {
   138  		if home := homeDir(); home != "" {
   139  			p = home + p[1:]
   140  		}
   141  	}
   142  	return path.Clean(os.ExpandEnv(p))
   143  }
   144  
   145  func homeDir() string {
   146  	if home := os.Getenv("HOME"); home != "" {
   147  		return home
   148  	}
   149  	if usr, err := user.Current(); err == nil {
   150  		return usr.HomeDir
   151  	}
   152  	return ""
   153  }
   154  
   155  func detectMimeType(file string) string {
   156  	if ext := filepath.Ext(file); ext != "" {
   157  		return mime.TypeByExtension(ext)
   158  	}
   159  	f, err := os.Open(file)
   160  	if err != nil {
   161  		return ""
   162  	}
   163  	defer f.Close()
   164  	buf := make([]byte, 512)
   165  	if n, _ := f.Read(buf); n > 0 {
   166  		return http.DetectContentType(buf)
   167  	}
   168  	return ""
   169  }
   170