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.

121 lines
2.9 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. "strconv"
  12. )
  13. var uploadReplication *string
  14. func init() {
  15. cmdUpload.Run = runUpload // break init cycle
  16. cmdUpload.IsDebug = cmdUpload.Flag.Bool("debug", false, "verbose debug information")
  17. server = cmdUpload.Flag.String("server", "localhost:9333", "weedfs master location")
  18. uploadReplication = cmdUpload.Flag.String("replication", "000", "replication type(000,001,010,100,110,200)")
  19. }
  20. var cmdUpload = &Command{
  21. UsageLine: "upload -server=localhost:9333 file1 [file2 file3]",
  22. Short: "upload one or a list of files",
  23. Long: `upload one or a list of files.
  24. It uses consecutive file keys for the list of files.
  25. e.g. If the file1 uses key k, file2 can be read via k_1
  26. `,
  27. }
  28. type AssignResult struct {
  29. Fid string `json:"fid"`
  30. Url string `json:"url"`
  31. PublicUrl string `json:"publicUrl"`
  32. Count int
  33. Error string `json:"error"`
  34. }
  35. func assign(count int) (*AssignResult, error) {
  36. values := make(url.Values)
  37. values.Add("count", strconv.Itoa(count))
  38. values.Add("replication", *uploadReplication)
  39. jsonBlob, err := util.Post("http://"+*server+"/dir/assign", values)
  40. debug("assign result :", string(jsonBlob))
  41. if err != nil {
  42. return nil, err
  43. }
  44. var ret AssignResult
  45. err = json.Unmarshal(jsonBlob, &ret)
  46. if err != nil {
  47. return nil, err
  48. }
  49. if ret.Count <= 0 {
  50. return nil, errors.New(ret.Error)
  51. }
  52. return &ret, nil
  53. }
  54. func upload(filename string, server string, fid string) (int, error) {
  55. debug("Start uploading file:", filename)
  56. fh, err := os.Open(filename)
  57. if err != nil {
  58. debug("Failed to open file:", filename)
  59. return 0, err
  60. }
  61. fi, fiErr := fh.Stat()
  62. if fiErr != nil {
  63. debug("Failed to stat file:", filename)
  64. return 0, fiErr
  65. }
  66. ret, e := operation.Upload("http://"+server+"/"+fid+"?ts="+strconv.Itoa(int(fi.ModTime().Unix())), path.Base(filename), fh)
  67. if e != nil {
  68. return 0, e
  69. }
  70. return ret.Size, e
  71. }
  72. type SubmitResult struct {
  73. FileName string `json:"fileName"`
  74. FileUrl string `json:"fileUrl"`
  75. Fid string `json:"fid"`
  76. Size int `json:"size"`
  77. Error string `json:"error"`
  78. }
  79. func submit(files []string) []SubmitResult {
  80. ret, err := assign(len(files))
  81. if err != nil {
  82. fmt.Println(err)
  83. return nil
  84. }
  85. results := make([]SubmitResult, len(files))
  86. for index, file := range files {
  87. fid := ret.Fid
  88. if index > 0 {
  89. fid = fid + "_" + strconv.Itoa(index)
  90. }
  91. results[index].Size, err = upload(file, ret.PublicUrl, fid)
  92. if err != nil {
  93. fid = ""
  94. results[index].Error = err.Error()
  95. }
  96. results[index].FileName = file
  97. results[index].Fid = fid
  98. results[index].FileUrl = ret.PublicUrl + "/" + fid
  99. }
  100. return results
  101. }
  102. func runUpload(cmd *Command, args []string) bool {
  103. if len(cmdUpload.Flag.Args()) == 0 {
  104. return false
  105. }
  106. results := submit(args)
  107. bytes, _ := json.Marshal(results)
  108. fmt.Print(string(bytes))
  109. return true
  110. }