You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

184 lines
3.0 KiB

package main
import (
"bufio"
"bytes"
"compress/gzip"
"encoding/base64"
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"strings"
"text/template"
"time"
)
const b64Width = 76
var (
webAssetsTmpl = template.Must(template.New("web_assets").Parse("" +
"// WARNING: GENERATED FILE, NERDS! {{.Now}}\n" +
"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 {
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())
}
func toGz(input []byte) []byte {
var buf bytes.Buffer
zwriter, err := gzip.NewWriterLevel(&buf, gzip.BestCompression)
if err != nil {
die(err)
}
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
}
func toB64Gz(input []byte) string {
return string(toB64(toGz(input)))
}
func main() {
if len(os.Args) < 2 {
die(errors.New(fmt.Sprintf("Usage: %s <index.html-path>", os.Args[0])))
}
assets := &webAssetStrings{
IndexHTML: toB64Gz(fetchIndexHtml(os.Args[1])),
NormalizeCSS: toB64Gz(fetchUrl(normalizeCssUrl)),
JqueryMinJS: toB64Gz(fetchUrl(jqueryMinJsUrl)),
Now: time.Now(),
}
webAssetsTmpl.Execute(os.Stdout, assets)
}