scale_down 0.7.3 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -9,12 +9,14 @@ ScaleDown
9
9
  So you want to scale an image?
10
10
  ------------------------------
11
11
 
12
- You have an image on `example.com`. It has a public path of `/images/john/picture.png`.
13
- You want it scaled to fit in a 400x400 pixel box. ScaleDown is running on the subdomain `images`.
12
+ You have an image on `example.com`. It has a public path of
13
+ `/images/john/picture.png`. You want it scaled to fit in a 400x400 pixel box.
14
+ ScaleDown is running on the subdomain `images`.
14
15
 
15
16
  http://server/images/john/scaled/400x400/picture.png?HMAC_SIGNATURE
16
17
 
17
- The scaled file is saved in a public path identical to the request. It will be statically served on the next request.
18
+ The scaled file is saved in a public path identical to the request. It will be
19
+ statically served on the next request.
18
20
 
19
21
  Geometry, Labels and Cropping
20
22
  ==============================
@@ -52,10 +54,11 @@ A geometry defines a box the image must fit within: `WIDTHxHEIGHT`.
52
54
  ```sh
53
55
  # scale to a 300 pixel width box by 900 pixel high box
54
56
  http://server/images/john/scaled/300x900/picture.png?HMAC_SIGNATURE
55
- ^^^^^^^
57
+ ^^^^^^^
56
58
  ```
57
59
 
58
- Either, but not both, dimensions may use the keyword `auto`. This will scale the image to fit the defined dimension.
60
+ Either, but not both, dimensions may use the keyword `auto`. This will scale
61
+ the image to fit the defined dimension.
59
62
 
