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
}