package main import ( "embed" "encoding/json" "flag" "fmt" "io/fs" "log" "math/rand/v2" "net/http" "runtime/debug" "strconv" "time" "git.chandlerswift.com/chandlerswift/nau-sidewalks/sidewalk" ) //go:embed static var embeddedFiles embed.FS //go:embed data/sidewalks.json var sidewalk_data []byte var buildInfoJSON []byte const DEVEL = false // serve files from dev dir, not embedded, so I don't have to rebuild the app every time func main() { port := flag.Int("port", 8000, "Port to listen on") flag.Parse() if DEVEL { http.Handle("GET /", http.FileServer(http.Dir("./static"))) } else { frontend, err := fs.Sub(embeddedFiles, "static") if err != nil { panic(err) } http.Handle("GET /", http.FileServer(http.FS(frontend))) } // Decode the JSON data var sidewalks []sidewalk.Sidewalk if err := json.Unmarshal(sidewalk_data, &sidewalks); err != nil { log.Fatalf("Error decoding JSON: %v", err) } for i := range sidewalks { sidewalks[i].Condition = sidewalk.Condition(rand.IntN(4)) } initializeBuildInfoJSON() http.HandleFunc("GET /api/version", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.Write(buildInfoJSON) }) http.HandleFunc("GET /api/sidewalks", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(sidewalks) }) http.HandleFunc("POST /api/sidewalks/{id}", func(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err != nil { http.Error(w, "Could not parse form", http.StatusInternalServerError) } sidewalkID, err := strconv.Atoi(r.PathValue("id")) if err != nil { http.Error(w, "Invalid id", http.StatusBadRequest) return } condition, err := strconv.Atoi(r.Form.Get("condition")) if err != nil { http.Error(w, "Invalid condition", http.StatusBadRequest) } sidewalks[sidewalkID].Condition = sidewalk.Condition(condition) sidewalks[sidewalkID].LastUpdated = time.Now() http.Redirect(w, r, "/", http.StatusSeeOther) }) fmt.Printf("Serving on :%v\n", *port) panic(http.ListenAndServe(fmt.Sprintf(":%v", *port), nil)) } func initializeBuildInfoJSON() { rawBuildInfo, _ := debug.ReadBuildInfo() var revision, time string var dirty bool for _, buildSetting := range rawBuildInfo.Settings { if buildSetting.Key == "vcs.revision" { revision = buildSetting.Value } else if buildSetting.Key == "vcs.time" { time = buildSetting.Value } else if buildSetting.Key == "vcs.modified" { dirty = buildSetting.Value == "true" } } buildInfo := map[string]interface{}{ "GitRev": revision, "GitDirty": dirty, "GitTime": time, "GoVersion": rawBuildInfo.GoVersion, "AllBuildInfo": rawBuildInfo.String(), } var err error buildInfoJSON, err = json.Marshal(buildInfo) if err != nil { panic(err) } }