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