aboutsummaryrefslogtreecommitdiff
path: root/cmd/web/install.go
diff options
context:
space:
mode:
authorMitch Riedstra <mitch@riedstra.us>2021-01-09 15:22:27 -0500
committerMitch Riedstra <mitch@riedstra.us>2021-01-09 15:22:27 -0500
commit602790e2ca33ad7f22235bf2ae548cef7db8b814 (patch)
treef79fc9a7f6e019a3f2a774e13d030937b3ae9f86 /cmd/web/install.go
parente31c9168627c040317e5cc8566724f88910439ae (diff)
downloadsteam-export-602790e2ca33ad7f22235bf2ae548cef7db8b814.tar.gz
steam-export-602790e2ca33ad7f22235bf2ae548cef7db8b814.tar.xz
Add a progress bar to the UI for installation via HTTP. Uses polling, but whatever.
Diffstat (limited to 'cmd/web/install.go')
-rw-r--r--cmd/web/install.go57
1 files changed, 53 insertions, 4 deletions
diff --git a/cmd/web/install.go b/cmd/web/install.go
index 678037a..d9a2379 100644
--- a/cmd/web/install.go
+++ b/cmd/web/install.go
@@ -3,9 +3,11 @@ package main
import (
"encoding/json"
"fmt"
+ "io"
"net/http"
"net/url"
"os"
+ "strconv"
"strings"
"sync"
"time"
@@ -36,6 +38,8 @@ func statsHandler(w http.ResponseWriter, r *http.Request) {
status.m.RLock()
defer status.m.RUnlock()
+ w.Header().Add("Content-type", "application/json")
+
enc := json.NewEncoder(w)
err := enc.Encode(status.s)
@@ -52,12 +56,57 @@ func installHttp(u string) error {
return fmt.Errorf("Installer: getting %w", err)
}
- err = Lib.Extract(resp.Body)
+ estSize, err := strconv.ParseInt(resp.Header.Get("Estimated-size"), 10, 64)
if err != nil {
- return fmt.Errorf("Installer: extracting %w", err)
+ return fmt.Errorf("Failed to convert estimated size header: %w", err)
}
- resp.Body.Close()
- return nil
+
+ status.m.Lock()
+ status.s.Size = estSize
+ status.m.Unlock()
+
+ rdr, wrtr := io.Pipe()
+
+ go func() {
+ err = Lib.Extract(rdr)
+ if err != nil {
+ Logger.Printf("Installer: extracting %w", err)
+ }
+ resp.Body.Close()
+ }()
+
+ var total int64
+ start := time.Now()
+ status.m.Lock()
+ status.s.Start = &start
+ status.m.Unlock()
+ for {
+ var n int64
+ n, err = io.CopyN(wrtr, resp.Body, 100*1024*1024)
+ if err == io.EOF {
+ break
+ } else if err != nil {
+ Logger.Printf("Error encountered read from response body in installer: %s", err)
+ break
+ }
+
+ total += n
+ mb := float64(total / 1024 / 1024)
+ rate := mb / time.Since(start).Seconds()
+
+ Logger.Printf("Downloading from %s, Size: %s, %0.1f%% Done, Rate: %.2f mb/s",
+ u, formatBytes(estSize), float64(total)/float64(estSize)*100, rate)
+
+ status.m.Lock()
+ status.s.Transferred = total
+ status.m.Unlock()
+ }
+
+ if err == io.EOF {
+ return nil
+ }
+
+ return err
}
func installPath(p string) error {