github.com/everdrone/grab@v0.1.7-0.20230416223925-40674b995521/internal/instance/download.go (about) 1 package instance 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "os" 7 "path/filepath" 8 "strings" 9 10 "github.com/everdrone/grab/internal/net" 11 "github.com/everdrone/grab/internal/utils" 12 "github.com/rs/zerolog/log" 13 14 "github.com/hashicorp/hcl/v2" 15 ) 16 17 func (s *Grab) Download() error { 18 if s.Flags.DryRun { 19 log.Warn().Msg("dry run, not downloading") 20 21 for _, site := range s.Config.Sites { 22 // do not print anything if the site does not download anything? 23 // if !site.HasMatches { 24 // continue 25 // } 26 27 for location, infoMap := range site.InfoMap { 28 log.Info().Fields(infoMap).Str("site", site.Name).Str("location", location).Msg("indexing") 29 } 30 31 for _, asset := range site.Assets { 32 for src, dst := range asset.Downloads { 33 rel, _ := filepath.Rel(s.Config.Global.Location, dst) 34 log.Info().Str("source", src).Str("destination", rel).Str("site", site.Name).Str("asset", asset.Name).Msg("downloading") 35 } 36 37 } 38 } 39 40 return nil 41 } 42 43 for _, site := range s.Config.Sites { 44 45 // MARK: - Download info file 46 47 for subdirectory, infoMap := range site.InfoMap { 48 // create directory 49 if err := utils.Fs.MkdirAll(subdirectory, os.ModePerm); err != nil { 50 return &hcl.Diagnostics{{ 51 Severity: hcl.DiagError, 52 Summary: "Failed to create directory", 53 Detail: fmt.Sprintf("%s: %s", subdirectory, err.Error()), 54 }} 55 } 56 57 marshaled, err := json.MarshalIndent(infoMap, "", " ") 58 if err != nil { 59 // this should never happen, since infoMap is encodable 60 return &hcl.Diagnostics{{ 61 Severity: hcl.DiagError, 62 Summary: "Failed to marshal info", 63 Detail: fmt.Sprintf("%+v: %s", infoMap, err.Error()), 64 }} 65 } 66 67 dst := filepath.Join(subdirectory, "_info.json") 68 69 log.Info().Str("destination", dst).Msg("indexing") 70 71 if err := utils.Io.WriteFile(utils.Fs, dst, marshaled, os.ModePerm); err != nil { 72 return &hcl.Diagnostics{{ 73 Severity: hcl.DiagError, 74 Summary: "Failed to write info file", 75 Detail: fmt.Sprintf("%s: %s", dst, err.Error()), 76 }} 77 } 78 } 79 80 // MARK: - Download asset files 81 82 for _, asset := range site.Assets { 83 for src, dst := range asset.Downloads { 84 // create directory 85 dir := filepath.Dir(dst) 86 if err := utils.Fs.MkdirAll(dir, os.ModePerm); err != nil { 87 return &hcl.Diagnostics{{ 88 Severity: hcl.DiagError, 89 Summary: "Failed to create directory", 90 Detail: fmt.Sprintf("%s: %s", dir, err.Error()), 91 }} 92 } 93 94 options := net.MergeFetchOptionsChain(s.Config.Global.Network, site.Network, asset.Network) 95 96 // log.Debug().Str("site", site.Name).Str("asset", asset.Name).Str("source", src).Interface("options", options).Msg("network options") 97 98 // check if file exists 99 performWrite := true 100 if exists, err := utils.Io.Exists(utils.Fs, dst); err != nil || exists { 101 performWrite = false 102 } 103 104 // if force or file does not exist, write to disk 105 if s.Flags.Force || performWrite { 106 log.Info().Str("url", src).Str("file", filepath.Base(dst)).Msg("downloading") 107 108 if err := net.Download(src, dst, options); err != nil { 109 // return now if we are in strict mode 110 if s.Flags.Strict { 111 log.Err(err).Str("source", src).Str("destination", strings.TrimPrefix(dst, s.Config.Global.Location)).Msg("failed to download asset") 112 return err 113 } else { 114 log.Err(err).Str("source", src).Str("destination", strings.TrimPrefix(dst, s.Config.Global.Location)).Msg("failed to download asset") 115 } 116 } 117 } else { 118 log.Warn().Str("destination", strings.TrimPrefix(dst, s.Config.Global.Location)).Msg("file already exists") 119 } 120 } 121 } 122 } 123 124 return nil 125 }