2025-02-11 00:14:58 -06:00
|
|
|
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) {
|
2025-02-12 22:32:28 -06:00
|
|
|
w.Header().Set("Content-Type", "application/json")
|
2025-02-11 00:14:58 -06:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|