hswaw/site: serve static

This adds a minimum serving Go binary, and static/template file
embedding.

The templates are not yet served or even loaded. The static files are
served at /static/..., eg.:

    $ curl 127.0.0.1:8080/static/mapka.png

Change-Id: Iedd8696db2c2e5d434dc2e7fbd0199d0f6ee5fff
diff --git a/hswaw/site/BUILD.bazel b/hswaw/site/BUILD.bazel
new file mode 100644
index 0000000..7af2940
--- /dev/null
+++ b/hswaw/site/BUILD.bazel
@@ -0,0 +1,19 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
+
+go_library(
+    name = "go_default_library",
+    srcs = ["main.go"],
+    importpath = "code.hackerspace.pl/hscloud/hswaw/site",
+    visibility = ["//visibility:private"],
+    deps = [
+        "//go/mirko:go_default_library",
+        "//hswaw/site/static:static_go",
+        "@com_github_golang_glog//:go_default_library",
+    ],
+)
+
+go_binary(
+    name = "site",
+    embed = [":go_default_library"],
+    visibility = ["//visibility:public"],
+)
diff --git a/hswaw/site/main.go b/hswaw/site/main.go
new file mode 100644
index 0000000..b68482a
--- /dev/null
+++ b/hswaw/site/main.go
@@ -0,0 +1,69 @@
+package main
+
+import (
+	"flag"
+	"fmt"
+	"mime"
+	"net/http"
+	"strings"
+
+	"code.hackerspace.pl/hscloud/go/mirko"
+	"github.com/golang/glog"
+
+	"code.hackerspace.pl/hscloud/hswaw/site/static"
+)
+
+var (
+	flagSitePublic string
+)
+
+type service struct {
+}
+
+func main() {
+	flag.StringVar(&flagSitePublic, "site_public", "0.0.0.0:8080", "Address at which to serve public HTTP requests")
+	flag.Parse()
+
+	mi := mirko.New()
+	if err := mi.Listen(); err != nil {
+		glog.Exitf("Listen failed: %v", err)
+	}
+
+	s := &service{}
+
+	mux := http.NewServeMux()
+	s.registerHTTP(mux)
+
+	go func() {
+		glog.Infof("Listening for public HTTP at %v", flagSitePublic)
+		if err := http.ListenAndServe(flagSitePublic, mux); err != nil {
+			glog.Exit(err)
+		}
+	}()
+
+	if err := mi.Serve(); err != nil {
+		glog.Exitf("Serve failed: %v", err)
+	}
+
+	<-mi.Done()
+}
+
+func (s *service) handleHTTPStatic(w http.ResponseWriter, r *http.Request) {
+	path := strings.TrimPrefix(r.URL.Path, "/")
+
+	staticPath := fmt.Sprintf("hswaw/site/%s", path)
+	glog.Infof("%q", staticPath)
+	if data, ok := static.Data[staticPath]; ok {
+		parts := strings.Split(path, ".")
+		ext := fmt.Sprintf(".%s", parts[len(parts)-1])
+		t := mime.TypeByExtension(ext)
+		w.Header().Set("Content-Type", t)
+		w.Write(data)
+	} else {
+		http.NotFound(w, r)
+	}
+}
+
+func (s *service) registerHTTP(mux *http.ServeMux) {
+	mux.HandleFunc("/static/", s.handleHTTPStatic)
+}
diff --git a/hswaw/site/static/BUILD.bazel b/hswaw/site/static/BUILD.bazel
new file mode 100644
index 0000000..141161c
--- /dev/null
+++ b/hswaw/site/static/BUILD.bazel
@@ -0,0 +1,20 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+load("@io_bazel_rules_go//extras:embed_data.bzl", "go_embed_data")
+
+go_embed_data(
+    name = "static",
+    srcs = [
+        "kontakt.png",
+        "main.css",
+        "mapka.png",
+    ],
+    package = "static",
+)
+
+# keep
+go_library(
+    name = "static_go",
+    srcs = [":static"],
+    importpath = "code.hackerspace.pl/hscloud/hswaw/site/static",
+    visibility = ["//visibility:public"],
+)
diff --git a/hswaw/site/templates/BUILD.bazel b/hswaw/site/templates/BUILD.bazel
new file mode 100644
index 0000000..58da1ea
--- /dev/null
+++ b/hswaw/site/templates/BUILD.bazel
@@ -0,0 +1,25 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+load("@io_bazel_rules_go//extras:embed_data.bzl", "go_embed_data")
+
+go_embed_data(
+    name = "templates",
+    srcs = [
+        "about.html",
+        "about_en.html",
+        "basic.html",
+        "header.html",
+        "main.html",
+        "rotimate_at.html",
+        "subscribe.html",
+        "subscribe_en.html",
+    ],
+    package = "templates",
+)
+
+# keep
+go_library(
+    name = "templates_go",
+    srcs = [":templates"],
+    importpath = "code.hackerspace.pl/hscloud/hswaw/site/templates",
+    visibility = ["//visibility:public"],
+)