diff --git a/main.go b/main.go index da29a2c..946ce43 100644 --- a/main.go +++ b/main.go @@ -1,4 +1,88 @@ package main -func main() { +import ( + "bytes" + "flag" + "fmt" + "image" + "image/color" + "image/png" + "log" + "net/http" + "os" + "sync" + "time" +) + +var port = flag.Int("port", 8000, "port") + +type Now struct { + lastUpdated time.Time + cacheWindow time.Duration + buffer *bytes.Buffer + lock sync.RWMutex +} + +func NewNow(d time.Duration) *Now { + return &Now{ + cacheWindow: d, + buffer: &bytes.Buffer{}, + } +} + +func (n *Now) ServeHTTP(w http.ResponseWriter, req *http.Request) { + log.Printf("%+v", req.RemoteAddr) + if time.Now().After(n.lastUpdated.Add(n.cacheWindow)) { + log.Println("updating image") + n.Update() + n.lastUpdated = time.Now() + } + n.lock.RLock() + w.Write(n.buffer.Bytes()) + n.lock.RUnlock() +} + +func (n *Now) Update() { + resp, err := http.Get("http://imgs.xkcd.com/comics/now.png") + if err != nil { + log.Fatal(err) + } + defer resp.Body.Close() + src, err := png.Decode(resp.Body) + if err != nil { + log.Fatal(err) + } + bounds := src.Bounds() + dest := image.NewNRGBA(bounds) + for y := bounds.Min.Y; y < bounds.Max.Y; y++ { + for x := bounds.Min.X; x < bounds.Max.X; x++ { + r, g, b, _ := src.At(x, y).RGBA() + if r == 0xFFFF && g == 0xFFFF && b == 0xFFFF { + dest.Set(x, y, color.NRGBA{0, 0, 0, 0}) + } else { + dest.Set(x, y, src.At(x, y)) + } + } + } + n.lock.Lock() + png.Encode(n.buffer, dest) + n.lock.Unlock() +} + +func main() { + flag.Parse() + + hostname, err := os.Hostname() + if err != nil { + log.Fatal("problem getting hostname:", err) + } + log.Printf("serving on: http://%s:%d/", hostname, *port) + addr := fmt.Sprintf(":%d", *port) + + http.Handle("/", NewNow(15*time.Minute)) + + err = http.ListenAndServe(addr, nil) + if err != nil { + log.Fatal(err) + } }