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.

104 lines
2.6 KiB

  1. package main
  2. import (
  3. "fmt"
  4. "io"
  5. "io/ioutil"
  6. "os"
  7. "path"
  8. "strings"
  9. "github.com/chrislusf/seaweedfs/go/operation"
  10. "github.com/chrislusf/seaweedfs/go/util"
  11. )
  12. var (
  13. d DownloadOptions
  14. )
  15. type DownloadOptions struct {
  16. server *string
  17. dir *string
  18. }
  19. func init() {
  20. cmdDownload.Run = runDownload // break init cycle
  21. d.server = cmdDownload.Flag.String("server", "localhost:9333", "SeaweedFS master location")
  22. d.dir = cmdDownload.Flag.String("dir", ".", "Download the whole folder recursively if specified.")
  23. }
  24. var cmdDownload = &Command{
  25. UsageLine: "download -server=localhost:9333 -dir=one_directory fid1 [fid2 fid3 ...]",
  26. Short: "download files by file id",
  27. Long: `download files by file id.
  28. Usually you just need to use curl to lookup the file's volume server, and then download them directly.
  29. This download tool combine the two steps into one.
  30. What's more, if you use "weed upload -maxMB=..." option to upload a big file divided into chunks, you can
  31. use this tool to download the chunks and merge them automatically.
  32. `,
  33. }
  34. func runDownload(cmd *Command, args []string) bool {
  35. for _, fid := range args {
  36. filename, content, e := fetchFileId(*d.server, fid)
  37. if e != nil {
  38. fmt.Println("Fetch Error:", e)
  39. continue
  40. }
  41. if filename == "" {
  42. filename = fid
  43. }
  44. if strings.HasSuffix(filename, "-list") {
  45. filename = filename[0 : len(filename)-len("-list")]
  46. fids := strings.Split(string(content), "\n")
  47. f, err := os.OpenFile(path.Join(*d.dir, filename), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.ModePerm)
  48. if err != nil {
  49. fmt.Println("File Creation Error:", e)
  50. continue
  51. }
  52. defer f.Close()
  53. for _, partId := range fids {
  54. var n int
  55. _, part, err := fetchFileId(*d.server, partId)
  56. if err == nil {
  57. n, err = f.Write(part)
  58. }
  59. if err == nil && n < len(part) {
  60. err = io.ErrShortWrite
  61. }
  62. if err != nil {
  63. fmt.Println("File Write Error:", err)
  64. break
  65. }
  66. }
  67. } else {
  68. ioutil.WriteFile(path.Join(*d.dir, filename), content, os.ModePerm)
  69. }
  70. }
  71. return true
  72. }
  73. func fetchFileId(server string, fileId string) (filename string, content []byte, e error) {
  74. fileUrl, lookupError := operation.LookupFileId(server, fileId)
  75. if lookupError != nil {
  76. return "", nil, lookupError
  77. }
  78. filename, content, e = util.DownloadUrl(fileUrl)
  79. return
  80. }
  81. func WriteFile(filename string, data []byte, perm os.FileMode) error {
  82. f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
  83. if err != nil {
  84. return err
  85. }
  86. n, err := f.Write(data)
  87. f.Close()
  88. if err == nil && n < len(data) {
  89. err = io.ErrShortWrite
  90. }
  91. return err
  92. }