Skip to content
Snippets Groups Projects
Commit 53ca8de3 authored by Pavel Antonov's avatar Pavel Antonov :asterisk:
Browse files

Merge branch 'feature/PRXS-1715-WebPSupport' into 'master'

Добавлена поддержка webp в images

See merge request perxis/perxis-go!115
parents 003ed41e 31da3360
No related branches found
No related tags found
No related merge requests found
Showing
with 351 additions and 34 deletions
......@@ -10,12 +10,11 @@ PROTOFILES= $(filter-out $(PROTODIR)/status/status.proto, $(ALLPROTO))
PROTOGOFILES=$(PROTOFILES:.proto=.pb.go)
PROTOGOGRPCFILES=$(PROTOFILES:.proto=_grpc.pb.go)
PKGDIR=pkg
ACCESSLOGGING=$(shell find $(PKGDIR) -name "logging_middleware.go" -type f)
ERRORLOGGING=$(shell find $(PKGDIR) -name "error_logging_middleware.go" -type f)
SERVICETELEMETRY=$(shell find $(PKGDIR) -name "telemetry_middleware.go" -type f)
SERVICEMIDDLEWARE=$(shell find $(PKGDIR) -name "middleware.go" -type f)
SERVICERECOVERING=$(shell find $(PKGDIR) -name "recovering_middleware.go" -type f)
ACCESSLOGGING=$(shell find -name "logging_middleware.go" -type f)
ERRORLOGGING=$(shell find -name "error_logging_middleware.go" -type f)
SERVICETELEMETRY=$(shell find -name "telemetry_middleware.go" -type f)
SERVICEMIDDLEWARE=$(shell find -name "middleware.go" -type f)
SERVICERECOVERING=$(shell find -name "recovering_middleware.go" -type f)
# Генерация grpc-клиентов для go
proto: protoc-check protoc-gen-go-check $(PROTOGOFILES)
......
......@@ -5,6 +5,7 @@ go 1.21
require (
github.com/antonmedv/expr v1.9.0
github.com/avast/retry-go/v4 v4.5.1
github.com/bep/gowebp v0.2.0
github.com/go-kit/kit v0.13.0
github.com/gosimple/slug v1.13.1
github.com/hashicorp/go-multierror v1.1.1
......@@ -20,6 +21,7 @@ require (
go.opentelemetry.io/otel/trace v1.20.0
go.uber.org/zap v1.26.0
golang.org/x/crypto v0.15.0
golang.org/x/image v0.14.0
golang.org/x/net v0.18.0
golang.org/x/oauth2 v0.14.0
google.golang.org/grpc v1.59.0
......
......@@ -5,10 +5,10 @@ cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2Aawl
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/antonmedv/expr v1.9.0 h1:j4HI3NHEdgDnN9p6oI6Ndr0G5QryMY0FNxT4ONrFDGU=
github.com/antonmedv/expr v1.9.0/go.mod h1:5qsM3oLGDND7sDmQGDXHkYfkjYMUX14qsgqmHhwGEk8=
github.com/avast/retry-go/v4 v4.5.0 h1:QoRAZZ90cj5oni2Lsgl2GW8mNTnUCnmpx/iKpwVisHg=
github.com/avast/retry-go/v4 v4.5.0/go.mod h1:7hLEXp0oku2Nir2xBAsg0PTphp9z71bN5Aq1fboC3+I=
github.com/avast/retry-go/v4 v4.5.1 h1:AxIx0HGi4VZ3I02jr78j5lZ3M6x1E0Ivxa6b0pUUh7o=
github.com/avast/retry-go/v4 v4.5.1/go.mod h1:/sipNsvNB3RRuT5iNcb6h73nw3IBmXJ/H3XrCQYSOpc=
github.com/bep/gowebp v0.2.0 h1:ZVfK8i9PpZqKHEmthQSt3qCnnHycbLzBPEsVtk2ch2Q=
github.com/bep/gowebp v0.2.0/go.mod h1:ZhFodwdiFp8ehGJpF4LdPl6unxZm9lLFjxD3z2h2AgI=
github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
......@@ -52,8 +52,6 @@ github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyf
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4=
github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA=
github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s=
......@@ -111,16 +109,10 @@ github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.mongodb.org/mongo-driver v1.13.0 h1:67DgFFjYOCMWdtTEmKFpV3ffWlFnh+CYZ8ZS/tXWUfY=
go.mongodb.org/mongo-driver v1.13.0/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ=
go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs=
go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY=
go.opentelemetry.io/otel v1.20.0 h1:vsb/ggIY+hUjD/zCAQHpzTmndPqv/ml2ArbsbfBYTAc=
go.opentelemetry.io/otel v1.20.0/go.mod h1:oUIGj3D77RwJdM6PPZImDpSZGDvkD9fhesHny69JFrs=
go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE=
go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8=
go.opentelemetry.io/otel/metric v1.20.0 h1:ZlrO8Hu9+GAhnepmRGhSU7/VkpjrNowxRN9GyKR4wzA=
go.opentelemetry.io/otel/metric v1.20.0/go.mod h1:90DRw3nfK4D7Sm/75yQ00gTJxtkBxX+wu6YaNymbpVM=
go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg=
go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo=
go.opentelemetry.io/otel/trace v1.20.0 h1:+yxVAPZPbQhbC3OfAkeIVTky6iTFpcr4SiY9om7mXSQ=
go.opentelemetry.io/otel/trace v1.20.0/go.mod h1:HJSK7F/hA5RlzpZ0zKDCHCDHm556LCDtKaAo6JmBFUU=
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
......@@ -133,22 +125,19 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4=
golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY=
golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0=
golang.org/x/oauth2 v0.14.0 h1:P0Vrf/2538nmC0H+pEQ3MNFRRnVR7RlqyVw+bvm26z0=
golang.org/x/oauth2 v0.14.0/go.mod h1:lAtNWgaWfL4cm7j2OV8TxGi9Qb7ECORx8DktCY74OwM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
......
package convert
import (
"image"
"io"
"os"
"strings"
"git.perx.ru/perxis/perxis-go/pkg/errors"
)
type (
EncodeFunc func(w io.Writer, img image.Image) error
Format string
)
func (f Format) String() string {
return string(f)
}
var (
defaultFormatEncoderRegistry = make(map[Format]EncodeFunc)
formatExtensions = make(map[string]Format)
)
func RegisterFormatEncoder(format Format, fn EncodeFunc, extensions ...string) {
defaultFormatEncoderRegistry[format] = fn
formatExtensions[format.String()] = format
for _, ext := range extensions {
formatExtensions[strings.TrimPrefix(strings.ToLower(ext), ".")] = format
}
}
func Encode(w io.Writer, format Format, img image.Image) error {
encoder, ok := defaultFormatEncoderRegistry[format]
if !ok {
return errors.Errorf("unknown format: %s", format)
}
err := encoder(w, img)
if err != nil {
return errors.Wrap(err, "encode image")
}
return nil
}
func Decode(r io.Reader) (image.Image, string, error) {
img, ext, err := image.Decode(r)
if err != nil {
return nil, "", errors.Wrap(err, "decode image")
}
return img, ext, nil
}
func Open(filename string) (image.Image, string, error) {
file, err := os.Open(filename)
if err != nil {
return nil, "", errors.Wrap(err, "open file")
}
defer file.Close()
img, ext, err := Decode(file)
if err != nil {
return nil, "", errors.Wrap(err, "decode file")
}
return img, ext, nil
}
func FormatFromExtension(ext string) (Format, error) {
ext = strings.TrimPrefix(strings.ToLower(ext), ".")
if f, ok := formatExtensions[ext]; ok {
return f, nil
}
return "", errors.Errorf("unsupported format")
}
package convert
import (
"bytes"
"image"
"os"
"testing"
"github.com/stretchr/testify/require"
)
func TestOpen(t *testing.T) {
_, ext, err := Open("testdata/1.jpeg")
if err != nil {
return
}
require.NoError(t, err)
require.Equal(t, "jpeg", ext)
}
func TestFormatFromExtension(t *testing.T) {
var tests = []struct {
name string
input string
output Format
wantErr bool
}{
{
name: "correct jpeg",
input: "jpg",
output: JPEG,
wantErr: false,
},
{
name: "correct png",
input: "png",
output: PNG,
wantErr: false,
},
{
name: "incorrect any",
input: "any",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
format, err := FormatFromExtension(tt.input)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
require.Equal(t, tt.output, format)
}
})
}
}
func TestEncode(t *testing.T) {
var tests = []struct {
name string
input Format
wantErr bool
}{
{
name: "unknown format",
input: "go",
wantErr: true,
},
{
name: "jpeg format",
input: JPEG,
wantErr: false,
},
{
name: "png format",
input: PNG,
wantErr: false,
},
{
name: "gif format",
input: GIF,
wantErr: false,
},
{
name: "tiff format",
input: TIFF,
wantErr: false,
},
{
name: "bmp format",
input: BMP,
wantErr: false,
},
}
img := image.NewRGBA(image.Rect(0, 0, 10, 10))
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
buf := new(bytes.Buffer)
err := Encode(buf, tt.input, img)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestDecode(t *testing.T) {
var tests = []struct {
name string
input string
output string
wantErr bool
}{
{
name: "unknown format",
input: "testdata/1.go",
wantErr: true,
},
{
name: "jpeg format",
input: "testdata/1.jpeg",
output: "jpeg",
wantErr: false,
},
{
name: "png format",
input: "testdata/1.png",
output: "png",
wantErr: false,
},
{
name: "gif format",
input: "testdata/1.gif",
output: "gif",
wantErr: false,
},
{
name: "tiff format",
input: "testdata/1.tiff",
output: "tiff",
wantErr: false,
},
{
name: "bmp format",
input: "testdata/1.bmp",
output: "bmp",
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
file, err := os.Open(tt.input)
if err != nil {
t.Fatal(err)
}
defer file.Close()
_, ext, err := Decode(file)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
require.Equal(t, tt.output, ext)
}
})
}
}
package convert
import (
"image"
"image/gif"
"image/jpeg"
"image/png"
"io"
"golang.org/x/image/bmp"
"golang.org/x/image/tiff"
)
const (
JPEG Format = "jpeg"
PNG Format = "png"
GIF Format = "gif"
TIFF Format = "tiff"
BMP Format = "bmp"
)
func init() {
RegisterFormatEncoder(JPEG, func(w io.Writer, img image.Image) error { return jpeg.Encode(w, img, nil) }, "jpg")
RegisterFormatEncoder(PNG, png.Encode)
RegisterFormatEncoder(GIF, func(w io.Writer, img image.Image) error { return gif.Encode(w, img, nil) })
RegisterFormatEncoder(TIFF, func(w io.Writer, img image.Image) error { return tiff.Encode(w, img, nil) }, "tif")
RegisterFormatEncoder(BMP, bmp.Encode)
}
images/convert/testdata/1.bmp

