mirror of
https://github.com/imgproxy/imgproxy.git
synced 2025-07-12 23:00:55 +02:00
Log modified processing options only
This commit is contained in:
@ -7,7 +7,8 @@
|
|||||||
- Using Application Default Credentials when `IMGPROXY_USE_GCS` is set to `true` but `IMGPROXY_GCS_KEY` is not set.
|
- Using Application Default Credentials when `IMGPROXY_USE_GCS` is set to `true` but `IMGPROXY_GCS_KEY` is not set.
|
||||||
**Note:** If you use `IMGPROXY_GCS_KEY`, it's recommended to set `IMGPROXY_USE_GCS` to `true` since it may be required by future versions to enable GCS support;
|
**Note:** If you use `IMGPROXY_GCS_KEY`, it's recommended to set `IMGPROXY_USE_GCS` to `true` since it may be required by future versions to enable GCS support;
|
||||||
- Setting `IMGPROXY_REPORT_DOWNLOADING_ERRORS` to `false` disables reporting of downloading errors;
|
- Setting `IMGPROXY_REPORT_DOWNLOADING_ERRORS` to `false` disables reporting of downloading errors;
|
||||||
- SVG passthrough. When source image and requested format are SVG, image will be returned without changes.
|
- SVG passthrough. When source image and requested format are SVG, image will be returned without changes;
|
||||||
|
- Log only modified processing options.
|
||||||
|
|
||||||
## v2.5.0
|
## v2.5.0
|
||||||
|
|
||||||
|
@ -10,6 +10,9 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
structdiff "github.com/imgproxy/imgproxy/struct-diff"
|
||||||
)
|
)
|
||||||
|
|
||||||
type urlOption struct {
|
type urlOption struct {
|
||||||
@ -158,22 +161,33 @@ func (rt resizeType) String() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
_newProcessingOptions processingOptions
|
||||||
|
newProcessingOptionsOnce sync.Once
|
||||||
|
)
|
||||||
|
|
||||||
func newProcessingOptions() *processingOptions {
|
func newProcessingOptions() *processingOptions {
|
||||||
return &processingOptions{
|
newProcessingOptionsOnce.Do(func() {
|
||||||
Resize: resizeFit,
|
_newProcessingOptions = processingOptions{
|
||||||
Width: 0,
|
Resize: resizeFit,
|
||||||
Height: 0,
|
Width: 0,
|
||||||
Gravity: gravityOptions{Type: gravityCenter},
|
Height: 0,
|
||||||
Enlarge: false,
|
Gravity: gravityOptions{Type: gravityCenter},
|
||||||
Quality: conf.Quality,
|
Enlarge: false,
|
||||||
Format: imageTypeUnknown,
|
Quality: conf.Quality,
|
||||||
Background: rgbColor{255, 255, 255},
|
Format: imageTypeUnknown,
|
||||||
Blur: 0,
|
Background: rgbColor{255, 255, 255},
|
||||||
Sharpen: 0,
|
Blur: 0,
|
||||||
Dpr: 1,
|
Sharpen: 0,
|
||||||
Watermark: watermarkOptions{Opacity: 1, Replicate: false, Gravity: gravityCenter},
|
Dpr: 1,
|
||||||
UsedPresets: make([]string, 0, len(conf.Presets)),
|
Watermark: watermarkOptions{Opacity: 1, Replicate: false, Gravity: gravityCenter},
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
po := _newProcessingOptions
|
||||||
|
po.UsedPresets = make([]string, 0, len(conf.Presets))
|
||||||
|
|
||||||
|
return &po
|
||||||
}
|
}
|
||||||
|
|
||||||
func (po *processingOptions) isPresetUsed(name string) bool {
|
func (po *processingOptions) isPresetUsed(name string) bool {
|
||||||
@ -189,8 +203,16 @@ func (po *processingOptions) presetUsed(name string) {
|
|||||||
po.UsedPresets = append(po.UsedPresets, name)
|
po.UsedPresets = append(po.UsedPresets, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (po *processingOptions) Diff() structdiff.Entries {
|
||||||
|
return structdiff.Diff(newProcessingOptions(), po)
|
||||||
|
}
|
||||||
|
|
||||||
func (po *processingOptions) String() string {
|
func (po *processingOptions) String() string {
|
||||||
return fmt.Sprintf("%+v", *po)
|
return po.Diff().String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (po *processingOptions) MarshalJSON() ([]byte, error) {
|
||||||
|
return po.Diff().MarshalJSON()
|
||||||
}
|
}
|
||||||
|
|
||||||
func colorFromHex(hexcolor string) (rgbColor, error) {
|
func colorFromHex(hexcolor string) (rgbColor, error) {
|
||||||
|
106
struct-diff/diff.go
Normal file
106
struct-diff/diff.go
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
package structdiff
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
var bufPool = sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
return new(bytes.Buffer)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
type Entry struct {
|
||||||
|
Name string
|
||||||
|
Value interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Entries []Entry
|
||||||
|
|
||||||
|
func (d Entries) String() string {
|
||||||
|
buf := bufPool.Get().(*bytes.Buffer)
|
||||||
|
last := len(d) - 1
|
||||||
|
|
||||||
|
buf.Reset()
|
||||||
|
|
||||||
|
for i, e := range d {
|
||||||
|
buf.WriteString(e.Name)
|
||||||
|
buf.WriteString(": ")
|
||||||
|
|
||||||
|
if dd, ok := e.Value.(Entries); ok {
|
||||||
|
buf.WriteByte('{')
|
||||||
|
buf.WriteString(dd.String())
|
||||||
|
buf.WriteByte('}')
|
||||||
|
} else {
|
||||||
|
fmt.Fprint(buf, e.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
if i != last {
|
||||||
|
buf.WriteString("; ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Entries) MarshalJSON() ([]byte, error) {
|
||||||
|
buf := bufPool.Get().(*bytes.Buffer)
|
||||||
|
last := len(d) - 1
|
||||||
|
|
||||||
|
buf.Reset()
|
||||||
|
|
||||||
|
buf.WriteByte('{')
|
||||||
|
|
||||||
|
for i, e := range d {
|
||||||
|
j, err := json.Marshal(e.Value)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(buf, "%q:%s", e.Name, j)
|
||||||
|
|
||||||
|
if i != last {
|
||||||
|
buf.WriteByte(',')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.WriteByte('}')
|
||||||
|
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Diff(a, b interface{}) Entries {
|
||||||
|
valA := reflect.Indirect(reflect.ValueOf(a))
|
||||||
|
valB := reflect.Indirect(reflect.ValueOf(b))
|
||||||
|
|
||||||
|
d := make(Entries, 0, valA.NumField())
|
||||||
|
|
||||||
|
if valA.Type() != valB.Type() {
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < valA.NumField(); i++ {
|
||||||
|
fieldA := valA.Field(i)
|
||||||
|
fieldB := valB.Field(i)
|
||||||
|
|
||||||
|
intA := fieldA.Interface()
|
||||||
|
intB := fieldB.Interface()
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(intA, intB) {
|
||||||
|
name := valB.Type().Field(i).Name
|
||||||
|
value := intB
|
||||||
|
|
||||||
|
if fieldB.Kind() == reflect.Struct {
|
||||||
|
value = Diff(intA, intB)
|
||||||
|
}
|
||||||
|
|
||||||
|
d = append(d, Entry{name, value})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return d
|
||||||
|
}
|
Reference in New Issue
Block a user