package main import ( "fmt" "strconv" "strings" "html/template" "net/http" "os" "os/exec" "path/filepath" "log" "runtime" "sync" ) type Image struct { Name string Filename string Liked bool } var images []Image var currIndex int = 0 var imagesPerPage int = 4 func openbrowser(url string) { var err error switch runtime.GOOS { case "linux": err = exec.Command("xdg-open", url).Start() case "windows": err = exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start() case "darwin": err = exec.Command("open", url).Start() default: err = fmt.Errorf("unsupported platform") } if err != nil { log.Fatal(err) } } var funcMap = template.FuncMap{ "minus": minus, } func minus(a, b int) string { return strconv.FormatInt(int64(a-b), 10) } func main() { jpgs_path := "jpgs" http.HandleFunc("/", indexHandler) http.HandleFunc("/select", likeHandler) http.HandleFunc("/remove", removeHandler) http.HandleFunc("/removefav", removeFavsHandler) http.HandleFunc("/next", nextHandler) http.HandleFunc("/prev", prevHandler) http.HandleFunc("/favs", favsHandler) http.HandleFunc("/jpgs/", serveImage) http.Handle("/static/", http.FileServer(http.Dir("."))) filepath.Walk(jpgs_path, func(path string, info os.FileInfo, err error) error { if filepath.Ext(path) == ".jpg" || filepath.Ext(path) == ".JPG" { base := filepath.Base(path) name := base[:len(base)-len(filepath.Ext(base))] images = append(images, Image{name, filepath.ToSlash(path), false}) } return nil }) var wg sync.WaitGroup port := "42069" fmt.Println("Serving on http://localhost:" + port) wg.Add(1) go http.ListenAndServe(":" + port, nil) openbrowser("http://localhost:" + port) wg.Wait() } func serveImage(w http.ResponseWriter, r *http.Request) { filename := r.URL.Path[1:] http.ServeFile(w, r, filename) } func indexHandler(w http.ResponseWriter, r *http.Request) { tmpl, _ := template.ParseFiles("grid.html") idx := r.URL.Query().Get("idx") if len(idx) != 0 { tmp, _ := strconv.Atoi(idx) if tmp - 1 > len(images) { currIndex = len(images) - 1 } else if tmp >= 1 { currIndex = tmp - 1 } else { currIndex = 0 } } name := r.URL.Query().Get("name") if len(name) != 0 { for idx, i := range images { if (strings.Contains(i.Name, name)) { currIndex = idx; reload(w, r) return } } } imagesToShow := images[currIndex:min(currIndex+imagesPerPage, len(images))] err := tmpl.Execute(w, imagesToShow) if err != nil { log.Fatal(err) } } func reload(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/?idx="+strconv.Itoa(currIndex + 1), http.StatusFound) } func likeHandler(w http.ResponseWriter, r *http.Request) { visibleImages := images[currIndex:min(currIndex+imagesPerPage, len(images))] index := r.URL.Query().Get("img_index") i, _ := strconv.Atoi(index) visibleImages[i].Liked = true reload(w, r) } func removeHandler(w http.ResponseWriter, r *http.Request) { visibleImages := images[currIndex:min(currIndex+imagesPerPage, len(images))] index := r.URL.Query().Get("img_index") i, _ := strconv.Atoi(index) visibleImages[i].Liked = false reload(w, r) } func nextHandler(w http.ResponseWriter, r *http.Request) { currIndex += imagesPerPage if currIndex >= len(images) { currIndex = len(images) - imagesPerPage } reload(w, r) } func prevHandler(w http.ResponseWriter, r *http.Request) { currIndex -= imagesPerPage if currIndex < 0 { currIndex = 0 } reload(w, r) } func removeFavsHandler(w http.ResponseWriter, r *http.Request) { filename := r.URL.Query().Get("filename") for i := range images { if images[i].Filename == filename { images[i].Liked = false } } http.Redirect(w, r, "/favs", http.StatusFound) } func favsHandler(w http.ResponseWriter, r *http.Request) { tmpl, _ := template.New("favs.html").Funcs(funcMap).ParseFiles("favs.html") var liked []Image for _, i := range images { if i.Liked { liked = append(liked, i) } } err := tmpl.Execute(w, liked) if err != nil { log.Fatal(err) } } func min(a, b int) int { if a < b { return a } return b }