From 0a939cc19d433aa72a7de310a6917c8ef3646307 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Thu, 26 Dec 2013 13:35:23 -0800 Subject: [PATCH] allow more flexibility in specifying options Options can be specified in any order (size no longer needs to be listed first), and may be repeated. Duplicated options overwrite previous values. Technically, non-size options could already be repeated... now size can as well. There's really not much value to this, it's just an side-effect of allowing any order. fixes #5 --- proxy/data.go | 47 ++++++++++++++++++++++++++-------------------- proxy/data_test.go | 20 ++++++++++++++++---- readme.md | 7 ++++--- 3 files changed, 47 insertions(+), 27 deletions(-) diff --git a/proxy/data.go b/proxy/data.go index bf184fd..cbe3d86 100644 --- a/proxy/data.go +++ b/proxy/data.go @@ -61,27 +61,9 @@ func (o Options) String() string { func ParseOptions(str string) *Options { o := new(Options) - var h, w string parts := strings.Split(str, ",") - - // parse size - size := strings.SplitN(parts[0], "x", 2) - w = size[0] - if len(size) > 1 { - h = size[1] - } else { - h = w - } - - if w != "" { - o.Width, _ = strconv.ParseFloat(w, 64) - } - if h != "" { - o.Height, _ = strconv.ParseFloat(h, 64) - } - - for _, part := range parts[1:] { + for _, part := range parts { if part == "fit" { o.Fit = true continue @@ -95,10 +77,35 @@ func ParseOptions(str string) *Options { continue } - if len(part) > 2 && strings.HasPrefix(part, "r") { + if len(part) > 2 && part[:1] == "r" { o.Rotate, _ = strconv.Atoi(part[1:]) continue } + + if strings.ContainsRune(part, 'x') { + var h, w string + size := strings.SplitN(part, "x", 2) + w = size[0] + if len(size) > 1 { + h = size[1] + } else { + h = w + } + + if w != "" { + o.Width, _ = strconv.ParseFloat(w, 64) + } + if h != "" { + o.Height, _ = strconv.ParseFloat(h, 64) + } + continue + } + + if size, err := strconv.ParseFloat(part, 64); err == nil { + o.Width = size + o.Height = size + continue + } } return o diff --git a/proxy/data_test.go b/proxy/data_test.go index 8bb69eb..054b147 100644 --- a/proxy/data_test.go +++ b/proxy/data_test.go @@ -46,6 +46,7 @@ func TestParseOptions(t *testing.T) { {"", emptyOptions}, {"x", emptyOptions}, {"0", emptyOptions}, + {",,,,", emptyOptions}, // size variations {"1x", &Options{Width: 1}}, @@ -54,12 +55,23 @@ func TestParseOptions(t *testing.T) { {"0.1x0.2", &Options{Width: 0.1, Height: 0.2}}, // additional flags - {",fit", &Options{Fit: true}}, - {",r90", &Options{Rotate: 90}}, - {",fv", &Options{FlipVertical: true}}, - {",fh", &Options{FlipHorizontal: true}}, + {"fit", &Options{Fit: true}}, + {"r90", &Options{Rotate: 90}}, + {"fv", &Options{FlipVertical: true}}, + {"fh", &Options{FlipHorizontal: true}}, + + // duplicate flags (last one wins) + {"1x2,3x4", &Options{Width: 3, Height: 4}}, + {"1x2,3", &Options{Width: 3, Height: 3}}, + {"1x2,0x3", &Options{Width: 0, Height: 3}}, + {"1x,x2", &Options{Width: 1, Height: 2}}, + {"r90,r270", &Options{Rotate: 270}}, + + // mix of valid and invalid flags + {"FOO,1,BAR,r90,BAZ", &Options{Width: 1, Height: 1, Rotate: 90}}, {"1x2,fit,r90,fv,fh", &Options{1, 2, true, 90, true, true}}, + {"r90,fh,1x2,fv,fit", &Options{1, 2, true, 90, true, true}}, } for i, tt := range tests { diff --git a/readme.md b/readme.md index 056e228..8171359 100644 --- a/readme.md +++ b/readme.md @@ -24,9 +24,10 @@ imageproxy URLs are of the form `http://localhost/{options}/{remote_url}`. ### Options ### -Options are specified as a comma delimited list of parameters, the first of -which always specifies image size. The format is a superset of [resize.ly's -options](https://resize.ly/#demo). +Options are specified as a comma delimited list of parameters, which can be +supplied in any order. Duplicate parameters overwrite previous values. + +The format is a superset of [resize.ly's options](https://resize.ly/#demo). #### Size ####