package main import ( _ "embed" "errors" "fmt" "io" "math/rand" "net/http" "os" "strings" ) //go:embed public/index.html var indexSrc string const PORT = 3000 const IMAGES_DIR = "images" var cachedImages []string func loadImages() error { imagesDir := fmt.Sprintf("public/%s", IMAGES_DIR) entries, err := os.ReadDir(imagesDir) if err != nil { return fmt.Errorf("ERROR: Failed to read public/%s directory: %w", IMAGES_DIR, err) } cachedImages = []string{} for _, entry := range entries { if !entry.IsDir() && strings.HasSuffix(entry.Name(), ".webp") { cachedImages = append(cachedImages, entry.Name()) } } fmt.Printf("OK: Loaded %d images\n", len(cachedImages)) return nil } func getPage(w http.ResponseWriter, r *http.Request) { imageName := cachedImages[rand.Intn(len(cachedImages))] imageURL := fmt.Sprintf("/%s/%s", IMAGES_DIR, imageName) src := strings.Replace(indexSrc, "{{ IMAGE_URL }}", imageURL, 1) io.WriteString(w, src) } func getFavicon(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "public/favicon.ico") } func main() { if err := loadImages(); err != nil { fmt.Printf("ERROR: Error loading images: %s\n", err) os.Exit(1) } if len(cachedImages) == 0 { fmt.Printf("ERROR: no images found in public/%s\n", IMAGES_DIR) os.Exit(1) } http.HandleFunc("/", getPage) http.HandleFunc("/favicon.ico", getFavicon) http.Handle(fmt.Sprintf("/%s/", IMAGES_DIR), http.StripPrefix(fmt.Sprintf("/%s/", IMAGES_DIR), http.FileServer(http.Dir(fmt.Sprintf("public/%s", IMAGES_DIR))))) fmt.Printf("OK: Listening on port %d\n", PORT) err := http.ListenAndServe(fmt.Sprintf(":%d", PORT), nil) if errors.Is(err, http.ErrServerClosed) { fmt.Printf("OK: Server closed\n") } else if err != nil { fmt.Printf("ERROR: error starting server: %s\n", err) os.Exit(1) } }