diff --git a/.deb.yaml b/.deb.yaml index c98d3e3..5ecaecb 100755 --- a/.deb.yaml +++ b/.deb.yaml @@ -1,6 +1,6 @@ package: jasta source: jasta -version: 1:0.3.2 +version: 1:0.3.3 architecture: - amd64 - arm64 diff --git a/Makefile b/Makefile index 2a4e7a3..3ad9475 100755 --- a/Makefile +++ b/Makefile @@ -32,6 +32,9 @@ ci: install setup lint build tests run_local: go run cmd/jasta/main.go --config=config/config.dev.yaml +prerender_local: + go run cmd/jasta/main.go prerender + deb: deb-builder build diff --git a/cmd/jasta/main.go b/cmd/jasta/main.go index 7f06248..36ce5d7 100644 --- a/cmd/jasta/main.go +++ b/cmd/jasta/main.go @@ -12,8 +12,13 @@ import ( "go.osspkg.com/goppy/web" ) +var Version = "v0.0.0-dev" + func main() { app := goppy.New() + app.AppName("jasta") + app.AppDescription("Gateway for static sites") + app.AppVersion(Version) app.Plugins( web.WithHTTP(), ) diff --git a/config/config.dev.yaml b/config/config.dev.yaml index cb3feed..e03a6b9 100755 --- a/config/config.dev.yaml +++ b/config/config.dev.yaml @@ -1,6 +1,8 @@ env: dev -level: 4 -log: /dev/stdout +log: + level: 4 + file_path: /dev/stdout + format: string http: main: diff --git a/config/config.yaml b/config/config.yaml index 6eb8991..f29153f 100755 --- a/config/config.yaml +++ b/config/config.yaml @@ -1,6 +1,8 @@ env: dev -level: 4 -log: /var/log/jasta.log +log: + level: 4 + file_path: /var/log/jasta.log + format: string http: main: diff --git a/go.mod b/go.mod index c69c254..336c700 100644 --- a/go.mod +++ b/go.mod @@ -3,27 +3,27 @@ module github.com/osspkg/jasta go 1.20 require ( - go.osspkg.com/goppy v0.15.8 - go.osspkg.com/goppy/app v0.1.4 - go.osspkg.com/goppy/console v0.1.0 - go.osspkg.com/goppy/errors v0.1.0 - go.osspkg.com/goppy/iofile v0.1.3 - go.osspkg.com/goppy/plugins v0.1.1 - go.osspkg.com/goppy/shell v0.1.0 - go.osspkg.com/goppy/syscall v0.1.0 - go.osspkg.com/goppy/web v0.1.4 - go.osspkg.com/goppy/xlog v0.1.4 + go.osspkg.com/goppy v0.17.3 + go.osspkg.com/goppy/console v0.3.1 + go.osspkg.com/goppy/iofile v0.3.1 + go.osspkg.com/goppy/plugins v0.3.1 + go.osspkg.com/goppy/shell v0.3.0 + go.osspkg.com/goppy/syscall v0.3.0 + go.osspkg.com/goppy/web v0.3.2 + go.osspkg.com/goppy/xlog v0.3.1 go.osspkg.com/static v1.4.0 - golang.org/x/image v0.14.0 ) require ( github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect - go.osspkg.com/algorithms v1.3.0 // indirect - go.osspkg.com/goppy/iosync v0.1.2 // indirect - go.osspkg.com/goppy/ioutil v0.1.0 // indirect - go.osspkg.com/goppy/xc v0.1.0 // indirect - go.osspkg.com/goppy/xnet v0.1.1 // indirect + go.osspkg.com/algorithms v1.3.1 // indirect + go.osspkg.com/goppy/app v0.3.3 // indirect + go.osspkg.com/goppy/env v0.3.0 // indirect + go.osspkg.com/goppy/errors v0.3.0 // indirect + go.osspkg.com/goppy/iosync v0.3.0 // indirect + go.osspkg.com/goppy/ioutil v0.3.0 // indirect + go.osspkg.com/goppy/xc v0.3.0 // indirect + go.osspkg.com/goppy/xnet v0.3.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 30217a3..39969fa 100644 --- a/go.sum +++ b/go.sum @@ -6,44 +6,44 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -go.osspkg.com/algorithms v1.3.0 h1:rrKO440aNTofYJwGnOVsW00w0VRtZtu+BQrgXMXw7j4= -go.osspkg.com/algorithms v1.3.0/go.mod h1:J2SXxHdqBK9ALGYJomA9XGvTOhIwMK0fvVw+KusYyoo= -go.osspkg.com/goppy v0.15.8 h1:VNxG/pJLRNuo7cvab1UF5kC2Tr7KguwyBpQau32lqzA= -go.osspkg.com/goppy v0.15.8/go.mod h1:0dUVSEiLjrWD0IuGKTHKWA6vV3VUrz4u4CGBwCKffS4= -go.osspkg.com/goppy/app v0.1.4 h1:Los8E/6/PNiD4pLy22RDJUc98h69MCDQv/Mn0q2idc8= -go.osspkg.com/goppy/app v0.1.4/go.mod h1:3pBd9xeqxcAlWScY6A9uoK87XGx5+9hVP9U9KQRoF/o= -go.osspkg.com/goppy/console v0.1.0 h1:ksQzyPFJlp9EY48tyAU6fOzKLfKkGa0KIB+fPkhTnJE= -go.osspkg.com/goppy/console v0.1.0/go.mod h1:x4MxAqsjTygGXyu1QkDLTvRaeQVU3/0euCxSQjtXzic= -go.osspkg.com/goppy/errors v0.1.0 h1:2q8gdRZMEEDk7y/sneblQxpHhsi3pqF1BbFFHS7+FnE= -go.osspkg.com/goppy/errors v0.1.0/go.mod h1:SvA8dgErO9e2i3TR8hgJV4uMAzs4TkL4FxXBSnw2UG4= -go.osspkg.com/goppy/iofile v0.1.3 h1:JxKOeysFUCB9JDvqgwQTBrQz4mISdSE2ouRxX8RJrKA= -go.osspkg.com/goppy/iofile v0.1.3/go.mod h1:bJTlDCHoZ3rENuu7ZE4KzzJJNv1CVq1TRZmj9phhXC8= -go.osspkg.com/goppy/iosync v0.1.2 h1:w0BxqBa7PAdxFM2P8pZn3ToHK6ilX5IG+1nwIXJEoGg= -go.osspkg.com/goppy/iosync v0.1.2/go.mod h1:huJpHhpIQ2DgzY3wVt72RUsJaje0uqYiUvMRovb1/Dg= -go.osspkg.com/goppy/ioutil v0.1.0 h1:Z9CF1nzrjbcHJV1EIcLqOPAotePScuCjmTSyU7BoLzk= -go.osspkg.com/goppy/ioutil v0.1.0/go.mod h1:WpZGj1HpuBlDDH5k8mn+2QwPssMP83jKj59U8qLsBoU= -go.osspkg.com/goppy/plugins v0.1.1 h1:ly/g8LyGQNhT9BLKLbhHejUuPho5atd4uJmitorQyvM= -go.osspkg.com/goppy/plugins v0.1.1/go.mod h1:oolaNTq9VCWBAApLUFCHvWZ/7tMUhzLaqQEIxmLviNQ= -go.osspkg.com/goppy/shell v0.1.0 h1:L/28FTiO+Mo+YxjKj1dwYI+1oJWgMq4RAfgS6aDSA1Q= -go.osspkg.com/goppy/shell v0.1.0/go.mod h1:K6EnrxB2vD2Hpg1mJIkeQKcZ9VEAnX5pBWhMgUBBds0= -go.osspkg.com/goppy/syscall v0.1.0 h1:qOkgnjRo4RlSyYDQiYzZqfmGUIO9tuIZZ/OKsvfC3+s= -go.osspkg.com/goppy/syscall v0.1.0/go.mod h1:8MsNFOYAzNzGI6FE+0hmqLINQ5cxVkhqHUyirzENG9A= -go.osspkg.com/goppy/web v0.1.4 h1:rvAU2nVLn5m37A8LgWvJcSC1xTkVgPruVm7BLAiyCE0= -go.osspkg.com/goppy/web v0.1.4/go.mod h1:fHCxV/5F6ulR5FmCr3csDXI9D1tGVC0CZr5K7DGvsmQ= -go.osspkg.com/goppy/xc v0.1.0 h1:e2231FumnLEf1OjqEtbRaUxz3FT9M8pZVKg0C0aTf7g= -go.osspkg.com/goppy/xc v0.1.0/go.mod h1:ocKrJbO+EADhuClTbOqzDfCqnUO9+ikEW0M7pqLl1Y4= -go.osspkg.com/goppy/xlog v0.1.4 h1:3+o71O3Jb8UgfSA6nfpfQHfhHLIploHhlQ4p+Yfj5So= -go.osspkg.com/goppy/xlog v0.1.4/go.mod h1:AtYBxgKaxQxFWmb/SbmLvYp7ysuE2i1YYSE3Pu29nNQ= -go.osspkg.com/goppy/xnet v0.1.1 h1:nysNyS5O7nHXIN/IjP9HGfa6Qh5BTTSYLULijk+Sv9M= -go.osspkg.com/goppy/xnet v0.1.1/go.mod h1:eB5pFfZTCrcaIOHzt4RlTgBVF5dRUV/u52qz/2hY3qk= -go.osspkg.com/goppy/xtest v0.1.2 h1:rbUzEnWZW9vkGa24owydA9icQcfOaROJWSym1l0mCtU= +go.osspkg.com/algorithms v1.3.1 h1:Weh0Z4dMzHFRJTfMva/mU6Uk95wSRGwt1Saj2sfz3Wc= +go.osspkg.com/algorithms v1.3.1/go.mod h1:kj+oVK7UDQlXMKleMTYzbEEpUAXC2tzRBtki7F5EbXc= +go.osspkg.com/goppy v0.17.3 h1:ouLV9o2TTciR2+nkVzl9JPpm9HJMiNFlHPaWCDr3waM= +go.osspkg.com/goppy v0.17.3/go.mod h1:+lHoulh1Q0EU1LeWqnBfFyX+yvFsqQ5MsBnGHWTd4qE= +go.osspkg.com/goppy/app v0.3.3 h1:pQy1ptCg+8dloUx1icHtmJ9CEm4ZLgkiXlOfxMVLtlQ= +go.osspkg.com/goppy/app v0.3.3/go.mod h1:hv+T2GuR5hnDUI57qUsQQaN0wzg6I4FiuOcziEyoBG0= +go.osspkg.com/goppy/console v0.3.1 h1:fg1HDeev01h55k29B6LyzCDf3b2sn5yl3YYOGN2f4w0= +go.osspkg.com/goppy/console v0.3.1/go.mod h1:TpDVGqmJaKuxemUUPj/cNyLEo3jlyL/T0iOzsZDmjjY= +go.osspkg.com/goppy/env v0.3.0 h1:F4hq5KCjMfhXIcsNvbfQzdVHpB8ZVu7XMj0F1hZrq7c= +go.osspkg.com/goppy/env v0.3.0/go.mod h1:7r+0+1h2mFfat5vaWHPu4+Zl9vq6+raz59ScmqLe4zI= +go.osspkg.com/goppy/errors v0.3.0 h1:n98V9gW8UOfooY9Y9FNwV7oznKGQxrIr/J19brqayzc= +go.osspkg.com/goppy/errors v0.3.0/go.mod h1:rbBTNHK0wpGi3FgJ4M27n7LOvB3Aw6kKc0Q4np16wh0= +go.osspkg.com/goppy/iofile v0.3.1 h1:AwuU7PuCPfFAPRKZv2dlOoqrlQfE8T7lERFktbT6650= +go.osspkg.com/goppy/iofile v0.3.1/go.mod h1:2Efhu11htfc4/IIuWtJ8iIQB86kkBaDKslsaive8Kfs= +go.osspkg.com/goppy/iosync v0.3.0 h1:eClduMtjVZUPpNYzHm7EClCa3y58lB/FlIRtHgyU9YE= +go.osspkg.com/goppy/iosync v0.3.0/go.mod h1:Ocol//DRF4n0m40jFmYBxnjHtFjeyeO0RcY/pwOCtsg= +go.osspkg.com/goppy/ioutil v0.3.0 h1:dcjuZMrL2CXOMA9UbVlxMZvHXiRbwxFCMfh9hCPsdE4= +go.osspkg.com/goppy/ioutil v0.3.0/go.mod h1:pbyQ/pa301T+0T9rb9bZd6q4ofC4yVAFWu0sQvjitmc= +go.osspkg.com/goppy/plugins v0.3.1 h1:mxjcgs24BvCii19aKYCXVz+EpmW2qjT4JX6bsc8RgJk= +go.osspkg.com/goppy/plugins v0.3.1/go.mod h1:WTSeS/6B2K1FAciQBqHgE0u0t8BD94ehD+HK1hV/IrA= +go.osspkg.com/goppy/shell v0.3.0 h1:h1w3vRoaro2d6s/A1Tvghq5de8wHDwoobNONwhkxiJc= +go.osspkg.com/goppy/shell v0.3.0/go.mod h1:ZgAoKBOyHor1xyPZdgljNLh/gnd1EKiOhYhgFT3xueQ= +go.osspkg.com/goppy/syscall v0.3.0 h1:2PcpkqC1ol14HTOC+XyG+3lsuQ9pnG9ueE4xFywoSdE= +go.osspkg.com/goppy/syscall v0.3.0/go.mod h1:Vz1BCzM8MmyC/26SjiVh6OGcAkky1y4xalSWbVceiL4= +go.osspkg.com/goppy/web v0.3.2 h1:+U3JNcRHzbgrL0kOWFzCXL5YjZVmvL1tN8q8dQ0fL6E= +go.osspkg.com/goppy/web v0.3.2/go.mod h1:zrWR2jWXhF7TllfBVwXmCsk6u7qXHuIhqaIAXcJvV1k= +go.osspkg.com/goppy/xc v0.3.0 h1:3r10skiV63AO5OnjvbpEpLF8p8eqYB+AbRa6cnxKsmQ= +go.osspkg.com/goppy/xc v0.3.0/go.mod h1:Diqc/s597erdipSXBHSg5RZsFizleLrqxBCSwGeuktQ= +go.osspkg.com/goppy/xlog v0.3.1 h1:ZPzjau9cNiXbh7YbopRGWnEKhNndpNAEqwqPeqqHwrg= +go.osspkg.com/goppy/xlog v0.3.1/go.mod h1:YnsETZ6KaMKy8UA4u03rwRcsdJFMy1Jygsv5DYHHnLU= +go.osspkg.com/goppy/xnet v0.3.0 h1:rGzTtjGnRmk2s1ujI6Si6fXAS85WO2qeoQeoxfw34QI= +go.osspkg.com/goppy/xnet v0.3.0/go.mod h1:/XIH64sw58nOA3Ma7z6i26Kp8bqKMNQpdjAoI6FVe9Q= +go.osspkg.com/goppy/xtest v0.3.0 h1:QV0159LiYXKALfsOwhCG+zUuy5jnIFeopYs00PSRa2g= go.osspkg.com/static v1.4.0 h1:2uy4/11c0QP+QLMucKQZbAU+e6lhVHKw5dWJPTk/DBg= go.osspkg.com/static v1.4.0/go.mod h1:94YydVU3qUtb1J534486lpm+qg6CviQjqtxKlkpSppM= -golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4= -golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= 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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/jasta/plugin.go b/internal/jasta/plugin.go index abb80d0..bbc575b 100644 --- a/internal/jasta/plugin.go +++ b/internal/jasta/plugin.go @@ -9,7 +9,7 @@ import ( "fmt" "github.com/osspkg/jasta/internal/utils" - "go.osspkg.com/goppy/app" + "go.osspkg.com/goppy/iofile" "go.osspkg.com/goppy/plugins" ) @@ -34,7 +34,7 @@ func WebsiteConfigDecode(c *Config) (WebsiteConfigs, error) { } for _, filename := range files { wc := &WebsiteConfig{} - if err = app.Sources(filename).Decode(wc); err != nil { + if err = iofile.FileCodec(filename).Decode(wc); err != nil { return nil, fmt.Errorf("invalid website config [%s]: %w", filename, err) } if err = wc.Validate(); err != nil { diff --git a/internal/utils/images.go b/internal/utils/images.go deleted file mode 100644 index 3df4753..0000000 --- a/internal/utils/images.go +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (c) 2023 Mikhail Knyazhev . All rights reserved. - * Use of this source code is governed by a BSD-3-Clause license that can be found in the LICENSE file. - */ - -package utils - -import ( - "crypto/sha1" - "fmt" - "image" - "image/jpeg" - "image/png" - "io" - "os" - "path/filepath" - "strings" - "sync" - - "go.osspkg.com/goppy/errors" - "go.osspkg.com/goppy/xlog" - "golang.org/x/image/bmp" - "golang.org/x/image/draw" - "golang.org/x/image/tiff" - "golang.org/x/image/webp" -) - -var ( - ExtNotSupported = errors.New("ext is not supported") -) - -type ( - Images struct { - folder string - cache map[string]ImageInfo - mux sync.Mutex - } - - ImageInfo struct { - Hash string - Origin string - Scale string - Thumb string - } -) - -var decoders = map[string]func(r io.Reader) (image.Image, error){ - ".jpg": jpeg.Decode, - ".jpeg": jpeg.Decode, - ".png": png.Decode, - ".webp": webp.Decode, - ".bmp": bmp.Decode, - ".tiff": tiff.Decode, -} - -func New() *Images { - return &Images{ - folder: "", - cache: make(map[string]ImageInfo, 100), - } -} - -func (v *Images) SetFolder(dir string) error { - if err := os.MkdirAll(dir, 0755); err != nil { - return fmt.Errorf("create image folder: %w", err) - } - v.folder = dir - return nil -} - -func (v *Images) Build(filename string, scale, thumb int) (*ImageInfo, error) { - var err error - img := &ImageInfo{} - - if img.Hash, err = v.getHash(filename); err != nil { - return nil, err - } - - v.mux.Lock() - i, ok := v.cache[img.Hash] - v.mux.Unlock() - if ok { - return &i, nil - } - - if img.Origin, err = v.resize(filename, img.Hash+".orig", 0); err != nil { - return nil, err - } - if img.Scale, err = v.resize(filename, img.Hash+".scale", scale); err != nil { - return nil, err - } - if img.Thumb, err = v.resize(filename, img.Hash+".thumb", thumb); err != nil { - return nil, err - } - - v.mux.Lock() - v.cache[img.Hash] = *img - v.mux.Unlock() - - return img, nil -} - -func (v *Images) resize(filename, suffix string, width int) (string, error) { - src, name, err := v.readFile(filename) - if err != nil { - return "", err - } - x, y := v.scaleFactor(src.Bounds().Max.X, src.Bounds().Max.Y, width) - dst := image.NewNRGBA(image.Rect(0, 0, x, y)) - draw.CatmullRom.Scale(dst, dst.Rect, src, src.Bounds(), draw.Over, nil) - newFilename := fmt.Sprintf("%s-%s.png", name, suffix) - return newFilename, v.writeFile(v.folder+"/"+newFilename, dst) -} - -func (v *Images) scaleFactor(oW, oH, width int) (int, int) { - if width == 0 { - return oW, oH - } - oWF, oHF := float64(oW), float64(oH) - nWidth := float64(width) - scale := oWF / nWidth - return int(oWF / scale), int(oHF / scale) -} - -func (v *Images) writeFile(filename string, img image.Image) error { - file, err := os.Create(filename) - if err != nil { - return fmt.Errorf("write image `%s`: %w", filename, err) - } - defer func() { - if err0 := file.Close(); err0 != nil { - xlog.WithFields(xlog.Fields{ - "err": err0.Error(), - "file": filename, - }).Errorf("Close image file") - } - }() - if err = png.Encode(file, img); err != nil { - return fmt.Errorf("encode image `%s`: %w", filename, err) - } - return nil -} - -func (v *Images) readFile(filename string) (image.Image, string, error) { - ext := filepath.Ext(filename) - dec, ok := decoders[ext] - if !ok { - return nil, "", ExtNotSupported - } - - file, err := os.Open(filename) - if err != nil { - return nil, "", fmt.Errorf("read image `%s`: %w", filename, err) - } - defer func() { - if err0 := file.Close(); err0 != nil { - xlog.WithFields(xlog.Fields{ - "err": err0.Error(), - "file": filename, - }).Errorf("Close image file") - } - }() - - img, err := dec(file) - if err != nil { - return nil, "", fmt.Errorf("decode image `%s`: %w", filename, err) - } - fi, err := file.Stat() - if err != nil { - return nil, "", fmt.Errorf("info image `%s`: %w", filename, err) - } - return img, strings.Replace(fi.Name(), ext, "", 1), nil -} - -func (v *Images) getHash(filename string) (string, error) { - file, err := os.Open(filename) - if err != nil { - return "", fmt.Errorf("read image `%s`: %w", filename, err) - } - defer func() { - if err0 := file.Close(); err0 != nil { - xlog.WithFields(xlog.Fields{ - "err": err0.Error(), - "file": filename, - }).Errorf("Close image file") - } - }() - - h := sha1.New() - if _, err = io.Copy(h, file); err != nil { - return "", fmt.Errorf("calc hash image `%s`: %w", filename, err) - } - return fmt.Sprintf("%x", h.Sum(nil)), nil -}