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  }