aboutsummaryrefslogtreecommitdiff
path: root/cmd/web/handlers.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/web/handlers.go')
-rw-r--r--cmd/web/handlers.go207
1 files changed, 207 insertions, 0 deletions
diff --git a/cmd/web/handlers.go b/cmd/web/handlers.go
new file mode 100644
index 0000000..b8fa705
--- /dev/null
+++ b/cmd/web/handlers.go
@@ -0,0 +1,207 @@
+package main
+
+import (
+ "fmt"
+ "strings"
+ "net/url"
+ "os"
+ "encoding/json"
+ "io"
+ "net/http"
+ "time"
+
+ "github.com/gorilla/mux"
+ "riedstra.dev/mitch/steam-export/steam"
+)
+
+func (a *App) HandleIndex(w http.ResponseWriter, r *http.Request) {
+ // During rendering of the template I believe it's
+ // mutating during the sort of keys, so Lib no longer
+ // is an RWMutex and we're just locking this as if
+ // we're writing to it
+ a.Library.Lock()
+ defer a.Library.Unlock()
+ a.Status.Lock()
+ defer a.Status.Unlock()
+
+ err := a.Templates.ExecuteTemplate(w, "index",
+ struct {
+ Lib *steam.Library
+ Info *statusInfo
+ Local bool
+ HostIP string
+ Port string
+ Version string
+ }{
+ &a.Library.Library,
+ a.Status,
+ isLocal(r.RemoteAddr),
+ getHostIP(),
+ getPort(),
+ Version,
+ })
+ if err != nil {
+ Logger.Printf("While Rendering template: %s", err)
+ }
+ Logger.Printf("Client %s Index page", r.RemoteAddr)
+}
+
+func (a *App) HandleInstall(w http.ResponseWriter, r *http.Request) {
+ err := r.ParseForm()
+ if err != nil {
+ Logger.Printf("Installer: While parsing form: %s", err)
+ http.Error(w, fmt.Sprintf("Invalid form: %s", err), 400)
+ return
+ }
+
+ uri := r.Form.Get("uri")
+
+ if strings.HasPrefix(uri, "http") {
+ _, err := url.Parse(uri)
+ if err != nil {
+ Logger.Printf("Installer: While parsing url: %s", err)
+ http.Error(w, fmt.Sprintf("Invalid url: %s", err), 400)
+ return
+ }
+ } else {
+ fi, err := os.Stat(uri)
+ if err != nil || !fi.Mode().IsRegular() {
+ Logger.Printf("Installer: While parsing url/path: %s", err)
+ http.Error(w, fmt.Sprintf("Invalid uri/path: %s", err), 400)
+ return
+ }
+ }
+
+ Logger.Printf("Installer: Sending request for: %s to channel", uri)
+ a.download <- uri
+
+ http.Redirect(w, r, "/", 302)
+}
+
+func (a *App) HandleDownload(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ game := vars["game"]
+
+ a.Library.Lock()
+ g, ok := a.Library.Games[game]
+ a.Library.Unlock()
+ if !ok {
+ Logger.Printf("Missing: %s", game)
+ http.Error(w, "Game is missing", 404)
+ return
+ }
+
+ 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)
+
+ // 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)
+}
+
+func (a *App) HandleDelete(w http.ResponseWriter, r *http.Request) {
+ err := r.ParseForm()
+ if err != nil {
+ Logger.Printf("Installer: While parsing form: %s", err)
+ http.Error(w, fmt.Sprintf("Invalid form: %s", err), 400)
+ return
+ }
+
+ game := r.PostForm.Get("name")
+
+ if game == "" {
+ Logger.Println("Deleter: No game specified")
+ http.Error(w, "Game param required", 400)
+ return
+ }
+
+ a.Library.Lock()
+ g, ok := a.Library.Games[game]
+ a.Library.Unlock()
+ if !ok {
+ Logger.Printf("Missing: %s", game)
+ http.Error(w, "Game is missing", 404)
+ return
+ }
+
+ err = g.Delete()
+ if err != nil {
+ Logger.Printf("Error removing game: %s", err)
+ http.Error(w, fmt.Sprintf("Error removing game: %s", err), 500)
+ return
+ }
+ Logger.Printf("Removed game: %s", game)
+
+ a.LibraryReload()
+ http.Redirect(w, r, "/", 302)
+}
+
+func (a *App) HandleStats(w http.ResponseWriter, r *http.Request) {
+ a.Status.RLock()
+ defer a.Status.RUnlock()
+
+ w.Header().Add("Content-type", "application/json")
+
+ enc := json.NewEncoder(w)
+
+ err := enc.Encode(a.Status)
+ if err != nil {
+ Logger.Println("While encoding Status: ", err)
+ }
+ return
+}
+
+func (a *App) HandleSetLib(w http.ResponseWriter, r *http.Request) {
+ err := r.ParseForm()
+ if err != nil {
+ Logger.Printf("Setlib: While parsing form: %s", err)
+ http.Error(w, fmt.Sprintf("Invalid form: %s", err), 400)
+ return
+ }
+
+ a.LibrarySet(r.Form.Get("path"))
+
+ http.Redirect(w, r, "/", 302)
+}
+
+func HandleQuit(w http.ResponseWriter, r *http.Request) {
+ Logger.Println("Quit was called, exiting")
+ w.Header().Add("Content-type", "text/plain")
+ w.Write([]byte("Shutting down..."))
+ go func() {
+ time.Sleep(time.Second * 2)
+ os.Exit(0)
+ }()
+ return
+}
+