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  }