diff --git a/main.go b/main.go index ff42597..7c546d3 100644 --- a/main.go +++ b/main.go @@ -1,20 +1,16 @@ package main import ( - "context" "embed" "encoding/json" "flag" "fmt" "io/fs" "log" + "math/rand/v2" "net/http" - "os" - "os/signal" "runtime/debug" "strconv" - "sync" - "syscall" "time" "git.chandlerswift.com/chandlerswift/nau-sidewalks/sidewalk" @@ -23,32 +19,18 @@ import ( //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() { - devel := flag.Bool("devel", false, "Serve from ./static instead of embedded") port := flag.Int("port", 8000, "Port to listen on") - dataFile := flag.String("datafile", "", "File to read sidewalk data from (required)") flag.Parse() - if *dataFile == "" { - panic("datafile arg is required") - } - sidewalkData, err := os.ReadFile(*dataFile) - if err != nil { - panic(err) - } - - // Decode the JSON data - var sidewalks []sidewalk.Sidewalk - var sidewalksMutex sync.RWMutex - if err := json.Unmarshal(sidewalkData, &sidewalks); err != nil { - log.Fatalf("Error decoding JSON: %v", err) - } - sidewalksLen := len(sidewalks) - - // Serve static content - if *devel { + if DEVEL { http.Handle("GET /", http.FileServer(http.Dir("./static"))) } else { frontend, err := fs.Sub(embeddedFiles, "static") @@ -58,6 +40,16 @@ func main() { 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") @@ -66,70 +58,30 @@ func main() { http.HandleFunc("GET /api/sidewalks", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") - sidewalksMutex.RLock() json.NewEncoder(w).Encode(sidewalks) - sidewalksMutex.RUnlock() }) 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) - return } sidewalkID, err := strconv.Atoi(r.PathValue("id")) - if err != nil || sidewalkID < 0 || sidewalkID >= sidewalksLen { + 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) - return } - sidewalksMutex.Lock() sidewalks[sidewalkID].Condition = sidewalk.Condition(condition) sidewalks[sidewalkID].LastUpdated = time.Now() - sidewalksMutex.Unlock() http.Redirect(w, r, "/", http.StatusSeeOther) }) - server := &http.Server{Addr: fmt.Sprintf(":%v", *port)} - - go func() { - fmt.Printf("Serving %v sidewalks on :%v\n", sidewalksLen, *port) - if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { - log.Fatalf("HTTP server error: %v", err) - } - }() - - // Listen for OS termination signals - stop := make(chan os.Signal, 1) - signal.Notify(stop, os.Interrupt, syscall.SIGTERM) - <-stop // Block until signal is received - - fmt.Println("\nShutting down server...") - - // write out JSON - sidewalksMutex.RLock() - f, err := os.Create(*dataFile) - if err != nil { - panic(err) - } - defer f.Close() - err = json.NewEncoder(f).Encode(sidewalks) - if err != nil { - panic(err) - } - sidewalksMutex.RUnlock() - - // graceful shutdown - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - if err := server.Shutdown(ctx); err != nil { - log.Fatalf("Server forced to shutdown: %v", err) - } - + fmt.Printf("Serving on :%v\n", *port) + panic(http.ListenAndServe(fmt.Sprintf(":%v", *port), nil)) } func initializeBuildInfoJSON() { diff --git a/static/index.html b/static/index.html index 5041587..e09b26e 100644 --- a/static/index.html +++ b/static/index.html @@ -92,6 +92,19 @@ polyline.bindPopup(tagsContent+"
"+buttons); + // // Listen for popup open to attach event listeners + // polyline.on('popupopen', function(e) { + // document.querySelectorAll(".popup-btn").forEach(button => { + // button.addEventListener("click", async function(event) { + // const value = event.target.getAttribute("data-value"); + + // await fetch("/api/foo", { + // method: "POST", + // body: value + // }); + // }); + // }); + // }); } }) .catch(error => { @@ -101,6 +114,11 @@ const control = new L.Control.SimpleLocate({ position: "topleft", className: "button-locate", + afterClick: (result) => { + console.log("afterClick", result); + if (!result.geolocation) console.log("Geolocation Error"); + if (!result.orientation) console.log("Orientation Error"); + }, }).addTo(map);