diff options
-rw-r--r-- | derelict.go | 54 | ||||
-rw-r--r-- | models.go | 9 | ||||
-rw-r--r-- | recent.tmpl | 4 | ||||
-rw-r--r-- | storage.go | 51 |
4 files changed, 81 insertions, 37 deletions
diff --git a/derelict.go b/derelict.go index ef0b6c3..d084e49 100644 --- a/derelict.go +++ b/derelict.go @@ -1,9 +1,7 @@ package main import ( - "crypto/sha1" "embed" - "encoding/hex" "encoding/json" "html/template" "io/ioutil" @@ -11,7 +9,6 @@ import ( "net/http" "os" "regexp" - "sort" "github.com/gorilla/mux" ) @@ -23,21 +20,24 @@ var content embed.FS var internal embed.FS var ( + storage Storage templates *template.Template - root string - validToken *regexp.Regexp + validToken = regexp.MustCompile(`[a-fA-F0-9]+`) ) func main() { - initRoot() - - validToken = regexp.MustCompile(`[a-fA-F0-9]+`) + storage.Path = os.Getenv("DERELICTROOT") + if storage.Path == "" { + storage.Path = ".derelict" + } port := os.Getenv("DERELICTPORT") if port == "" { port = "8080" } + storage.MustInit() + templates = template.Must(template.ParseFS(internal, "*.tmpl")) router := mux.NewRouter() @@ -49,23 +49,13 @@ func main() { log.Fatal(http.ListenAndServe(":"+port, router)) } -func initRoot() { - root = os.Getenv("DERELICTROOT") - if root == "" { - root = ".derelict" - } - os.Mkdir(root, 0755) - os.Mkdir(root+"/battles", 0755) - os.Mkdir(root+"/tokens", 0700) -} - func handleBattlesPost(w http.ResponseWriter, r *http.Request) { token := r.Header.Get("Derelict-Token") if !validToken.MatchString(token) { http.Error(w, "Invalid token", http.StatusBadRequest) return } - _, err := os.Stat(root + "/tokens/" + token) + _, err := os.Stat(storage.Path + "/tokens/" + token) if _, ok := err.(*os.PathError); ok { http.Error(w, "Unauthorized", http.StatusUnauthorized) return @@ -85,32 +75,26 @@ func handleBattlesPost(w http.ResponseWriter, r *http.Request) { http.Error(w, "Error in body", http.StatusBadRequest) return } - hash := sha1.Sum(data) - name := hex.EncodeToString(hash[:]) - ioutil.WriteFile(root+"/battles/"+name, data, 0644) + name, err := storage.AddBattle(data) + if err != nil { + http.Error(w, "Error writing", http.StatusInternalServerError) + return + } w.WriteHeader(http.StatusOK) w.Write([]byte(name)) } func handleBattlesId(w http.ResponseWriter, r *http.Request) { - id := mux.Vars(r)["id"] - w.Header().Add("Content-Type", "application/json") - http.ServeFile(w, r, root+"/battles/"+id) + storage.ServeBattle(mux.Vars(r)["id"], w, r) } func handleRecent(w http.ResponseWriter, r *http.Request) { - files, err := ioutil.ReadDir(root + "/battles") + battles, err := storage.ListRecentBattles(10) if err != nil { - panic(err) - } - sort.Slice(files, func(lhs, rhs int) bool { - return files[lhs].ModTime().After(files[rhs].ModTime()) - }) - count := 10 - if count > len(files) { - count = len(files) + http.Error(w, "Error getting recent battles", http.StatusInternalServerError) + return } - templates.ExecuteTemplate(w, "recent", files[:count]) + templates.ExecuteTemplate(w, "recent", battles) } func handleView(w http.ResponseWriter, r *http.Request) { @@ -1,5 +1,9 @@ package main +import ( + "time" +) + type Killmail struct { Id string `json:"id"` Hash string `json:"hash"` @@ -9,3 +13,8 @@ type Wreck struct { Killmail Team string `json:"team"` } + +type Battle struct { + Id string + Date time.Time +} diff --git a/recent.tmpl b/recent.tmpl index 4a64d58..b4ca11a 100644 --- a/recent.tmpl +++ b/recent.tmpl @@ -15,10 +15,10 @@ <table> {{range .}} <tr> - <td><a href="/view/{{.Name}}">{{.Name}}</a> + <td><a href="/view/{{.Id}}">{{.Id}}</a> <td>some wrecks <td>some grids - <td>{{.ModTime.Format "January 02, 2006 15:04 UTC"}} + <td>{{.Date.Format "January 02, 2006 15:04 UTC"}} {{end}} </table> <h2>About</h2> diff --git a/storage.go b/storage.go new file mode 100644 index 0000000..ec2d33e --- /dev/null +++ b/storage.go @@ -0,0 +1,51 @@ +package main + +import ( + "crypto/sha1" + "encoding/hex" + "io/ioutil" + "net/http" + "os" + "sort" +) + +type Storage struct { + Path string +} + +func (s *Storage) MustInit() error { + os.Mkdir(s.Path, 0755) + os.Mkdir(s.Path+"/battles", 0755) + os.Mkdir(s.Path+"/tokens", 0700) + return nil +} + +func (s *Storage) AddBattle(data []byte) (string, error) { + hash := sha1.Sum(data) + id := hex.EncodeToString(hash[:]) + return id, ioutil.WriteFile(s.Path+"/battles/"+id, data, 0644) +} + +func (s *Storage) ServeBattle(id string, w http.ResponseWriter, r *http.Request) { + w.Header().Add("Content-Type", "application/json") + http.ServeFile(w, r, s.Path+"/battles/"+id) +} + +func (s *Storage) ListRecentBattles(count int) ([]Battle, error) { + files, err := ioutil.ReadDir(s.Path + "/battles") + if err != nil { + return nil, err + } + + sort.Slice(files, func(lhs, rhs int) bool { + return files[lhs].ModTime().After(files[rhs].ModTime()) + }) + + battles := make([]Battle, 0, count) + + for i := 0; i < count && i < len(files); i++ { + battles = append(battles, Battle{Id: files[i].Name(), Date: files[i].ModTime()}) + } + + return battles, nil +} |