2012-12-19 02:56:37 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
|
|
|
"bytes"
|
|
|
|
"compress/gzip"
|
|
|
|
"encoding/base64"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
2012-12-19 05:06:15 +00:00
|
|
|
"io"
|
2012-12-19 02:56:37 +00:00
|
|
|
"io/ioutil"
|
|
|
|
"log"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
2012-12-19 05:06:15 +00:00
|
|
|
"strings"
|
2012-12-19 02:56:37 +00:00
|
|
|
"text/template"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2012-12-19 05:06:15 +00:00
|
|
|
const b64Width = 76
|
|
|
|
|
2012-12-19 02:56:37 +00:00
|
|
|
var (
|
|
|
|
webAssetsTmpl = template.Must(template.New("web_assets").Parse("" +
|
2012-12-19 05:06:15 +00:00
|
|
|
"// WARNING: GENERATED FILE, NERDS! {{.Now}}\n" +
|
2012-12-19 02:56:37 +00:00
|
|
|
"package conway\n" +
|
|
|
|
"\n" +
|
|
|
|
"const (\n" +
|
|
|
|
" GAME_OF_LIFE_INDEX_HTML = `{{.IndexHTML}}`\n" +
|
|
|
|
" NORMALIZE_CSS = `{{.NormalizeCSS}}`\n" +
|
|
|
|
" JQUERY_MIN_JS = `{{.JqueryMinJS}}`\n" +
|
|
|
|
")\n"))
|
|
|
|
normalizeCssUrl = "http://necolas.github.com/normalize.css/2.0.1/normalize.css"
|
|
|
|
jqueryMinJsUrl = "http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"
|
|
|
|
)
|
|
|
|
|
|
|
|
type webAssetStrings struct {
|
|
|
|
IndexHTML string
|
|
|
|
NormalizeCSS string
|
|
|
|
JqueryMinJS string
|
|
|
|
Now time.Time
|
|
|
|
}
|
|
|
|
|
|
|
|
func die(err error) {
|
|
|
|
log.Fatal("CRUD:", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func toB64(input []byte) string {
|
2012-12-19 05:06:15 +00:00
|
|
|
var (
|
|
|
|
err error
|
|
|
|
out bytes.Buffer
|
|
|
|
)
|
|
|
|
encoded := base64.StdEncoding.EncodeToString(input)
|
|
|
|
lenEncoded := len(encoded)
|
|
|
|
|
|
|
|
outbuf := bufio.NewWriter(&out)
|
|
|
|
inbuf := strings.NewReader(encoded)
|
|
|
|
|
|
|
|
outbuf.WriteByte('\n')
|
|
|
|
if err != nil {
|
|
|
|
die(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
nWritten := 0
|
|
|
|
for {
|
|
|
|
for n := 0; n < b64Width; n++ {
|
|
|
|
c, err := inbuf.ReadByte()
|
|
|
|
if err == io.EOF {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
die(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = outbuf.WriteByte(c)
|
|
|
|
if err != nil {
|
|
|
|
die(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
nWritten++
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err := inbuf.ReadByte()
|
|
|
|
if err == io.EOF {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
die(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = inbuf.UnreadByte()
|
|
|
|
if err != nil {
|
|
|
|
die(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = outbuf.WriteByte('\n')
|
|
|
|
if err != nil {
|
|
|
|
die(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if nWritten != lenEncoded {
|
|
|
|
die(errors.New(fmt.Sprintf("base64-encoded length = %d, but wrote %d",
|
|
|
|
lenEncoded, nWritten)))
|
|
|
|
}
|
|
|
|
|
|
|
|
outbuf.Flush()
|
|
|
|
return string(out.Bytes())
|
2012-12-19 02:56:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func toGz(input []byte) []byte {
|
|
|
|
var buf bytes.Buffer
|
|
|
|
|
2012-12-19 05:06:15 +00:00
|
|
|
zwriter, err := gzip.NewWriterLevel(&buf, gzip.BestCompression)
|
|
|
|
if err != nil {
|
|
|
|
die(err)
|
|
|
|
}
|
2012-12-19 02:56:37 +00:00
|
|
|
|
|
|
|
zbuf := bufio.NewWriter(zwriter)
|
|
|
|
|
|
|
|
toWrite := len(input)
|
|
|
|
for written := 0; written < toWrite; {
|
|
|
|
n, err := zbuf.Write(input[written:])
|
|
|
|
if err != nil {
|
|
|
|
die(err)
|
|
|
|
}
|
|
|
|
written += n
|
|
|
|
}
|
|
|
|
|
|
|
|
zbuf.Flush()
|
|
|
|
zwriter.Close()
|
|
|
|
return buf.Bytes()
|
|
|
|
}
|
|
|
|
|
|
|
|
func fetchUrl(url string) []byte {
|
|
|
|
resp, err := http.Get(url)
|
|
|
|
if err != nil {
|
|
|
|
die(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
|
|
if err != nil {
|
|
|
|
die(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return body
|
|
|
|
}
|
|
|
|
|
|
|
|
func fetchIndexHtml(indexHtmlPath string) []byte {
|
|
|
|
fd, err := os.Open(indexHtmlPath)
|
|
|
|
if err != nil {
|
|
|
|
die(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
body, err := ioutil.ReadAll(fd)
|
|
|
|
if err != nil {
|
|
|
|
die(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return body
|
|
|
|
}
|
|
|
|
|
2012-12-19 05:06:15 +00:00
|
|
|
func toB64Gz(input []byte) string {
|
|
|
|
return string(toB64(toGz(input)))
|
|
|
|
}
|
|
|
|
|
2012-12-19 02:56:37 +00:00
|
|
|
func main() {
|
|
|
|
if len(os.Args) < 2 {
|
|
|
|
die(errors.New(fmt.Sprintf("Usage: %s <index.html-path>", os.Args[0])))
|
|
|
|
}
|
|
|
|
|
|
|
|
assets := &webAssetStrings{
|
2012-12-19 05:06:15 +00:00
|
|
|
IndexHTML: toB64Gz(fetchIndexHtml(os.Args[1])),
|
|
|
|
NormalizeCSS: toB64Gz(fetchUrl(normalizeCssUrl)),
|
|
|
|
JqueryMinJS: toB64Gz(fetchUrl(jqueryMinJsUrl)),
|
2012-12-19 02:56:37 +00:00
|
|
|
Now: time.Now(),
|
|
|
|
}
|
|
|
|
|
|
|
|
webAssetsTmpl.Execute(os.Stdout, assets)
|
|
|
|
}
|