├── .gitignore ├── README.md ├── go.mod ├── go.sum ├── index.html ├── .goreleaser.yml └── server.go /.gitignore: -------------------------------------------------------------------------------- 1 | deploy 2 | *.swp 3 | *.db 4 | dist 5 | *.tar.gz 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ``` 2 | go run server.go -port 9090 -html index.html 3 | ``` 4 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/whatever420/color-api 2 | 3 | go 1.13 4 | 5 | require github.com/gorilla/mux v1.7.3 6 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= 2 | github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= 3 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{.String}} 5 | 6 | 7 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | before: 2 | hooks: 3 | - go mod tidy 4 | builds: 5 | - 6 | id: "color" 7 | main: ./server.go 8 | binary: color 9 | env: 10 | - CGO_ENABLED=0 11 | - GO11MODULE=on 12 | goarch: 13 | - amd64 14 | goos: 15 | - linux 16 | archives: 17 | - replacements: 18 | darwin: Darwin 19 | linux: Linux 20 | windows: Windows 21 | 386: i386 22 | amd64: x86_64 23 | checksum: 24 | name_template: 'checksums.txt' 25 | snapshot: 26 | name_template: "{{.Tag}}-next" 27 | changelog: 28 | sort: asc 29 | filters: 30 | exclude: 31 | - '^docs:' 32 | - '^test:' 33 | -------------------------------------------------------------------------------- /server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "flag" 7 | "fmt" 8 | "html/template" 9 | "image" 10 | "image/color" 11 | "image/draw" 12 | "image/png" 13 | "math/rand" 14 | "net/http" 15 | "os" 16 | "os/signal" 17 | "strconv" 18 | "syscall" 19 | "time" 20 | 21 | "github.com/gorilla/mux" 22 | ) 23 | 24 | // Run the trap 25 | func SetupTrap(server *http.Server) { 26 | cigs := make(chan os.Signal, 1) 27 | signal.Notify(cigs, syscall.SIGINT) 28 | go func() { 29 | <-cigs 30 | if err := server.Shutdown(context.Background()); err != nil { 31 | fmt.Println(err) 32 | } 33 | }() 34 | } 35 | 36 | type Color [3]uint8 37 | 38 | func (c Color) String() string { 39 | return fmt.Sprintf("#%02x%02x%02x", c[0], c[1], c[2]) 40 | } 41 | 42 | func (c Color) Xyz() string { 43 | return fmt.Sprintf("%02x%02x%02x", c[0], c[1], c[2]) 44 | } 45 | 46 | func RandomColor(rand *rand.Rand) Color { 47 | return Color{uint8(rand.Intn(256)), uint8(rand.Intn(256)), uint8(rand.Intn(256))} 48 | } 49 | 50 | func ColorFromString(s string) Color { 51 | if len(s) != 6 { 52 | return Color{255, 255, 255} 53 | } 54 | 55 | r, _ := strconv.ParseInt(s[0:2], 16, 64) 56 | g, _ := strconv.ParseInt(s[2:4], 16, 64) 57 | b, _ := strconv.ParseInt(s[4:6], 16, 64) 58 | 59 | return Color{uint8(r), uint8(g), uint8(b)} 60 | } 61 | 62 | func (c *Color) Image() image.Image { 63 | img := image.NewRGBA(image.Rect(0, 0, 32, 32)) 64 | draw.Draw( 65 | img, 66 | img.Bounds(), 67 | &image.Uniform{color.RGBA{c[0], c[1], c[2], 255}}, 68 | image.ZP, 69 | draw.Src, 70 | ) 71 | return img 72 | } 73 | 74 | func main() { 75 | 76 | port := flag.Int("port", 8080, "port number to open on") 77 | html := flag.String("html", "index.html", "location of file to use as a template") 78 | flag.Parse() 79 | 80 | sour := rand.NewSource(time.Now().UnixNano()) 81 | rand := rand.New(sour) 82 | 83 | s := &http.Server{ 84 | Addr: fmt.Sprintf(":%v", *port), 85 | } 86 | 87 | fname := *html 88 | 89 | tmpl, err := template.New("color").ParseFiles(fname) 90 | 91 | if err != nil { 92 | fmt.Printf("error: %v\n", err) 93 | return 94 | } 95 | 96 | SetupTrap(s) 97 | 98 | r := mux.NewRouter() 99 | 100 | r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 101 | c := RandomColor(rand) 102 | fmt.Println("Random color:", c) 103 | if err := tmpl.ExecuteTemplate(w, "index.html", c); err != nil { 104 | fmt.Println(err) 105 | } 106 | }) 107 | 108 | r.HandleFunc("favicon.ico", func(w http.ResponseWriter, r *http.Request) { 109 | fmt.Println("Vanilla favicon.ico...") 110 | fmt.Fprintf(w, "...") 111 | }) 112 | 113 | r.HandleFunc("/{color}/favicon.ico", func(w http.ResponseWriter, r *http.Request) { 114 | c := ColorFromString(mux.Vars(r)["color"]) 115 | fmt.Println(mux.Vars(r)["color"], c) 116 | 117 | buf := new(bytes.Buffer) 118 | 119 | _ = png.Encode(buf, c.Image()) 120 | 121 | fmt.Println(len(buf.String())) 122 | fmt.Println([]byte(buf.String())) 123 | 124 | if err := png.Encode(w, c.Image()); err != nil { 125 | fmt.Println("Failed:", err) 126 | } 127 | }) 128 | 129 | r.HandleFunc("/color", func(w http.ResponseWriter, r *http.Request) { 130 | fmt.Fprintf(w, "%v", RandomColor(rand)) 131 | }) 132 | 133 | // http.NotFound(w ResponseWriter, r *Request) 134 | 135 | http.Handle("/", r) 136 | 137 | fmt.Println("Finished:", s.ListenAndServe()) 138 | } 139 | --------------------------------------------------------------------------------