aboutsummaryrefslogtreecommitdiff
path: root/cmd/web
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/web')
-rw-r--r--cmd/web/delete.go42
-rw-r--r--cmd/web/download.go31
-rw-r--r--cmd/web/flagSliceString.go12
-rw-r--r--cmd/web/index.go52
-rw-r--r--cmd/web/install.go116
-rw-r--r--cmd/web/main.go71
-rw-r--r--cmd/web/unix.go6
-rw-r--r--cmd/web/windows.go12
8 files changed, 290 insertions, 52 deletions
diff --git a/cmd/web/delete.go b/cmd/web/delete.go
new file mode 100644
index 0000000..7188b45
--- /dev/null
+++ b/cmd/web/delete.go
@@ -0,0 +1,42 @@
+package main
+
+import (
+ "fmt"
+ "net/http"
+)
+
+func gameDelete(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
+ }
+
+ libMu.RLock()
+ g, ok := Lib.Games[game]
+ libMu.RUnlock()
+ 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
+ }
+
+ reloadLib()
+ http.Redirect(w, r, "/", 302)
+}
diff --git a/cmd/web/download.go b/cmd/web/download.go
new file mode 100644
index 0000000..a640ea2
--- /dev/null
+++ b/cmd/web/download.go
@@ -0,0 +1,31 @@
+package main
+
+import (
+ "net/http"
+
+ "github.com/gorilla/mux"
+)
+
+func gameDownloader(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ game := vars["game"]
+
+ libMu.RLock()
+ g, ok := Lib.Games[game]
+ libMu.RUnlock()
+ if !ok {
+ Logger.Printf("Missing: %s", game)
+ http.Error(w, "Game is missing", 404)
+ return
+ }
+
+ w.Header().Add("Content-type", "application/tar")
+
+ err := g.Package(w)
+ if err != nil {
+ Logger.Printf("Error Sending game: %s", err)
+ // Headers already sent, don't bother sending an error
+ }
+
+}
+
diff --git a/cmd/web/flagSliceString.go b/cmd/web/flagSliceString.go
new file mode 100644
index 0000000..ec06966
--- /dev/null
+++ b/cmd/web/flagSliceString.go
@@ -0,0 +1,12 @@
+package main
+
+type FlagSliceString []string
+
+func (f *FlagSliceString) String() string {
+ return ""
+}
+
+func (f *FlagSliceString) Set(val string) error {
+ *f = append(*f, val)
+ return nil
+}
diff --git a/cmd/web/index.go b/cmd/web/index.go
index 1a2c344..2dfe20e 100644
--- a/cmd/web/index.go
+++ b/cmd/web/index.go
@@ -1,8 +1,10 @@
package main
import (
- "net/http"
"html/template"
+ "net/http"
+
+ "riedstra.dev/mitch/steam-export/steam"
)
var (
@@ -23,33 +25,71 @@ var (
</div>
</nav>
-<h2>Library: {{.Folder}}</h2>
+<h2>Library: {{.Lib.Folder}}</h2>
+
+{{ if .Info.Running }}
+<pre><code>
+Currently Downloading from: {{.Info.Url}}
+</pre></code>
+{{ end }}
+
+{{ if .Info.Error }}
+<pre><code>
+Error {{.Info.Error}} Downloading from: {{.Info.Url}}
+{{ end }}
+</pre></code>
<p>
Installed games:
+
+Tip: You can right click and save link as to specify a save location, e.g.
+an external hard drive
</p>
<ul>
-{{ range $key, $val := .Games }}
+{{ range $key, $val := .Lib.Games }}
<li>
<a href="/download/{{$key}}">{{$key}}</a>
</li>
{{ end }}
</ul>
-Install a game from a URL:
+Delete a game: ( Type out exact name, case sensitive )
+
+<form action="/delete" method="POST">
+ <input type="text" name="name" />
+ <input type="submit" value="Delete">
+</form>
+
+Install a game from a URL or local file path:
<form action="/install" method="GET">
- <input type="text" name="url" />
+ <input type="text" name="uri" />
<input type="submit" value="Install">
</form>
+<p>
+Note that You can also give someone a URL to install a game if they're running
+this program, e.g. <br />
+http://127.0.0.1:8899/install?uri=http://my-server-ip-or-hostname/download/My Game
+</p>
+
+
</body>
`))
)
func index(w http.ResponseWriter, r *http.Request) {
- err := Templ.ExecuteTemplate(w, "index", Lib)
+ libMu.RLock()
+ defer libMu.RUnlock()
+ status.m.RLock()
+ defer status.m.RUnlock()
+
+ err := Templ.ExecuteTemplate(w, "index",
+ struct {
+ Lib *steam.Library
+ Info *statusInfo
+ }{Lib, status.s})
if err != nil {
Logger.Printf("While Rendering template: %s", err)
}
diff --git a/cmd/web/install.go b/cmd/web/install.go
new file mode 100644
index 0000000..cd2f03a
--- /dev/null
+++ b/cmd/web/install.go
@@ -0,0 +1,116 @@
+package main
+
+import (
+ "net/url"
+ "os"
+ "strings"
+ "fmt"
+ "net/http"
+ "sync"
+)
+
+type statusInfo struct {
+ Running bool
+ Error error
+ Url string
+}
+
+var (
+ status = struct {
+ m *sync.RWMutex
+ s *statusInfo
+ }{
+ m: &sync.RWMutex{},
+ s: &statusInfo{Running: false},
+ }
+
+ getPath = make(chan string)
+)
+
+func installHttp(u string) error {
+ resp, err := http.Get(u)
+ if err != nil {
+ return fmt.Errorf("Installer: getting %w", err)
+ }
+
+ err = Lib.Extract(resp.Body)
+ if err != nil {
+ return fmt.Errorf("Installer: extracting %w", err)
+ }
+ resp.Body.Close()
+ return nil
+}
+
+func installPath(p string) error {
+ fh, err := os.Open(p)
+ if err != nil {
+ return fmt.Errorf("Installer: opening %w", err)
+ }
+
+ err = Lib.Extract(fh)
+ if err != nil {
+ return fmt.Errorf("Installer: opening %w", err)
+ }
+ fh.Close()
+ return nil
+}
+
+func installer(urls <-chan string) {
+ var err error
+ for u := range urls {
+ status.m.Lock()
+ status.s.Running = true
+ status.s.Url = u
+ status.m.Unlock()
+
+ if strings.HasPrefix(u, "http") {
+ err = installHttp(u)
+ } else {
+ err = installPath(u)
+ }
+
+ status.m.Lock()
+ status.s.Running = false
+ status.s.Error = err
+ status.m.Unlock()
+
+ reloadLib()
+ }
+}
+
+func gameInstaller(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 {
+ Logger.Printf("Installer: While parsing url: %s", err)
+ http.Error(w, fmt.Sprintf("Invalid uri/path: %s", err), 400)
+ return
+ }
+
+ if !fi.Mode().IsRegular() {
+ Logger.Printf("Installer: While parsing url: %s", err)
+ http.Error(w, fmt.Sprintf("Invalid uri/path: %s", err), 400)
+ return
+ }
+ }
+
+ getPath <- uri
+
+ http.Redirect(w, r, "/", 302)
+}
diff --git a/cmd/web/main.go b/cmd/web/main.go
index 93025e5..64321da 100644
--- a/cmd/web/main.go
+++ b/cmd/web/main.go
@@ -5,7 +5,7 @@ import (
"log"
"net/http"
"os"
- "path/filepath"
+ "sync"
"github.com/gorilla/mux"
"riedstra.dev/mitch/steam-export/steam"
@@ -15,75 +15,54 @@ var (
Logger = log.New(os.Stderr, "", log.LstdFlags)
Listen = ":8899"
- Lib = steam.NewLibraryMust(DefaultLib)
+ libMu = &sync.RWMutex{}
+ Lib *steam.Library
)
-//size, err := estimateSize(g.LibraryPath + "common/" + g.Name)
-//if err != nil {
-// http.Error(w, "Encountered:"+err, 500)
-// return
-//}
-func estimateSize(pth string) (int64, error) {
- var size int64 = 0
-
- err := filepath.Walk(pth, func(path string, info os.FileInfo, err error) error {
-
- if err != nil {
- return err
- }
-
- if info.Mode().IsRegular() {
- size = size + info.Size()
- }
-
- return nil
- })
-
- return size, err
-
-}
-
-func gameDownloader(w http.ResponseWriter, r *http.Request) {
- vars := mux.Vars(r)
- game := vars["game"]
-
- g, ok := Lib.Games[game]
- if !ok {
- Logger.Printf("Missing: %s", game)
- http.Error(w, "Game is missing", 404)
- return
- }
-
- w.Header().Add("Content-type", "application/tar")
-
- err := g.Package(w)
+func reloadLib() {
+ libMu.Lock()
+ defer libMu.Unlock()
+ var err error
+ Lib, err = steam.NewLibrary(DefaultLib)
if err != nil {
- Logger.Printf("Error Sending game: %s", err)
- // Headers already sent, don't bother sending an error
+ Logger.Printf("Error reopening library: %s", err)
+ return
}
-
}
func main() {
fl := flag.NewFlagSet("steam-export", flag.ExitOnError)
debug := fl.Bool("d", false, "Print line numbers in log")
- listen := fl.String("l", Listen, "What address do we listen on?")
+ fl.StringVar(&Listen, "l", Listen, "What address do we listen on?")
+ fl.StringVar(&DefaultLib, "L", DefaultLib, "Full path to default library")
fl.Parse(os.Args[1:])
if *debug {
Logger.SetFlags(log.LstdFlags | log.Llongfile)
}
+ var err error
+ Lib, err = steam.NewLibrary(DefaultLib)
+ if err != nil {
+ Logger.Fatalf("While opening library path: %s", err)
+ }
+
+ go installer(getPath)
+
r := mux.NewRouter()
+ r.HandleFunc("/delete", gameDelete)
+ r.HandleFunc("/install", gameInstaller)
r.HandleFunc("/download/{game}", gameDownloader)
r.HandleFunc("/style.css", cssHandler)
r.HandleFunc("/", index)
s := http.Server{
Handler: r,
- Addr: *listen,
+ Addr: Listen,
}
+ go startBrowser()
+
Logger.Fatal(s.ListenAndServe())
}
diff --git a/cmd/web/unix.go b/cmd/web/unix.go
index 6b1b1ae..bbe6087 100644
--- a/cmd/web/unix.go
+++ b/cmd/web/unix.go
@@ -8,3 +8,9 @@ import (
)
var DefaultLib string = filepath.Join(os.Getenv("HOME"), ".steam/steam/steamapps")
+
+// TODO
+func startBrowser() {
+ return
+}
+
diff --git a/cmd/web/windows.go b/cmd/web/windows.go
index 2effa08..9fe8ab6 100644
--- a/cmd/web/windows.go
+++ b/cmd/web/windows.go
@@ -2,4 +2,16 @@
package main
+import (
+ "os/exec"
+ "time"
+)
+
var DefaultLib string = `C:\Program Files (x86)\Steam\steamapps`
+
+func startBrowser() {
+ time.Sleep(time.Second*3)
+ c := exec.Command("cmd", "/c", "start", "http://127.0.0.1"+Listen)
+ Logger.Println(c.Run())
+}
+