313 KiB

images/convert/testdata/1.gif

289 KiB

package testdata
// hi
images/convert/testdata/1.jpeg

43.8 KiB

images/convert/testdata/1.png

8.2 KiB

images/convert/testdata/1.tiff

14.6 KiB

images/convert/testdata/1.webp

29.6 KiB

//go:build webp
package convert
import (
"image"
"io"
"github.com/bep/gowebp/libwebp"
"github.com/bep/gowebp/libwebp/webpoptions"
// Нужно включать в сборку для вызова регистрации декодера в стандартном
// пакете "images" для декодирования файлов webp.
_ "golang.org/x/image/webp"
)
const (
WEBP Format = "webp"
)
func init() {
RegisterFormatEncoder(WEBP, func(w io.Writer, img image.Image) error { return libwebp.Encode(w, img, webpoptions.EncodingOptions{}) })
}
//go:build webp
package convert
import (
"bytes"
"image"
"os"
"testing"
"github.com/stretchr/testify/require"
)
func TestEncodeWebP(t *testing.T) {
img := image.NewRGBA(image.Rect(0, 0, 10, 10))
buf := new(bytes.Buffer)
err := Encode(buf, WEBP, img)
require.NoError(t, err)
}
func TestDecodeWebP(t *testing.T) {
file, err := os.Open("testdata/1.webp")
if err != nil {
t.Fatal(err)
}
defer file.Close()
_, ext, err := Decode(file)
require.NoError(t, err)
require.Equal(t, "webp", ext)
}
// Code generated by gowrap. DO NOT EDIT.
// template: ../../../assets/templates/middleware/error_log
// template: ../../assets/templates/middleware/error_log
// gowrap: http://github.com/hexdigest/gowrap
package middleware
//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/images -i Images -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l ""
//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/images -i Images -t ../../assets/templates/middleware/error_log -o error_logging_middleware.go -l ""
import (
"context"
"git.perx.ru/perxis/perxis-go/images"
"git.perx.ru/perxis/perxis-go/pkg/files"
"git.perx.ru/perxis/perxis-go/pkg/images"
"go.uber.org/zap"
)
......
// Code generated by gowrap. DO NOT EDIT.
// template: ../../../assets/templates/middleware/access_log
// template: ../../assets/templates/middleware/access_log
// gowrap: http://github.com/hexdigest/gowrap
package middleware
//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/images -i Images -t ../../../assets/templates/middleware/access_log -o logging_middleware.go -l ""
//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/images -i Images -t ../../assets/templates/middleware/access_log -o logging_middleware.go -l ""
import (
"context"
"fmt"
"time"
"git.perx.ru/perxis/perxis-go/images"
"git.perx.ru/perxis/perxis-go/pkg/auth"
"git.perx.ru/perxis/perxis-go/pkg/files"
"git.perx.ru/perxis/perxis-go/pkg/images"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
......
......@@ -4,10 +4,10 @@
package middleware
//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/images -i Images -t ../../../assets/templates/middleware/middleware -o middleware.go -l ""
//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/images -i Images -t ../../assets/templates/middleware/middleware -o middleware.go -l ""
import (
"git.perx.ru/perxis/perxis-go/pkg/images"
"git.perx.ru/perxis/perxis-go/images"
"go.uber.org/zap"
)
......
......@@ -4,14 +4,14 @@
package middleware
//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/images -i Images -t ../../../assets/templates/middleware/recovery -o recovering_middleware.go -l ""
//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/images -i Images -t ../../assets/templates/middleware/recovery -o recovering_middleware.go -l ""
import (
"context"
"fmt"
"git.perx.ru/perxis/perxis-go/images"
"git.perx.ru/perxis/perxis-go/pkg/files"
"git.perx.ru/perxis/perxis-go/pkg/images"
"go.uber.org/zap"
)
......
......@@ -4,13 +4,13 @@
package middleware
//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/images -i Images -t ../../../assets/templates/middleware/telemetry -o telemetry_middleware.go -l ""
//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/images -i Images -t ../../assets/templates/middleware/telemetry -o telemetry_middleware.go -l ""
import (
"context"
"git.perx.ru/perxis/perxis-go/images"
"git.perx.ru/perxis/perxis-go/pkg/files"
"git.perx.ru/perxis/perxis-go/pkg/images"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment