package main import ( "embed" "encoding/json" "html/template" "log" "net/http" "os" "github.com/gorilla/mux" ) //go:embed *.css *.js media/brackets/*.png var content embed.FS //go:embed *.tmpl var internal embed.FS var ( storage Storage templates *template.Template ) func main() { 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() router.HandleFunc("/", handleRecent).Methods("GET") router.HandleFunc("/view/{id:[_0-9a-f]+}", handleView).Methods("GET") router.HandleFunc("/battles", handleBattlesPost).Methods("POST") router.HandleFunc("/battles/{id:[_0-9a-f]+}", handleBattlesId).Methods("GET") router.PathPrefix("/").Handler(http.FileServer(http.FS(content))) log.Fatal(http.ListenAndServe(":"+port, router)) } func handleBattlesPost(w http.ResponseWriter, r *http.Request) { authorized, err := storage.CanPost(r.Header.Get("Derelict-Token")) if err != nil { http.Error(w, "Invalid token", http.StatusBadRequest) return } if !authorized { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } decoder := json.NewDecoder(r.Body) var stub BattleStub if err := decoder.Decode(&stub); err != nil { http.Error(w, "Error reading stub", http.StatusBadRequest) return } var battle Battle err = battle.From(&stub) if err != nil { http.Error(w, "Error getting battle details", http.StatusInternalServerError) return } err = storage.AddBattle(&battle) if err != nil { http.Error(w, "Error writing battle", http.StatusInternalServerError) return } w.Write([]byte(battle.Id)) } func handleBattlesId(w http.ResponseWriter, r *http.Request) { storage.ServeBattle(mux.Vars(r)["id"], w, r) } func handleRecent(w http.ResponseWriter, r *http.Request) { battles, err := storage.ListRecentBattles(10) if err != nil { http.Error(w, "Error getting recent battles", http.StatusInternalServerError) return } templates.ExecuteTemplate(w, "recent", battles) } func handleView(w http.ResponseWriter, r *http.Request) { battle := Battle{Id: mux.Vars(r)["id"]} storage.LoadBattle(&battle) templates.ExecuteTemplate(w, "view", &battle) }