diff options
| author | Mitch Riedstra <mitch@riedstra.us> | 2021-01-09 00:49:16 -0500 |
|---|---|---|
| committer | Mitch Riedstra <mitch@riedstra.us> | 2021-01-09 00:49:16 -0500 |
| commit | e31c9168627c040317e5cc8566724f88910439ae (patch) | |
| tree | 0ce4b3de81adfe8f9af56c498a969a8a2be44280 /cmd | |
| parent | d762cdbae06efd194ffac7b976c16aac21a26f94 (diff) | |
| download | steam-export-e31c9168627c040317e5cc8566724f88910439ae.tar.gz steam-export-e31c9168627c040317e5cc8566724f88910439ae.tar.xz | |
Add some download stats, and a status endpoint.
Diffstat (limited to 'cmd')
| -rw-r--r-- | cmd/web/download.go | 41 | ||||
| -rw-r--r-- | cmd/web/install.go | 31 | ||||
| -rw-r--r-- | cmd/web/main.go | 1 |
3 files changed, 61 insertions, 12 deletions
diff --git a/cmd/web/download.go b/cmd/web/download.go index 93c4ff5..1c70717 100644 --- a/cmd/web/download.go +++ b/cmd/web/download.go @@ -1,7 +1,10 @@ package main import ( + "io" "net/http" + "time" + "fmt" "github.com/gorilla/mux" ) @@ -20,14 +23,40 @@ func gameDownloader(w http.ResponseWriter, r *http.Request) { } w.Header().Add("Content-type", "application/tar") + w.Header().Add("Estimated-size", fmt.Sprintf("%d", g.Size)) Logger.Printf("Client %s is downloading: %s", r.RemoteAddr, game) - err := g.Package(w) - if err != nil { - Logger.Printf("Client %s Error Sending game: %s", r.RemoteAddr, err) - // Headers already sent, don't bother sending an error - return + + // Invert the writer so we can break up the copy and get progress + // information in here + rdr, pwrtr := io.Pipe() + go func() { + err := g.Package(pwrtr) + if err != nil { + Logger.Println("Error in package writing: ", err) + } + }() + + var total int64 + + start := time.Now() + for { + n, err := io.CopyN(w, rdr, 256*1024*1024) + if err == io.EOF { + break + } + if err != nil { + Logger.Printf("Client %s Error Sending game: %s", r.RemoteAddr, err) + // Headers already sent, don't bother sending an error + return + } + total += n + mb := float64(total / 1024 / 1024) + rate := mb / time.Since(start).Seconds() + + Logger.Printf("Client %s is downloading %s: %0.1f%% done %.2f mb/s", + r.RemoteAddr, game, float64(total)/float64(g.Size)*100, rate) } + Logger.Printf("Client %s finished downloading: %s", r.RemoteAddr, game) } - diff --git a/cmd/web/install.go b/cmd/web/install.go index 63faaf6..678037a 100644 --- a/cmd/web/install.go +++ b/cmd/web/install.go @@ -1,18 +1,23 @@ package main import ( + "encoding/json" + "fmt" + "net/http" "net/url" "os" "strings" - "fmt" - "net/http" "sync" + "time" ) type statusInfo struct { - Running bool - Error error - Url string + Running bool + Error error + Url string + Transferred int64 + Size int64 + Start *time.Time } var ( @@ -27,6 +32,19 @@ var ( getPath = make(chan string) ) +func statsHandler(w http.ResponseWriter, r *http.Request) { + status.m.RLock() + defer status.m.RUnlock() + + enc := json.NewEncoder(w) + + err := enc.Encode(status.s) + if err != nil { + Logger.Println("While encoding status: ", err) + } + return +} + func installHttp(u string) error { Logger.Println("Installer: loading from url") resp, err := http.Get(u) @@ -57,6 +75,8 @@ func installPath(p string) error { return nil } +// installer handles installing games either from a local path or a +// remote URL func installer(urls <-chan string) { var err error for u := range urls { @@ -87,7 +107,6 @@ func gameInstaller(w http.ResponseWriter, r *http.Request) { return } - err := r.ParseForm() if err != nil { Logger.Printf("Installer: While parsing form: %s", err) diff --git a/cmd/web/main.go b/cmd/web/main.go index 0f76670..a16f15f 100644 --- a/cmd/web/main.go +++ b/cmd/web/main.go @@ -153,6 +153,7 @@ func main() { r.HandleFunc("/install", gameInstaller) r.HandleFunc("/steam-export-web.exe", serveSelf) r.HandleFunc("/download/{game}", gameDownloader) + r.HandleFunc("/status", statsHandler) r.HandleFunc("/style.css", cssHandler) r.HandleFunc("/", index) |
