github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/cmd/swarm/upload.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2016 Go Ethereum作者 10 //此文件是Go以太坊的一部分。 11 // 12 //Go以太坊是免费软件:您可以重新发布和/或修改它 13 //根据GNU通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊的分布希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU通用公共许可证了解更多详细信息。 21 // 22 //你应该已经收到一份GNU通用公共许可证的副本 23 //一起去以太坊吧。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 // 26 package main 27 28 import ( 29 "errors" 30 "fmt" 31 "io" 32 "io/ioutil" 33 "mime" 34 "net/http" 35 "os" 36 "os/user" 37 "path" 38 "path/filepath" 39 "strings" 40 41 "github.com/ethereum/go-ethereum/cmd/utils" 42 swarm "github.com/ethereum/go-ethereum/swarm/api/client" 43 "gopkg.in/urfave/cli.v1" 44 ) 45 46 func upload(ctx *cli.Context) { 47 48 args := ctx.Args() 49 var ( 50 bzzapi = strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/") 51 recursive = ctx.GlobalBool(SwarmRecursiveFlag.Name) 52 wantManifest = ctx.GlobalBoolT(SwarmWantManifestFlag.Name) 53 defaultPath = ctx.GlobalString(SwarmUploadDefaultPath.Name) 54 fromStdin = ctx.GlobalBool(SwarmUpFromStdinFlag.Name) 55 mimeType = ctx.GlobalString(SwarmUploadMimeType.Name) 56 client = swarm.NewClient(bzzapi) 57 toEncrypt = ctx.Bool(SwarmEncryptedFlag.Name) 58 file string 59 ) 60 61 if len(args) != 1 { 62 if fromStdin { 63 tmp, err := ioutil.TempFile("", "swarm-stdin") 64 if err != nil { 65 utils.Fatalf("error create tempfile: %s", err) 66 } 67 defer os.Remove(tmp.Name()) 68 n, err := io.Copy(tmp, os.Stdin) 69 if err != nil { 70 utils.Fatalf("error copying stdin to tempfile: %s", err) 71 } else if n == 0 { 72 utils.Fatalf("error reading from stdin: zero length") 73 } 74 file = tmp.Name() 75 } else { 76 utils.Fatalf("Need filename as the first and only argument") 77 } 78 } else { 79 file = expandPath(args[0]) 80 } 81 82 if !wantManifest { 83 f, err := swarm.Open(file) 84 if err != nil { 85 utils.Fatalf("Error opening file: %s", err) 86 } 87 defer f.Close() 88 hash, err := client.UploadRaw(f, f.Size, toEncrypt) 89 if err != nil { 90 utils.Fatalf("Upload failed: %s", err) 91 } 92 fmt.Println(hash) 93 return 94 } 95 96 stat, err := os.Stat(file) 97 if err != nil { 98 utils.Fatalf("Error opening file: %s", err) 99 } 100 101 // 102 //根据上传文件的类型 103 var doUpload func() (hash string, err error) 104 if stat.IsDir() { 105 doUpload = func() (string, error) { 106 if !recursive { 107 return "", errors.New("Argument is a directory and recursive upload is disabled") 108 } 109 if defaultPath != "" { 110 //构造绝对默认路径 111 absDefaultPath, _ := filepath.Abs(defaultPath) 112 absFile, _ := filepath.Abs(file) 113 // 114 //从绝对默认路径修剪它并获取相对默认路径 115 absFile = strings.TrimRight(absFile, "/") + "/" 116 if absDefaultPath != "" && absFile != "" && strings.HasPrefix(absDefaultPath, absFile) { 117 defaultPath = strings.TrimPrefix(absDefaultPath, absFile) 118 } 119 } 120 return client.UploadDirectory(file, defaultPath, "", toEncrypt) 121 } 122 } else { 123 doUpload = func() (string, error) { 124 f, err := swarm.Open(file) 125 if err != nil { 126 return "", fmt.Errorf("error opening file: %s", err) 127 } 128 defer f.Close() 129 if mimeType == "" { 130 mimeType = detectMimeType(file) 131 } 132 f.ContentType = mimeType 133 return client.Upload(f, "", toEncrypt) 134 } 135 } 136 hash, err := doUpload() 137 if err != nil { 138 utils.Fatalf("Upload failed: %s", err) 139 } 140 fmt.Println(hash) 141 } 142 143 //展开文件路径 144 //1。用用户主目录替换tilde 145 //2。扩展嵌入的环境变量 146 //三。清理路径,例如/a/b/。/c->/a/c 147 //注意,它有局限性,例如~someuser/tmp将不会扩展 148 func expandPath(p string) string { 149 if strings.HasPrefix(p, "~/") || strings.HasPrefix(p, "~\\") { 150 if home := homeDir(); home != "" { 151 p = home + p[1:] 152 } 153 } 154 return path.Clean(os.ExpandEnv(p)) 155 } 156 157 func homeDir() string { 158 if home := os.Getenv("HOME"); home != "" { 159 return home 160 } 161 if usr, err := user.Current(); err == nil { 162 return usr.HomeDir 163 } 164 return "" 165 } 166 167 func detectMimeType(file string) string { 168 if ext := filepath.Ext(file); ext != "" { 169 return mime.TypeByExtension(ext) 170 } 171 f, err := os.Open(file) 172 if err != nil { 173 return "" 174 } 175 defer f.Close() 176 buf := make([]byte, 512) 177 if n, _ := f.Read(buf); n > 0 { 178 return http.DetectContentType(buf) 179 } 180 return "" 181 }