github.com/criteo/command-launcher@v0.0.0-20230407142452-fb616f546e98/internal/helper/file-loader.go (about) 1 package helper 2 3 import ( 4 "crypto/tls" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "net/http" 9 "os" 10 "strings" 11 "time" 12 13 grab "github.com/cavaliergopher/grab/v3" 14 ) 15 16 // Load file from http(s) or local disk 17 // Use http:// https:// as prefix for remote file 18 // Use file:// or no prefix for local file 19 func LoadFile(fileUrlOrPath string) ([]byte, error) { 20 location := fileUrlOrPath 21 if strings.HasPrefix(location, "http") { 22 return LoadFileFromUrl(location) 23 } 24 location = strings.TrimPrefix(location, "file://") 25 return ioutil.ReadFile(location) 26 } 27 28 // Load a file from a http(s) url 29 func LoadFileFromUrl(url string) ([]byte, error) { 30 resp, err := HttpGetWrapper(url) 31 if err != nil { 32 return nil, err 33 } 34 if resp.StatusCode != http.StatusOK { 35 return nil, fmt.Errorf("failed to download file from %s", url) 36 } 37 defer resp.Body.Close() 38 39 return ioutil.ReadAll(resp.Body) 40 } 41 42 // Download file from http(s) or local disk 43 // Use http:// https:// as prefix for remote file 44 // Use file:// or no prefix for local file 45 func DownloadFile(fileUrlOrPath string, dest string, showProgress bool) error { 46 location := fileUrlOrPath 47 if strings.HasPrefix(location, "http") { 48 return DownloadFileFromUrl(location, dest, showProgress) 49 } 50 location = strings.TrimPrefix(location, "file://") 51 return CopyLocalFile(location, dest, showProgress) 52 } 53 54 func DownloadFileFromUrl(url string, dest string, showProgress bool) error { 55 client := grab.NewClient() 56 57 resolvedUrl, resolved := ResolveUrl(url) // fix mac OS issue 58 if resolved { 59 client.HTTPClient.(*http.Client).Transport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} 60 } 61 req, err := grab.NewRequest(dest, resolvedUrl) 62 if err != nil { 63 return fmt.Errorf("cannot get request from the server (%v)", err) 64 } 65 66 fmt.Println("Initializing download...") 67 resp := client.Do(req) 68 69 if showProgress { 70 t := time.NewTicker(500 * time.Millisecond) 71 defer t.Stop() 72 73 for !resp.IsComplete() { 74 select { 75 case <-t.C: 76 fmt.Printf("\033[1Atransferred %.2f%%\033[K\n", 100*resp.Progress()) 77 default: 78 } 79 } 80 81 // clear progress line 82 fmt.Printf("\033[1A\033[K") 83 } 84 85 // check for errors 86 if err := resp.Err(); err != nil { 87 fmt.Fprintf(os.Stderr, "Error downloading %s: %v\n", url, err) 88 return fmt.Errorf("error downloading %s: %v", url, err) 89 } 90 return nil 91 } 92 93 func CopyLocalFile(src string, dest string, showProgress bool) error { 94 sourceFileStat, err := os.Stat(src) 95 if err != nil { 96 return err 97 } 98 99 if !sourceFileStat.Mode().IsRegular() { 100 return fmt.Errorf("%s is not a regular file", src) 101 } 102 103 source, err := os.Open(src) 104 if err != nil { 105 return err 106 } 107 defer source.Close() 108 109 destination, err := os.Create(dest) 110 if err != nil { 111 return err 112 } 113 114 defer destination.Close() 115 116 // TODO: show progress here 117 _, err = io.Copy(destination, source) 118 119 return err 120 }