mirror of
https://github.com/nkanaev/yarr.git
synced 2025-05-24 00:33:14 +00:00
switch assets to embed
This commit is contained in:
parent
a3146926b1
commit
121101de9d
45
assets/assets.go
Normal file
45
assets/assets.go
Normal file
@ -0,0 +1,45 @@
|
||||
package assets
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"html/template"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"io/fs"
|
||||
"os"
|
||||
)
|
||||
|
||||
type assetsfs struct {
|
||||
embedded *embed.FS
|
||||
templates map[string]*template.Template
|
||||
}
|
||||
|
||||
var FS assetsfs
|
||||
|
||||
func (afs assetsfs) Open(name string) (fs.File, error) {
|
||||
if afs.embedded != nil {
|
||||
return afs.embedded.Open(name)
|
||||
}
|
||||
return os.DirFS("assets").Open(name)
|
||||
}
|
||||
|
||||
func Render(path string, writer io.Writer, data interface{}) {
|
||||
var tmpl *template.Template
|
||||
tmpl, found := FS.templates[path]
|
||||
if !found {
|
||||
tmpl = template.Must(template.New(path).Delims("{%", "%}").Funcs(template.FuncMap{
|
||||
"inline": func(svg string) template.HTML {
|
||||
svgfile, _ := FS.Open("graphicarts/" + svg)
|
||||
content, _ := ioutil.ReadAll(svgfile)
|
||||
svgfile.Close()
|
||||
return template.HTML(content)
|
||||
},
|
||||
}).ParseFS(FS, path))
|
||||
FS.templates[path] = tmpl
|
||||
}
|
||||
tmpl.Execute(writer, data)
|
||||
}
|
||||
|
||||
func init() {
|
||||
FS.templates = make(map[string]*template.Template)
|
||||
}
|
15
assets/assetsfs.go
Normal file
15
assets/assetsfs.go
Normal file
@ -0,0 +1,15 @@
|
||||
// +build release
|
||||
|
||||
package assets
|
||||
|
||||
import "embed"
|
||||
|
||||
//go:embed *.html
|
||||
//go:embed graphicarts
|
||||
//go:embed javascripts
|
||||
//go:embed stylesheets
|
||||
var embedded embed.FS
|
||||
|
||||
func init() {
|
||||
FS.embedded = &embedded
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
Install `Go >= 1.14` and `gcc`. Get the source code:
|
||||
Install `Go >= 1.16` and `gcc`. Get the source code:
|
||||
|
||||
git clone https://github.com/nkanaev/yarr.git
|
||||
git clone https://github.com/nkanaev/gofeed.git yarr/gofeed
|
||||
|
2
go.mod
2
go.mod
@ -1,6 +1,6 @@
|
||||
module github.com/nkanaev/yarr
|
||||
|
||||
go 1.14
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/PuerkitoBio/goquery v1.5.1
|
||||
|
13
makefile
13
makefile
@ -1,24 +1,21 @@
|
||||
VERSION=1.3
|
||||
GITHASH=$(shell git rev-parse --short=8 HEAD)
|
||||
|
||||
ASSETS = assets/javascripts/* assets/stylesheets/* assets/graphicarts/* assets/*.html
|
||||
CGO_ENABLED=1
|
||||
|
||||
GO_LDFLAGS = -s -w
|
||||
GO_LDFLAGS := $(GO_LDFLAGS) -X 'main.Version=$(VERSION)' -X 'main.GitHash=$(GITHASH)'
|
||||
|
||||
default: bundle
|
||||
default: build_default
|
||||
|
||||
server/assets.go: $(ASSETS)
|
||||
go run scripts/bundle_assets.go >/dev/null
|
||||
|
||||
bundle: server/assets.go
|
||||
|
||||
build_default: bundle
|
||||
build_default:
|
||||
mkdir -p _output
|
||||
go build -tags "sqlite_foreign_keys release" -ldflags="$(GO_LDFLAGS)" -o _output/yarr main.go
|
||||
|
||||
build_macos: bundle
|
||||
build_macos:
|
||||
set GOOS=darwin
|
||||
set GOARCH=amd64
|
||||
mkdir -p _output/macos
|
||||
@ -26,13 +23,13 @@ build_macos: bundle
|
||||
cp artwork/icon.png _output/macos/icon.png
|
||||
go run scripts/package_macos.go -outdir _output/macos -version "$(VERSION)"
|
||||
|
||||
build_linux: bundle
|
||||
build_linux:
|
||||
set GOOS=linux
|
||||
set GOARCH=386
|
||||
mkdir -p _output/linux
|
||||
go build -tags "sqlite_foreign_keys release linux" -ldflags="$(GO_LDFLAGS)" -o _output/linux/yarr main.go
|
||||
|
||||
build_windows: bundle
|
||||
build_windows:
|
||||
set GOOS=windows
|
||||
set GOARCH=386
|
||||
mkdir -p _output/windows
|
||||
|
@ -1,97 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"text/template"
|
||||
htemplate "html/template"
|
||||
)
|
||||
|
||||
var code_template = `// +build release
|
||||
|
||||
// autogenerated. do not edit!
|
||||
|
||||
package server
|
||||
|
||||
var assets_bundle = map[string]asset{
|
||||
{{- range .}}
|
||||
"{{.Name}}": {etag: "{{.Etag}}", body: "{{.Body}}"},
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
func init() {
|
||||
assets = assets_bundle
|
||||
}
|
||||
`
|
||||
|
||||
type asset struct {
|
||||
Name, Etag, Body string
|
||||
}
|
||||
|
||||
func shasum(b []byte) string {
|
||||
h := sha256.New()
|
||||
h.Write(b)
|
||||
return fmt.Sprintf("%x", h.Sum(nil))[:16]
|
||||
}
|
||||
|
||||
func encode(b []byte) string {
|
||||
var buf bytes.Buffer
|
||||
zw := gzip.NewWriter(&buf)
|
||||
zw.Write(b)
|
||||
zw.Close()
|
||||
return base64.StdEncoding.EncodeToString(buf.Bytes())
|
||||
}
|
||||
|
||||
func main() {
|
||||
assets := make([]asset, 0)
|
||||
filepatterns := []string{
|
||||
"assets/login.html",
|
||||
"assets/graphicarts/*.svg",
|
||||
"assets/graphicarts/*.png",
|
||||
"assets/javascripts/*.js",
|
||||
"assets/stylesheets/*.css",
|
||||
"assets/stylesheets/*.map",
|
||||
}
|
||||
fmt.Printf("%8s %8s %s\n", "original", "encoded", "filename")
|
||||
for _, pattern := range filepatterns {
|
||||
filenames, _ := filepath.Glob(pattern)
|
||||
for _, filename := range filenames {
|
||||
content, _ := ioutil.ReadFile(filename)
|
||||
assets = append(assets, asset{
|
||||
Name: strings.TrimPrefix(strings.ReplaceAll(filename, "\\", "/"), "assets/"),
|
||||
Etag: shasum(content),
|
||||
Body: encode(content),
|
||||
})
|
||||
fmt.Printf(
|
||||
"%8d %8d %s\n",
|
||||
len(content),
|
||||
len(assets[len(assets)-1].Body),
|
||||
filename,
|
||||
)
|
||||
}
|
||||
}
|
||||
var indexbuf bytes.Buffer
|
||||
htemplate.Must(htemplate.New("index.html").Delims("{%", "%}").Funcs(htemplate.FuncMap{
|
||||
"inline": func(svg string) htemplate.HTML {
|
||||
content, _ := ioutil.ReadFile("assets/graphicarts/" + svg)
|
||||
return htemplate.HTML(content)
|
||||
},
|
||||
}).ParseFiles("assets/index.html")).Execute(&indexbuf, nil)
|
||||
indexcontent := indexbuf.Bytes()
|
||||
assets = append(assets, asset{
|
||||
Name: "index.html",
|
||||
Etag: shasum(indexcontent),
|
||||
Body: encode(indexcontent),
|
||||
})
|
||||
|
||||
var buf bytes.Buffer
|
||||
template := template.Must(template.New("code").Parse(code_template))
|
||||
template.Execute(&buf, assets)
|
||||
ioutil.WriteFile("server/assets.go", buf.Bytes(), 0644)
|
||||
}
|
@ -1,26 +1,22 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/nkanaev/yarr/storage"
|
||||
"github.com/nkanaev/yarr/assets"
|
||||
"html"
|
||||
"html/template"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"mime"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// TODO: gzip?
|
||||
var StaticHandler = http.StripPrefix("/static/", http.FileServer(http.FS(assets.FS))).ServeHTTP
|
||||
|
||||
var routes []Route = []Route{
|
||||
p("/", IndexHandler).ManualAuth(),
|
||||
p("/static/*path", StaticHandler).ManualAuth(),
|
||||
@ -43,36 +39,6 @@ var routes []Route = []Route{
|
||||
p("/logout", LogoutHandler),
|
||||
}
|
||||
|
||||
type asset struct {
|
||||
etag string
|
||||
body string // base64(gzip(content))
|
||||
gzipped *[]byte
|
||||
decoded *string
|
||||
}
|
||||
|
||||
func (a *asset) gzip() *[]byte {
|
||||
if a.gzipped == nil {
|
||||
gzipped, _ := base64.StdEncoding.DecodeString(a.body)
|
||||
a.gzipped = &gzipped
|
||||
}
|
||||
return a.gzipped
|
||||
}
|
||||
|
||||
func (a *asset) text() *string {
|
||||
if a.decoded == nil {
|
||||
gzipped, _ := base64.StdEncoding.DecodeString(a.body)
|
||||
reader, _ := gzip.NewReader(bytes.NewBuffer(gzipped))
|
||||
decoded, _ := ioutil.ReadAll(reader)
|
||||
reader.Close()
|
||||
|
||||
decoded_string := string(decoded)
|
||||
a.decoded = &decoded_string
|
||||
}
|
||||
return a.decoded
|
||||
}
|
||||
|
||||
var assets map[string]asset
|
||||
|
||||
type FolderCreateForm struct {
|
||||
Title string `json:"title"`
|
||||
}
|
||||
@ -104,43 +70,17 @@ func IndexHandler(rw http.ResponseWriter, req *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
if assets != nil {
|
||||
asset := assets["login.html"]
|
||||
rw.Header().Set("Content-Type", "text/html")
|
||||
rw.Header().Set("Content-Encoding", "gzip")
|
||||
rw.Write(*asset.gzip())
|
||||
return
|
||||
} else {
|
||||
f, err := os.Open("assets/login.html")
|
||||
if err != nil {
|
||||
handler(req).log.Print(err)
|
||||
assets.Render("login.html", rw, nil)
|
||||
return
|
||||
}
|
||||
io.Copy(rw, f)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if assets != nil {
|
||||
asset := assets["index.html"]
|
||||
|
||||
rw.Header().Set("Content-Type", "text/html")
|
||||
rw.Header().Set("Content-Encoding", "gzip")
|
||||
rw.Write(*asset.gzip())
|
||||
} else {
|
||||
t := template.Must(template.New("index.html").Delims("{%", "%}").Funcs(template.FuncMap{
|
||||
"inline": func(svg string) template.HTML {
|
||||
content, _ := ioutil.ReadFile("assets/graphicarts/" + svg)
|
||||
return template.HTML(content)
|
||||
},
|
||||
}).ParseFiles("assets/index.html"))
|
||||
rw.Header().Set("Content-Type", "text/html")
|
||||
t.Execute(rw, nil)
|
||||
}
|
||||
assets.Render("index.html", rw, nil)
|
||||
}
|
||||
|
||||
/*
|
||||
func StaticHandler(rw http.ResponseWriter, req *http.Request) {
|
||||
path := Vars(req)["path"]
|
||||
http.StripPrefix("/static/", http.FileServer(http.FS(assets.FS))).ServeHTTP(rw, req)
|
||||
ctype := mime.TypeByExtension(filepath.Ext(path))
|
||||
|
||||
if assets != nil {
|
||||
@ -164,6 +104,7 @@ func StaticHandler(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.Header().Set("Content-Type", ctype)
|
||||
io.Copy(rw, f)
|
||||
}
|
||||
*/
|
||||
|
||||
func StatusHandler(rw http.ResponseWriter, req *http.Request) {
|
||||
writeJSON(rw, map[string]interface{}{
|
||||
|
@ -19,7 +19,7 @@ func (r Route) ManualAuth() Route {
|
||||
return r
|
||||
}
|
||||
|
||||
func p(path string, handler func(http.ResponseWriter, *http.Request)) Route {
|
||||
func p(path string, handler http.HandlerFunc) Route {
|
||||
var urlRegexp string
|
||||
urlRegexp = regexp.MustCompile(`[\*\:]\w+`).ReplaceAllStringFunc(path, func(m string) string {
|
||||
if m[0:1] == `*` {
|
||||
|
Loading…
x
Reference in New Issue
Block a user