refactor asset with embed tool

This commit is contained in:
sentriz
2019-06-26 12:01:49 +01:00
parent e6c6d2406f
commit d8881bd31c
35 changed files with 11004 additions and 21662 deletions

1
_build_vars Normal file
View File

@@ -0,0 +1 @@
export GO111MODULE=on

View File

@@ -1,7 +1,6 @@
#!/bin/bash #!/bin/bash
GO111MODULES=on source _build_vars
go build \ go build \
-tags "$(tr '\n' ' ' < _build_tags)" \ -tags "$(tr '\n' ' ' < _build_tags)" \
cmd/scanner/main.go cmd/gonicscan/main.go

View File

@@ -1,8 +1,15 @@
#!/bin/bash #!/bin/bash
GO111MODULES=on shopt -s globstar
source _build_vars
./_do_compile_assets go run \
cmd/gonicembed/main.go \
-out-path server/assets_bytes.go \
-tag-list embed \
-package-name server \
-assets-var-name AssetBytes \
-asset-path-prefix server/assets/ \
server/assets/**
go build \ go build \
-tags "$(tr '\n' ' ' < _build_tags) embed" \ -tags "$(tr '\n' ' ' < _build_tags) embed" \
cmd/server/main.go cmd/gonic/main.go

View File

@@ -1,14 +0,0 @@
#!/bin/bash
shopt -s globstar
server_base_dir=server
assets_name=assets
resources \
-declare \
-var $(sed -E 's/(^|_)([a-z])/\U\2/g' <<< $assets_name) \
-package ${assets_name}_compiled \
-output "$server_base_dir/${assets_name}_compiled/${assets_name}_compiled.go" \
-trim "$server_base_dir/${assets_name}_src/" \
"$server_base_dir/${assets_name}_src/"**

View File

@@ -1,8 +1,7 @@
#!/bin/bash #!/bin/bash
GO111MODULES=on source _build_vars
go run \ go run \
-tags "$(tr '\n' ' ' < _build_tags)" \ -tags "$(tr '\n' ' ' < _build_tags)" \
cmd/scanner/main.go \ cmd/gonicscan/main.go
$@ $@

View File

@@ -1,8 +1,7 @@
#!/bin/bash #!/bin/bash
GO111MODULES=on source _build_vars
go run \ go run \
-tags "$(tr '\n' ' ' < _build_tags)" \ -tags "$(tr '\n' ' ' < _build_tags)" \
cmd/server/main.go \ cmd/gonic/main.go \
$@ $@

View File

@@ -50,6 +50,7 @@ func main() {
db, db,
*musicPath, *musicPath,
*listenAddr, *listenAddr,
"server/assets/",
) )
err = s.SetupAdmin() err = s.SetupAdmin()
if err != nil { if err != nil {

147
cmd/gonicembed/main.go Normal file
View File

@@ -0,0 +1,147 @@
package main
import (
"flag"
"fmt"
"io"
"log"
"os"
"strings"
"time"
"github.com/peterbourgon/ff"
"github.com/pkg/errors"
)
const (
programName = "gonicembed"
byteCols = 24
// begin file template
fileHeader = `// file generated with embed tool
// do not edit
// +build %s
package %s
import "time"
type EmbeddedAsset struct {
ModTime time.Time
Bytes []byte
}
var %s = map[string]*EmbeddedAsset{`
fileFooter = `
}`
// begin asset template
assetHeader = `
%q: &EmbeddedAsset{
ModTime: time.Unix(%d, 0),
Bytes: []byte{
`
assetFooter = `}},`
)
type config struct {
packageName string
outPath string
tagList string
assetsVarName string
assetPathPrefix string
}
type file struct {
data io.ReadSeeker
path string
modTime time.Time
}
func processAsset(c *config, f *file, out io.Writer) error {
out.Write([]byte(fmt.Sprintf(assetHeader,
strings.TrimPrefix(f.path, c.assetPathPrefix),
f.modTime.Unix(),
)))
defer out.Write([]byte(assetFooter))
buffer := make([]byte, byteCols)
for {
read, err := f.data.Read(buffer)
for i := 0; i < read; i++ {
fmt.Fprintf(out, "0x%02x,", buffer[i])
}
if err != nil {
break
}
fmt.Fprintln(out)
}
return nil
}
func processAssets(c *config, files []string) error {
outWriter, err := os.Create(c.outPath)
if err != nil {
return errors.Wrap(err, "creating out path")
}
outWriter.Write([]byte(fmt.Sprintf(fileHeader,
c.tagList,
c.packageName,
c.assetsVarName,
)))
defer outWriter.Write([]byte(fileFooter))
for _, path := range files {
info, err := os.Stat(path)
if err != nil {
return errors.Wrap(err, "stating asset")
}
if info.IsDir() {
continue
}
data, err := os.Open(path)
if err != nil {
return errors.Wrap(err, "opening asset")
}
f := &file{
data: data,
path: path,
modTime: info.ModTime(),
}
if err := processAsset(c, f, outWriter); err != nil {
return errors.Wrap(err, "processing asset")
}
}
return nil
}
func main() {
set := flag.NewFlagSet(programName, flag.ExitOnError)
outPath := set.String(
"out-path", "",
"generated file's path (required)")
pkgName := set.String(
"package-name", "assets",
"generated file's package name")
tagList := set.String(
"tag-list", "",
"generated file's build tag list")
assetsVarName := set.String(
"assets-var-name", "Assets",
"generated file's assets var name")
assetPathPrefix := set.String(
"asset-path-prefix", "",
"generated file's assets map key prefix to be stripped")
if err := ff.Parse(set, os.Args[1:]); err != nil {
log.Fatalf("error parsing args: %v\n", err)
}
if *outPath == "" {
log.Fatalln("invalid arguments. see -h")
}
c := &config{
packageName: *pkgName,
outPath: *outPath,
tagList: *tagList,
assetsVarName: *assetsVarName,
assetPathPrefix: *assetPathPrefix,
}
if err := processAssets(c, set.Args()); err != nil {
log.Fatalf("error processing files: %v\n", err)
}
}

View File

@@ -13,7 +13,7 @@ import (
) )
const ( const (
programName = "gonic" programName = "gonicscan"
) )
func main() { func main() {
@@ -24,8 +24,7 @@ func main() {
dbPath := set.String( dbPath := set.String(
"db-path", "gonic.db", "db-path", "gonic.db",
"path to database (optional)") "path to database (optional)")
err := ff.Parse(set, os.Args[1:]) if err := ff.Parse(set, os.Args[1:]); err != nil {
if err != nil {
log.Fatalf("error parsing args: %v\n", err) log.Fatalf("error parsing args: %v\n", err)
} }
if _, err := os.Stat(*musicPath); os.IsNotExist(err) { if _, err := os.Stat(*musicPath); os.IsNotExist(err) {

3
go.mod
View File

@@ -20,14 +20,13 @@ require (
github.com/jinzhu/now v1.0.0 // indirect github.com/jinzhu/now v1.0.0 // indirect
github.com/josephburnett/jd v0.0.0-20190523064723-9cd4cea55d7d github.com/josephburnett/jd v0.0.0-20190523064723-9cd4cea55d7d
github.com/karrick/godirwalk v1.8.0 github.com/karrick/godirwalk v1.8.0
github.com/kr/pretty v0.1.0 // indirect
github.com/lib/pq v1.0.0 // indirect github.com/lib/pq v1.0.0 // indirect
github.com/mattn/go-sqlite3 v1.10.0 // indirect github.com/mattn/go-sqlite3 v1.10.0 // indirect
github.com/nicksellen/audiotags v0.0.0-20160226222119-94015fa599bd github.com/nicksellen/audiotags v0.0.0-20160226222119-94015fa599bd
github.com/omeid/go-resources v0.0.0-20190324090249-46f4269d8abd
github.com/peterbourgon/ff v1.2.0 github.com/peterbourgon/ff v1.2.0
github.com/pkg/errors v0.8.1 github.com/pkg/errors v0.8.1
github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b
github.com/wader/gormstore v0.0.0-20190302154359-acb787ba3755 github.com/wader/gormstore v0.0.0-20190302154359-acb787ba3755
golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd // indirect golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd // indirect
google.golang.org/appengine v1.5.0 // indirect google.golang.org/appengine v1.5.0 // indirect

12
go.sum
View File

@@ -90,7 +90,12 @@ github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A= github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o= github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
@@ -99,8 +104,6 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nicksellen/audiotags v0.0.0-20160226222119-94015fa599bd h1:xKn/gU8lZupoZt/HE7a/R3aH93iUO6JwyRsYelQUsRI= github.com/nicksellen/audiotags v0.0.0-20160226222119-94015fa599bd h1:xKn/gU8lZupoZt/HE7a/R3aH93iUO6JwyRsYelQUsRI=
github.com/nicksellen/audiotags v0.0.0-20160226222119-94015fa599bd/go.mod h1:B6icauz2l4tkYQxmDtCH4qmNWz/evSW5CsOqp6IE5IE= github.com/nicksellen/audiotags v0.0.0-20160226222119-94015fa599bd/go.mod h1:B6icauz2l4tkYQxmDtCH4qmNWz/evSW5CsOqp6IE5IE=
github.com/omeid/go-resources v0.0.0-20190324090249-46f4269d8abd h1:VxcHM9xpZ4BHxQPYWAavsxPciBZITxmnGNyIO7hsUfk=
github.com/omeid/go-resources v0.0.0-20190324090249-46f4269d8abd/go.mod h1:SIESmZeFlCKsQZcd2NEiX8spNNmCWB1V/RbM/eBKDfo=
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
github.com/openzipkin/zipkin-go v0.1.3/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/openzipkin/zipkin-go v0.1.3/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
github.com/peterbourgon/ff v1.2.0 h1:wGn2NwdHk8MTlRQpnXnO91UKegxt5DvlwR/bTK/L2hc= github.com/peterbourgon/ff v1.2.0 h1:wGn2NwdHk8MTlRQpnXnO91UKegxt5DvlwR/bTK/L2hc=
@@ -122,10 +125,9 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be h1:ta7tUOvsPHVHGom5hKW5VXNc2xZIkfCKP8iaqOyYtUQ= github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be h1:ta7tUOvsPHVHGom5hKW5VXNc2xZIkfCKP8iaqOyYtUQ=
github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be/go.mod h1:MIDFMn7db1kT65GmV94GzpX9Qdi7N/pQlwb+AN8wh+Q= github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be/go.mod h1:MIDFMn7db1kT65GmV94GzpX9Qdi7N/pQlwb+AN8wh+Q=
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b h1:4kg1wyftSKxLtnPAvcRWakIPpokB9w780/KwrNLnfPA=
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
github.com/wader/gormstore v0.0.0-20190302154359-acb787ba3755 h1:pNaEDfvqe9W2h4D+xm5f+lnZdao3Rob6O0b8SovpGbE= github.com/wader/gormstore v0.0.0-20190302154359-acb787ba3755 h1:pNaEDfvqe9W2h4D+xm5f+lnZdao3Rob6O0b8SovpGbE=
@@ -155,6 +157,7 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -206,6 +209,7 @@ google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 236 KiB

After

Width:  |  Height:  |  Size: 236 KiB

View File

@@ -4,12 +4,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>gonic</title> <title>gonic</title>
<link rel="stylesheet" href="/admin/static/stylesheets/reset.css"> {{ template "head" }}
<link rel="stylesheet" href="https://cdn.materialdesignicons.com/3.6.95/css/materialdesignicons.min.css">
<link rel="stylesheet" href="/admin/static/stylesheets/main.css">
<link rel="shortcut icon" href="/admin/static/images/favicon.ico" type="image/x-icon">
<link rel="icon" href="/admin/static/images/favicon.ico" type="image/x-icon">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
</head> </head>
<body> <body>
<div> <div>

View File

@@ -0,0 +1,8 @@
{{ define "head" }}
<link rel="stylesheet" href="/admin/static/stylesheets/reset.css">
<link rel="stylesheet" href="https://cdn.materialdesignicons.com/3.6.95/css/materialdesignicons.min.css">
<link rel="stylesheet" href="/admin/static/stylesheets/main.css">
<link rel="shortcut icon" href="/admin/static/images/favicon.ico" type="image/x-icon">
<link rel="icon" href="/admin/static/images/favicon.ico" type="image/x-icon">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
{{ end }}

10652
server/assets_bytes.go Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +0,0 @@
// +build !embed
package server
import "github.com/omeid/go-resources/live"
var (
assets = live.Dir("./assets_src")
)

9
server/assets_getters.go Normal file
View File

@@ -0,0 +1,9 @@
package server
import "errors"
var ErrAssetNotFound = errors.New("asset not found")
type Assets struct {
BasePath string
}

View File

@@ -0,0 +1,39 @@
// +build !embed
package server
import (
"io"
"io/ioutil"
"os"
"path/filepath"
"time"
"github.com/pkg/errors"
)
func (a *Assets) Find(path string) (time.Time, io.ReadSeeker, error) {
fullPath := filepath.Join(a.BasePath, path)
info, err := os.Stat(fullPath)
if err != nil {
return time.Time{}, nil, errors.Wrap(err, "statting asset")
}
file, err := os.Open(fullPath)
if err != nil {
return time.Time{}, nil, errors.Wrapf(ErrAssetNotFound, "%v", err)
}
return info.ModTime(), file, nil
}
func (a *Assets) FindBytes(path string) (time.Time, []byte, error) {
fullPath := filepath.Join(a.BasePath, path)
info, err := os.Stat(fullPath)
if err != nil {
return time.Time{}, nil, errors.Wrap(err, "statting asset")
}
file, err := ioutil.ReadFile(fullPath)
if err != nil {
return time.Time{}, nil, errors.Wrapf(ErrAssetNotFound, "%v", err)
}
return info.ModTime(), file, nil
}

View File

@@ -0,0 +1,26 @@
// +build embed
package server
import (
"bytes"
"io"
"time"
)
func (_ *Assets) Find(path string) (time.Time, io.ReadSeeker, error) {
asset, ok := AssetBytes[path]
if !ok {
return time.Time{}, nil, ErrAssetNotFound
}
reader := bytes.NewReader(asset.Bytes)
return asset.ModTime, reader, nil
}
func (_ *Assets) FindBytes(path string) (time.Time, []byte, error) {
asset, ok := AssetBytes[path]
if !ok {
return time.Time{}, nil, ErrAssetNotFound
}
return asset.ModTime, asset.Bytes, nil
}

View File

@@ -1,9 +0,0 @@
// +build embed
package server
import "github.com/sentriz/gonic/server/assets_compiled"
var (
assets = assets_compiled.Assets
)

View File

@@ -1,10 +0,0 @@
{{ define "box" }}
<div class="padded box mono">
<div class="box-title">
<i class="mdi mdi-chart-arc"></i> {{ .Title }}
</div>
<div class="block-right">
{{ .Content }}
</div>
</div>
{{ end }}

View File

@@ -25,11 +25,17 @@ func newChain(wares ...middleware) middleware {
type Server struct { type Server struct {
mux *http.ServeMux mux *http.ServeMux
assets *Assets
*handler.Controller *handler.Controller
*http.Server *http.Server
} }
func New(db *gorm.DB, musicPath string, listenAddr string) *Server { func New(
db *gorm.DB,
musicPath string,
listenAddr string,
assetPath string,
) *Server {
mux := http.NewServeMux() mux := http.NewServeMux()
server := &http.Server{ server := &http.Server{
Addr: listenAddr, Addr: listenAddr,
@@ -42,8 +48,12 @@ func New(db *gorm.DB, musicPath string, listenAddr string) *Server {
DB: db, DB: db,
MusicPath: musicPath, MusicPath: musicPath,
} }
assets := &Assets{
BasePath: assetPath,
}
return &Server{ return &Server{
mux: mux, mux: mux,
assets: assets,
Server: server, Server: server,
Controller: controller, Controller: controller,
} }

View File

@@ -1,8 +1,8 @@
package server package server
import ( import (
"fmt"
"html/template" "html/template"
"log"
"net/http" "net/http"
"path/filepath" "path/filepath"
"time" "time"
@@ -11,11 +11,74 @@ import (
"github.com/dustin/go-humanize" "github.com/dustin/go-humanize"
"github.com/gorilla/securecookie" "github.com/gorilla/securecookie"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/shurcooL/httpfs/html/vfstemplate"
"github.com/shurcooL/httpfs/path/vfspath"
"github.com/wader/gormstore" "github.com/wader/gormstore"
) )
var (
partialsPaths = []string{
"partials/box.tmpl",
}
layoutPaths = []string{
"layouts/base.tmpl",
"layouts/user.tmpl",
}
pagePaths = []string{
"pages/change_own_password.tmpl",
"pages/change_password.tmpl",
"pages/create_user.tmpl",
"pages/delete_user.tmpl",
"pages/home.tmpl",
"pages/login.tmpl",
"pages/update_lastfm_api_key.tmpl",
}
imagePaths = []string{
"images/favicon.ico",
"images/gonic.png",
"images/gone.png",
}
stylesheetPaths = []string{
"stylesheets/main.css",
"stylesheets/reset.css",
}
)
type templateMap map[string]*template.Template
func parseFromPaths(assets *Assets, base *template.Template,
paths []string, destination templateMap) error {
for _, path := range paths {
_, tmplBytes, err := assets.FindBytes(path)
if err != nil {
return errors.Wrapf(err, "getting template %q from assets", path)
}
tmplStr := string(tmplBytes)
if destination != nil {
// we have a destination. meaning this template is a page.
// instead of parsing as usual, we need to clone and add to the
// template map
clone := template.Must(base.Clone())
tmplKey := filepath.Base(path)
destination[tmplKey] = template.Must(clone.Parse(tmplStr))
continue
}
_ = template.Must(base.Parse(tmplStr))
}
return nil
}
func staticHandler(assets *Assets, path string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
modTime, reader, err := assets.Find(path)
if err != nil {
log.Printf("error getting file %q from assets: %v\n", path, err)
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
_, name := filepath.Split(path)
http.ServeContent(w, r, name, modTime, reader)
}
}
func (s *Server) SetupAdmin() error { func (s *Server) SetupAdmin() error {
sessionKey := []byte(s.GetSetting("session_key")) sessionKey := []byte(s.GetSetting("session_key"))
if len(sessionKey) == 0 { if len(sessionKey) == 0 {
@@ -31,34 +94,18 @@ func (s *Server) SetupAdmin() error {
Funcs(template.FuncMap{ Funcs(template.FuncMap{
"humanDate": humanize.Time, "humanDate": humanize.Time,
}) })
const ( if err := parseFromPaths(
layoutDir = "/templates/layouts/*" s.assets, tmplBase, partialsPaths, nil); err != nil {
partialDir = "/templates/partials/*" return errors.Wrap(err, "parsing template partials")
pageDir = "/templates/pages/*"
)
tmplLayouts, err := vfstemplate.ParseGlob(assets, tmplBase, layoutDir)
if err != nil {
return errors.Wrap(err, "parsing layouts")
} }
tmplPartials, err := vfstemplate.ParseGlob(assets, tmplLayouts, partialDir) if err := parseFromPaths(
if err != nil { s.assets, tmplBase, layoutPaths, nil); err != nil {
return errors.Wrap(err, "parsing partials") return errors.Wrap(err, "parsing template layouts")
} }
pages, err := vfspath.Glob(assets, pageDir) s.Templates = make(templateMap)
if err != nil { if err := parseFromPaths(
return errors.Wrap(err, "parsing pages") s.assets, tmplBase, pagePaths, s.Templates); err != nil {
} return errors.Wrap(err, "parsing template pages for destination")
s.Templates = make(map[string]*template.Template)
for _, page := range pages {
tmplStr, ok := assets.String(page)
if !ok {
return fmt.Errorf("getting template %q from assets: %v\n", page)
}
tmplBaseClone := template.Must(tmplPartials.Clone())
tmplWithPage := template.Must(tmplBaseClone.Parse(tmplStr))
tmplWithPartial := template.Must(tmplWithPage.Parse(tmplStr))
shortName := filepath.Base(page)
s.Templates[shortName] = tmplWithPartial
} }
// //
withPublicWare := newChain( withPublicWare := newChain(
@@ -74,9 +121,10 @@ func (s *Server) SetupAdmin() error {
s.WithAdminSession, s.WithAdminSession,
) )
// begin static server // begin static server
s.mux.Handle("/admin/static/", http.StripPrefix("/admin", for _, path := range append(imagePaths, stylesheetPaths...) {
http.FileServer(assets), fullPath := filepath.Join("/admin/static", path)
)) s.mux.HandleFunc(fullPath, staticHandler(s.assets, path))
}
// begin public routes (creates new session) // begin public routes (creates new session)
s.mux.HandleFunc("/admin/login", withPublicWare(s.ServeLogin)) s.mux.HandleFunc("/admin/login", withPublicWare(s.ServeLogin))
s.mux.HandleFunc("/admin/login_do", withPublicWare(s.ServeLoginDo)) s.mux.HandleFunc("/admin/login_do", withPublicWare(s.ServeLoginDo))