wallart-server/cmd/wallart-server/main.go

120 lines
2.6 KiB
Go

package main
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"image/png"
"net/http"
"os"
"path"
"strings"
"github.com/kettek/apng"
)
var cacheDirectory string
func handleUpload(w http.ResponseWriter, r *http.Request) {
inf, header, err := r.FormFile("image")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer inf.Close()
if !strings.HasSuffix(header.Filename, ".pixil") {
http.Error(w, "Invalid file type", http.StatusBadRequest)
return
}
var pixil Pixil
if err := json.NewDecoder(inf).Decode(&pixil); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if pixil.Width != 8 || pixil.Height != 8 {
http.Error(w, "Invalid image size", http.StatusBadRequest)
return
}
outRaw, err := os.Create(path.Join(cacheDirectory, "wallart.bin"))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer outRaw.Close()
outPng, err := os.Create(path.Join(cacheDirectory, "wallart.png"))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer outPng.Close()
// You only get 8 frames max
numFrames := len(pixil.Frames)
if numFrames > 8 {
numFrames = 8
}
outImage := apng.APNG{
Frames: make([]apng.Frame, len(pixil.Frames)),
}
for i := 0; i < numFrames; i++ {
frame := pixil.Frames[i]
preview := frame.GetPreview()
if preview == nil {
http.Error(w, "Invalid frame", http.StatusBadRequest)
return
}
img, err := png.Decode(bytes.NewReader(preview))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Dump it to the raw file
for y := 0; y < 8; y++ {
for x := 0; x < 8; x++ {
r, g, b, _ := img.At(x, y).RGBA()
outRaw.Write([]byte{
byte(r >> 8),
byte(g >> 8),
byte(b >> 8),
})
}
}
outImage.Frames[i] = apng.Frame{
Image: img,
DelayNumerator: 1,
DelayDenominator: 2,
}
}
if err := apng.Encode(outPng, outImage); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
fmt.Fprintln(w, "It worked")
}
func main() {
listen := flag.String("listen", ":8080", "listen address")
web := flag.String("web", "web", "web directory")
flag.StringVar(&cacheDirectory, "cache", "cache", "cache directory")
flag.Parse()
cacheDir := http.Dir(cacheDirectory)
http.HandleFunc("/upload", handleUpload)
http.Handle("/wallart.bin", http.FileServer(cacheDir))
http.Handle("/wallart.png", http.FileServer(cacheDir))
http.Handle("/", http.FileServer(http.Dir(*web)))
http.ListenAndServe(*listen, nil)
}