/
yaurtww.go
96 lines (77 loc) · 2.38 KB
/
yaurtww.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package yaurtww
import (
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"strconv"
"time"
"github.com/cheggaaa/pb"
flag "github.com/docker/docker/pkg/mflag"
)
// Manifest is the manifest provided by the urban terror site, and describes
// what assets are required and states the version of the game.
type Manifest struct {
Version string
Assets []ManifestAsset
}
// ManifestAsset is a single manifest, and contains a checksum and filename.
type ManifestAsset struct {
MD5Sum string
FileName string
}
// const CDNURL = "http://cdn.urbanterror.info/urt/%s/%s/q3ut4/%s"
const CDNURL = "http://cdn.urbanterror.info/urt/"
var (
// ManifestPath is the path to the manifest.
ManifestPath string
// DownloadPath points to the destination directory for download.
DownloadPath = flag.String([]string{"d", "-dest"}, "./", "Path to destination directory")
// Version prints the version of yaurtww
Version = flag.Bool([]string{"v", "-version"}, false, "Print the name and version")
)
func init() {
ManifestPath = flag.String([]string{"m", "-manifest"}, RequiredFlag("Manifest is required."), "Path to yaurtww manifest")
}
// RequiredFlag is a shim to print error messages for flags.
func RequiredFlag(ErrorMessage string) string {
// shim to trick the compiler so that we can actually call os.Exit(1) and
// print a helpful error message when a flag is required.
log.Fatalln(ErrorMessage)
return "requiredstring"
}
// ReadManifest reads the stored manifest and returns it as Manifest
func ReadManifest(path *string) (manifest *Manifest, err error) {
file, err := ioutil.ReadFile(*path)
return
}
// Download downloads the file.
func (asset ManifestAsset) Download(url string) (err error) {
var sourceSize int64
downloadPath := *DownloadPath + asset.FileName
assetURL := url + asset.FileName
resp, err := http.Get(assetURL)
if err != nil {
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("Error getting %s: HTTP status %v", assetURL, resp.Status)
}
contentlength, _ := strconv.Atoi(resp.Header.Get("Content-Length"))
sourceSize = int64(contentlength)
file, err := os.Create(downloadPath)
if err != nil {
return
}
defer file.Close()
bar := pb.New(int(sourceSize)).SetUnits(pb.U_BYTES).SetRefreshRate(time.Millisecond * 10)
bar.ShowSpeed = true
bar.Start()
writer := io.MultiWriter(file, bar)
io.Copy(writer, resp.Body)
bar.Finish()
return
}