github.com/vektra/tachyon@v0.0.0-20150921164542-0da4f3861aef/download.go (about)

     1  package tachyon
     2  
     3  import (
     4  	"crypto/sha256"
     5  	"encoding/hex"
     6  	"fmt"
     7  	"io"
     8  	"net/http"
     9  	"os"
    10  )
    11  
    12  type DownloadCmd struct {
    13  	Url       string `tachyon:"url,required"`
    14  	Dest      string `tachyon:"dest"`
    15  	Sha256sum string `tachyon:"sha256sum"`
    16  	Once      bool   `tachyon:"once"`
    17  }
    18  
    19  func (d *DownloadCmd) Run(env *CommandEnv) (*Result, error) {
    20  	destPath := d.Dest
    21  
    22  	var out *os.File
    23  	var err error
    24  
    25  	if destPath == "" {
    26  		out, err = env.Env.TempFile("download")
    27  		destPath = out.Name()
    28  
    29  		if err != nil {
    30  			return nil, err
    31  		}
    32  	} else {
    33  		if d.Once {
    34  			fi, err := os.Stat(destPath)
    35  			if err == nil {
    36  				r := NewResult(false)
    37  				r.Data.Set("size", fi.Size())
    38  				r.Data.Set("path", destPath)
    39  
    40  				return r, nil
    41  			}
    42  		}
    43  
    44  		out, err = os.OpenFile(destPath, os.O_CREATE|os.O_WRONLY, 0644)
    45  		if err != nil {
    46  			return nil, err
    47  		}
    48  	}
    49  
    50  	defer out.Close()
    51  
    52  	resp, err := http.Get(d.Url)
    53  	if err != nil {
    54  		return nil, err
    55  	}
    56  
    57  	if resp.StatusCode/100 != 2 {
    58  		return nil, fmt.Errorf("Unable to download '%s', code: %d", d.Url, resp.StatusCode)
    59  	}
    60  
    61  	s := sha256.New()
    62  
    63  	tee := io.MultiWriter(out, s)
    64  
    65  	n, err := io.Copy(tee, resp.Body)
    66  	if err != nil {
    67  		return nil, err
    68  	}
    69  
    70  	r := NewResult(true)
    71  	r.Data.Set("size", n)
    72  	r.Data.Set("path", destPath)
    73  	r.Data.Set("sha256sum", hex.EncodeToString(s.Sum(nil)))
    74  
    75  	return r, nil
    76  }
    77  
    78  func init() {
    79  	RegisterCommand("download", &DownloadCmd{})
    80  }