60
63
  ```sh
61
64
  # scale to a 500 pixel wide box, of any height
@@ -68,7 +71,9 @@ When using a geometry an HMAC is required (see below).
68
71
  Crop
69
72
  ----
70
73
 
71
- To crop an image include the `-crop` option. The image will be scaled and cropped to fit the geometry. This is a simple crop positioned on the center and top of the image.
74
+ To crop an image include the `-crop` option. The image will be scaled and
75
+ cropped to fit the geometry. This is a simple crop positioned on the center and
76
+ top of the image.
72
77
 
73
78
  Both geometry and labels accept the `-crop` option.
74
79
 
@@ -79,7 +84,9 @@ http://server/images/john/scaled/100x100-crop/picture.png
79
84
 
80
85
  Info
81
86
  ----
82
- There is a very simple `/info` function for getting image dimensions. It just returns a string with the WIDTHxHEIGHT of the original image.
87
+ There is a simple `/info` function for getting image dimensions. It just
88
+ returns a json response the width, height and additional details of the
89
+ original file.
83
90
 
84
91
  http://server/images/logo.png/info
85
92
 
@@ -183,7 +190,8 @@ Dependencies
183
190
  * RMagick
184
191
  * Ruby-HMAC
185
192
 
186
- RMagick can be a bit tricky to install, these links http://www.google.com/search?q=install+rmagick might help.
193
+ RMagick can be a bit tricky to install, these links
194
+ http://www.google.com/search?q=install+rmagick might help.
187
195
 
188
196
  LICENSE
189
197
  =======
@@ -192,8 +200,20 @@ LICENSE
192
200
 
193
201
  Copyright © 2011 John Weir & Fame Driver LLC
194
202
 
195
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
196
-
197
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
198
-
199
- THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
203
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
204
+ this software and associated documentation files (the ‘Software’), to deal in
205
+ the Software without restriction, including without limitation the rights to
206
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
207
+ of the Software, and to permit persons to whom the Software is furnished to do
208
+ so, subject to the following conditions:
209
+
210
+ The above copyright notice and this permission notice shall be included in all
211
+ copies or substantial portions of the Software.
212
+
213
+ THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
214
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
215
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
216
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
217
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
218
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
219
+ SOFTWARE.
@@ -13,6 +13,7 @@ module ScaleDown
13
13
  require 'scale_down/controller'
14
14
  require 'scale_down/dispatcher'
15
15
  require 'scale_down/image'
16
+ require 'scale_down/info'
16
17
 
17
18
  class InvalidGeometry < Exception; end
18
19
  class FileSizeTooLarge < Exception; end
@@ -13,9 +13,9 @@ class ScaleDown::Controller < Sinatra::Application
13
13
  end
14
14
 
15
15
  get '/*/info' do
16
- info = ScaleDown::Dispatcher.info(params[:splat].join("/"))
17
- if info
18
- [200, info]
16
+ info = ScaleDown::Info.new(params[:splat].join("/"))
17
+ if ! info.missing?
18
+ [200, info.to_json]
19
19
  else
20
20
  [404, "Image not found"]
21
21
  end
@@ -19,17 +19,6 @@ class ScaleDown::Dispatcher
19
19
  [dispatcher.redirect_path, dispatcher.redirect_code]
20
20
  end
21
21
 
22
- # TODO return a JSON response with a full set of image details
23
- def info(relative_path)
24
- path = [ScaleDown.public_folder, relative_path].join("/")
25
- if File.exists?(path)
26
- GC.start
27
- image = Magick::Image.read(path).first
28
- [image.columns, image.rows].join('x')
29
- else
30
- nil
31
- end
32
- end
33
22
  end
34
23
 
35
24
  def initialize(params)
@@ -0,0 +1,33 @@
1
+ require 'json'
2
+
3
+ # Returns a json object with the height, width attributes
4
+ class ScaleDown::Info
5
+
6
+ def initialize(relative_path)
7
+ path = [ScaleDown.public_folder, relative_path].join("/")
8
+ if File.exists?(path)
9
+ GC.start
10
+ @image_list = Magick::Image.read(path)
11
+ @image = @image_list.first
12
+ else
13
+ @missing = true
14
+ end
15
+ end
16
+
17
+ def missing?
18
+ @missing == true
19
+ end
20
+
21
+ def hash
22
+ {
23
+ height: @image.rows,
24
+ width: @image.columns,
25
+ # is this an animated GIF or other file
26
+ animated: @image_list.size > 1
27
+ }
28
+ end
29
+
30
+ def to_json
31
+ JSON hash
32
+ end
33
+ end
@@ -1,3 +1,3 @@
1
1
  module ScaleDown
2
- VERSION = "0.7.3"
2
+ VERSION = "0.8.1"
3
3
  end
@@ -17,6 +17,7 @@ Gem::Specification.new do |s|
17
17
  s.add_dependency "rmagick", ">= 2.1"
18
18
  s.add_dependency "sinatra", ">= 1.0"
19
19
  s.add_dependency "ruby-hmac", ">= 0.4.0"
20
+ s.add_dependency "json", "~> 1.7.7"
20
21
 
21
22
  s.add_development_dependency "contest", ">= 0.1.2"
22
23
  s.add_development_dependency "rake", ">= 0.9.2.2"
Binary file
@@ -52,20 +52,20 @@ class ScaleDown::Controller::Test < Test::Unit::TestCase
52
52
  context "get dimensions" do
53
53
  context "for image which exists" do
54
54
  setup do
55
- ScaleDown::Dispatcher.expects(:info).with("image/path/image.jpg").returns "400x300"
55
+ ScaleDown::Info.expects(:new).with("image/path/image.jpg").returns mock(missing?: false, to_json: 'json_blob')
56
56
  end
57
57
 
58
58
  should "return the width and height as json" do
59
59
  get "/image/path/image.jpg/info"
60
60
 
61
61
  assert_equal 200, last_response.status
62
- assert_equal "400x300", last_response.body
62
+ assert_equal "json_blob", last_response.body
63
63
  end
64
64
  end
65
65
 
66
66
  context "for a non-existant image" do
67
67
  setup do
68
- ScaleDown::Dispatcher.expects(:info).with("image/path/image.jpg").returns nil
68
+ ScaleDown::Info.expects(:new).with("image/path/image.jpg").returns mock(missing?: true)
69
69
  end
70
70
 
71
71
  should "respond with a 404" do
@@ -167,19 +167,4 @@ class ScaleDown::Dispatcher::Test < Test::Unit::TestCase
167
167
  end
168
168
  end
169
169
  end
170
-
171
- context "#info" do
172
- setup do
173
- ScaleDown.public_folder = File.join(File.expand_path(File.dirname(__FILE__)), "..")
174
- end
175
-
176
- should "return the width x height for an image" do
177
- assert_equal "200x400", ScaleDown::Dispatcher.info("files/graphic.png")
178
- end
179
-
180
- should "return nil for a non-existant image" do
181
- assert_equal nil, ScaleDown::Dispatcher.info("files/notthere.jpg")
182
- end
183
- end
184
-
185
170
  end
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.dirname(__FILE__))+'/../test_helper'
2
+
3
+ class ScaleDown::Info::Test < Test::Unit::TestCase
4
+ context "#new" do
5
+ setup do
6
+ ScaleDown.public_folder = File.join(File.expand_path(File.dirname(__FILE__)), "..")
7
+ end
8
+
9
+ should "be missing? a non-existant image" do
10
+ assert ScaleDown::Info.new("files/notthere.jpg").missing?
11
+ end
12
+
13
+ should "generate json" do
14
+ info = ScaleDown::Info.new("files/graphic.png")
15
+ assert info.to_json
16
+ end
17
+ end
18
+
19
+ context "properties" do
20
+ should "have dimentions" do
21
+ info = ScaleDown::Info.new("files/graphic.png")
22
+ assert_equal 200, info.hash[:width]
23
+ assert_equal 400, info.hash[:height]
24
+ end
25
+
26
+ should "set the animation flag for animated gifs" do
27
+ info = ScaleDown::Info.new("files/graphic.png")
28
+ assert_equal false, info.hash[:animated]
29
+
30
+ info = ScaleDown::Info.new("files/animated.gif")
31
+ assert_equal true, info.hash[:animated]
32
+ end
33
+ end
34
+ end
@@ -55,27 +55,28 @@ class ScaleDown::Test < Test::Unit::TestCase
55
55
  FileUtils.rm_r("/tmp/scale_down")
56
56
  end
57
57
 
58
- context "homepage" do
59
- should "show the version" do
60
- get "/"
61
- assert_match ScaleDown::VERSION, last_response.body
62
- end
58
+ should "show the version on the homepage" do
59
+ get "/"
60
+ assert_match ScaleDown::VERSION, last_response.body
61
+ end
63
62
 
64
- should "show the labels" do
65
- ScaleDown.labels = {
66
- :medium => "100x100"
67
- }
63
+ should "show the labels on the homepage" do
64
+ ScaleDown.labels = {
65
+ :medium => "100x100"
66
+ }
68
67
 
69
- get "/"
70
- assert_match "medium", last_response.body
71
- assert_match "100x100", last_response.body
72
- end
68
+ get "/"
69
+ assert_match "medium", last_response.body
70
+ assert_match "100x100", last_response.body
73
71
  end
74
72
 
75
73
  should "get image info" do
76
74
  copy 'cmyk.tif', 'long-name.tiff', 1
77
75
  get "/test_images/example_1/#{CGI.escape 'long-name.tiff'}/info"
78
- assert_equal "300x500", last_response.body
76
+
77
+ result = JSON(last_response.body)
78
+ assert_equal 300, result["width"]
79
+ assert_equal 500, result["height"]
79
80
  end
80
81
 
81
82
  should "get an image with a geometry and scale it" do
metadata CHANGED
@@ -1,144 +1,111 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: scale_down
3
- version: !ruby/object:Gem::Version
4
- hash: 5
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 7
9
- - 3
10
- version: 0.7.3
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.8.1
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - John Weir
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2012-04-05 00:00:00 -04:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2013-04-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: rmagick
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &2164651320 !ruby/object:Gem::Requirement
25
17
  none: false
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 1
30
- segments:
31
- - 2
32
- - 1
33
- version: "2.1"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '2.1'
34
22
  type: :runtime
35
- version_requirements: *id001
36
- - !ruby/object:Gem::Dependency
37
- name: sinatra
38
23
  prerelease: false
39
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *2164651320
25
+ - !ruby/object:Gem::Dependency
26
+ name: sinatra
27
+ requirement: &2164650760 !ruby/object:Gem::Requirement
40
28
  none: false
41
- requirements:
42
- - - ">="
43
- - !ruby/object:Gem::Version
44
- hash: 15
45
- segments:
46
- - 1
47
- - 0
48
- version: "1.0"
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '1.0'
49
33
  type: :runtime
50
- version_requirements: *id002
51
- - !ruby/object:Gem::Dependency
52
- name: ruby-hmac
53
34
  prerelease: false
54
- requirement: &id003 !ruby/object:Gem::Requirement
35
+ version_requirements: *2164650760
36
+ - !ruby/object:Gem::Dependency
37
+ name: ruby-hmac
38
+ requirement: &2164650300 !ruby/object:Gem::Requirement
55
39
  none: false
56
- requirements:
57
- - - ">="
58
- - !ruby/object:Gem::Version
59
- hash: 15
60
- segments:
61
- - 0
62
- - 4
63
- - 0
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
64
43
  version: 0.4.0
65
44
  type: :runtime
66
- version_requirements: *id003
67
- - !ruby/object:Gem::Dependency
68
- name: contest
69
45
  prerelease: false
70
- requirement: &id004 !ruby/object:Gem::Requirement
46
+ version_requirements: *2164650300
47
+ - !ruby/object:Gem::Dependency
48
+ name: json
49
+ requirement: &2164649840 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.7.7
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *2164649840
58
+ - !ruby/object:Gem::Dependency
59
+ name: contest
60
+ requirement: &2164649380 !ruby/object:Gem::Requirement
71
61
  none: false
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- hash: 31
76
- segments:
77
- - 0
78
- - 1
79
- - 2
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
80
65
  version: 0.1.2
81
66
  type: :development
82
- version_requirements: *id004
83
- - !ruby/object:Gem::Dependency
84
- name: rake
85
67
  prerelease: false
86
- requirement: &id005 !ruby/object:Gem::Requirement
68
+ version_requirements: *2164649380
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: &2164648860 !ruby/object:Gem::Requirement
87
72
  none: false
88
- requirements:
89
- - - ">="
90
- - !ruby/object:Gem::Version
91
- hash: 11
92
- segments:
93
- - 0
94
- - 9
95
- - 2
96
- - 2
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
97
76
  version: 0.9.2.2
98
77
  type: :development
99
- version_requirements: *id005
100
- - !ruby/object:Gem::Dependency
101
- name: mocha
102
78
  prerelease: false
103
- requirement: &id006 !ruby/object:Gem::Requirement
79
+ version_requirements: *2164648860
80
+ - !ruby/object:Gem::Dependency
81
+ name: mocha
82
+ requirement: &2164648320 !ruby/object:Gem::Requirement
104
83
  none: false
105
- requirements:
106
- - - "="
107
- - !ruby/object:Gem::Version
108
- hash: 43
109
- segments:
110
- - 0
111
- - 9
112
- - 8
84
+ requirements:
85
+ - - =
86
+ - !ruby/object:Gem::Version
113
87
  version: 0.9.8
114
88
  type: :development
115
- version_requirements: *id006
116
- - !ruby/object:Gem::Dependency
117
- name: rack-test
118
89
  prerelease: false
119
- requirement: &id007 !ruby/object:Gem::Requirement
90
+ version_requirements: *2164648320
91
+ - !ruby/object:Gem::Dependency
92
+ name: rack-test
93
+ requirement: &2164647820 !ruby/object:Gem::Requirement
120
94
  none: false
121
- requirements:
122
- - - "="
123
- - !ruby/object:Gem::Version
124
- hash: 7
125
- segments:
126
- - 0
127
- - 5
128
- - 6
95
+ requirements:
96
+ - - =
97
+ - !ruby/object:Gem::Version
129
98
  version: 0.5.6
130
99
  type: :development
131
- version_requirements: *id007
132
- description: ""
133
- email:
100
+ prerelease: false
101
+ version_requirements: *2164647820
102
+ description: ''
103
+ email:
134
104
  - john@famedriver.com
135
105
  executables: []
136
-
137
106
  extensions: []
138
-
139
107
  extra_rdoc_files: []
140
-
141
- files:
108
+ files:
142
109
  - .gitignore
143
110
  - .travis.yml
144
111
  - CHANGES
@@ -152,9 +119,11 @@ files:
152
119
  - lib/scale_down/controller.rb
153
120
  - lib/scale_down/dispatcher.rb
154
121
  - lib/scale_down/image.rb
122
+ - lib/scale_down/info.rb
155
123
  - lib/scale_down/version.rb
156
124
  - lib/templates/index.erb
157
125
  - scale_down.gemspec
126
+ - test/files/animated.gif
158
127
  - test/files/cmyk.tif
159
128
  - test/files/cmyk_gray.jpg
160
129
  - test/files/graphic.png
@@ -165,44 +134,36 @@ files:
165
134
  - test/scale_down/controller_test.rb
166
135
  - test/scale_down/dispatcher_test.rb
167
136
  - test/scale_down/image_test.rb
137
+ - test/scale_down/info_test.rb
168
138
  - test/scale_down_test.rb
169
139
  - test/scaled_image_tag_test.rb
170
140
  - test/test_helper.rb
171
- has_rdoc: true
172
141
  homepage: http://github.com/jweir/ScaleDown
173
142
  licenses: []
174
-
175
143
  post_install_message:
176
144
  rdoc_options: []
177
-
178
- require_paths:
145
+ require_paths:
179
146
  - lib
180
- required_ruby_version: !ruby/object:Gem::Requirement
147
+ required_ruby_version: !ruby/object:Gem::Requirement
181
148
  none: false
182
- requirements:
183
- - - ">="
184
- - !ruby/object:Gem::Version
185
- hash: 3
186
- segments:
187
- - 0
188
- version: "0"
189
- required_rubygems_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ! '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ required_rubygems_version: !ruby/object:Gem::Requirement
190
154
  none: false
191
- requirements:
192
- - - ">="
193
- - !ruby/object:Gem::Version
194
- hash: 3
195
- segments:
196
- - 0
197
- version: "0"
155
+ requirements:
156
+ - - ! '>='
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
198
159
  requirements: []
199
-
200
160
  rubyforge_project: scale_down
201
- rubygems_version: 1.3.7
161
+ rubygems_version: 1.8.15
202
162
  signing_key:
203
163
  specification_version: 3
204
164
  summary: A Sinatra based server for quickly scaling and serving images. Nothing more.
205
- test_files:
165
+ test_files:
166
+ - test/files/animated.gif
206
167
  - test/files/cmyk.tif
207
168
  - test/files/cmyk_gray.jpg
208
169
  - test/files/graphic.png
@@ -213,6 +174,7 @@ test_files:
213
174
  - test/scale_down/controller_test.rb
214
175
  - test/scale_down/dispatcher_test.rb
215
176
  - test/scale_down/image_test.rb
177
+ - test/scale_down/info_test.rb
216
178
  - test/scale_down_test.rb
217
179
  - test/scaled_image_tag_test.rb
218
180
  - test/test_helper.rb