You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

144 lines
3.6 KiB

12 years ago
12 years ago
  1. package main
  2. import (
  3. "code.google.com/p/weed-fs/go/operation"
  4. "code.google.com/p/weed-fs/go/util"
  5. "encoding/json"
  6. "errors"
  7. "fmt"
  8. "net/url"
  9. "os"
  10. "path"
  11. "path/filepath"
  12. "strconv"
  13. )
  14. var (
  15. uploadReplication *string
  16. uploadDir *string
  17. )
  18. func init() {
  19. cmdUpload.Run = runUpload // break init cycle
  20. cmdUpload.IsDebug = cmdUpload.Flag.Bool("debug", false, "verbose debug information")
  21. server = cmdUpload.Flag.String("server", "localhost:9333", "weedfs master location")
  22. uploadDir = cmdUpload.Flag.String("dir", "", "Upload the whole folder recursively if specified.")
  23. uploadReplication = cmdUpload.Flag.String("replication", "000", "replication type(000,001,010,100,110,200)")
  24. }
  25. var cmdUpload = &Command{
  26. UsageLine: "upload -server=localhost:9333 file1 [file2 file3]\n upload -server=localhost:9333 -dir=one_directory",
  27. Short: "upload one or a list of files",
  28. Long: `upload one or a list of files, or batch upload one whole folder recursively.
  29. It uses consecutive file keys for the list of files.
  30. e.g. If the file1 uses key k, file2 can be read via k_1
  31. `,
  32. }
  33. type AssignResult struct {
  34. Fid string `json:"fid"`
  35. Url string `json:"url"`
  36. PublicUrl string `json:"publicUrl"`
  37. Count int
  38. Error string `json:"error"`
  39. }
  40. func assign(count int) (*AssignResult, error) {
  41. values := make(url.Values)
  42. values.Add("count", strconv.Itoa(count))
  43. values.Add("replication", *uploadReplication)
  44. jsonBlob, err := util.Post("http://"+*server+"/dir/assign", values)
  45. debug("assign result :", string(jsonBlob))
  46. if err != nil {
  47. return nil, err
  48. }
  49. var ret AssignResult
  50. err = json.Unmarshal(jsonBlob, &ret)
  51. if err != nil {
  52. return nil, err
  53. }
  54. if ret.Count <= 0 {
  55. return nil, errors.New(ret.Error)
  56. }
  57. return &ret, nil
  58. }
  59. func upload(filename string, server string, fid string) (int, error) {
  60. debug("Start uploading file:", filename)
  61. fh, err := os.Open(filename)
  62. if err != nil {
  63. debug("Failed to open file:", filename)
  64. return 0, err
  65. }
  66. fi, fiErr := fh.Stat()
  67. if fiErr != nil {
  68. debug("Failed to stat file:", filename)
  69. return 0, fiErr
  70. }
  71. ret, e := operation.Upload("http://"+server+"/"+fid+"?ts="+strconv.Itoa(int(fi.ModTime().Unix())), path.Base(filename), fh)
  72. if e != nil {
  73. return 0, e
  74. }
  75. return ret.Size, e
  76. }
  77. type SubmitResult struct {
  78. FileName string `json:"fileName"`
  79. FileUrl string `json:"fileUrl"`
  80. Fid string `json:"fid"`
  81. Size int `json:"size"`
  82. Error string `json:"error"`
  83. }
  84. func submit(files []string) ([]SubmitResult, error) {
  85. results := make([]SubmitResult, len(files))
  86. for index, file := range files {
  87. results[index].FileName = file
  88. }
  89. ret, err := assign(len(files))
  90. if err != nil {
  91. for index, _ := range files {
  92. results[index].Error = err.Error()
  93. }
  94. return results, err
  95. }
  96. for index, file := range files {
  97. fid := ret.Fid
  98. if index > 0 {
  99. fid = fid + "_" + strconv.Itoa(index)
  100. }
  101. results[index].Size, err = upload(file, ret.PublicUrl, fid)
  102. if err != nil {
  103. fid = ""
  104. results[index].Error = err.Error()
  105. }
  106. results[index].Fid = fid
  107. results[index].FileUrl = ret.PublicUrl + "/" + fid
  108. }
  109. return results, nil
  110. }
  111. func runUpload(cmd *Command, args []string) bool {
  112. if len(cmdUpload.Flag.Args()) == 0 {
  113. if *uploadDir == "" {
  114. return false
  115. }
  116. filepath.Walk(*uploadDir, func(path string, info os.FileInfo, err error) error {
  117. if !info.IsDir() {
  118. results, e := submit([]string{path})
  119. bytes, _ := json.Marshal(results)
  120. fmt.Println(string(bytes))
  121. if e != nil {
  122. return e
  123. }
  124. }
  125. return err
  126. })
  127. } else {
  128. results, _ := submit(args)
  129. bytes, _ := json.Marshal(results)
  130. fmt.Println(string(bytes))
  131. }
  132. return true
  133. }