scale_down 0.2.9 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.bundle/config +1 -2
- data/Gemfile +4 -0
- data/Gemfile.lock +10 -3
- data/README.rdoc +55 -42
- data/lib/scale_down/controller.rb +10 -5
- data/lib/scale_down/dispatcher.rb +6 -5
- data/lib/scale_down/image.rb +1 -1
- data/lib/scale_down/version.rb +1 -1
- data/lib/scale_down.rb +1 -1
- data/test/scale_down/controller_test.rb +6 -7
- data/test/scale_down/dispatcher_test.rb +11 -11
- data/test/scale_down/image_test.rb +18 -18
- data/test/scale_down_test.rb +7 -7
- data/test/scaled_image_tag_test.rb +7 -7
- data/test/test_helper.rb +1 -2
- metadata +3 -5
data/.bundle/config
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
---
|
2
|
-
BUNDLE_DISABLE_SHARED_GEMS: "1"
|
1
|
+
--- {}
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
scale_down (0.2.
|
4
|
+
scale_down (0.2.9)
|
5
5
|
rmagick (>= 2.1)
|
6
6
|
ruby-hmac (>= 0.4.0)
|
7
7
|
sinatra (>= 1.0)
|
@@ -10,6 +10,8 @@ GEM
|
|
10
10
|
remote: http://rubygems.org/
|
11
11
|
specs:
|
12
12
|
contest (0.1.3)
|
13
|
+
daemons (1.1.4)
|
14
|
+
eventmachine (0.12.10)
|
13
15
|
mocha (0.9.8)
|
14
16
|
rake
|
15
17
|
rack (1.2.2)
|
@@ -18,10 +20,14 @@ GEM
|
|
18
20
|
rake (0.8.7)
|
19
21
|
rmagick (2.13.1)
|
20
22
|
ruby-hmac (0.4.0)
|
21
|
-
sinatra (1.2.
|
23
|
+
sinatra (1.2.7)
|
22
24
|
rack (~> 1.1)
|
23
25
|
tilt (>= 1.2.2, < 2.0)
|
24
|
-
|
26
|
+
thin (1.3.1)
|
27
|
+
daemons (>= 1.0.9)
|
28
|
+
eventmachine (>= 0.12.6)
|
29
|
+
rack (>= 1.0.0)
|
30
|
+
tilt (1.3.3)
|
25
31
|
|
26
32
|
PLATFORMS
|
27
33
|
ruby
|
@@ -31,3 +37,4 @@ DEPENDENCIES
|
|
31
37
|
mocha (= 0.9.8)
|
32
38
|
rack-test (= 0.5.6)
|
33
39
|
scale_down!
|
40
|
+
thin
|
data/README.rdoc
CHANGED
@@ -1,52 +1,89 @@
|
|
1
1
|
= ScaleDown
|
2
2
|
|
3
|
-
|
3
|
+
An on demand image scaling server.
|
4
4
|
|
5
5
|
Images are scaled based upon their URL. An HMAC signature is used to prevent unauthorized scaling of images.
|
6
6
|
|
7
7
|
Supports cropping images and converts CMYK to RGB.
|
8
8
|
|
9
|
-
The URL schema
|
9
|
+
== The URL schema
|
10
10
|
|
11
|
-
|
11
|
+
Your file on `example.com` has a public path of `/images/john/picture.png`. You want it scaled to fit in a 400x400 pixel box. *ScaleDown* is running on the subdomain `images`.
|
12
12
|
|
13
|
-
|
13
|
+
The URL to your image would be:
|
14
14
|
|
15
|
-
|
15
|
+
http://images.example.com/images/john/scaled/400x400/picture.png?HMAC_SIGNATURE
|
16
|
+
|
17
|
+
The scaled file will be saved in a public path identical to the request. So once an image is scaled your webserver, Apache, Nginx, etc, can statically server the file.
|
18
|
+
|
19
|
+
The schema is
|
20
|
+
|
21
|
+
http://:host/:path_to_file/scaled/:geometry/:filename?:hmac_signature
|
22
|
+
|
23
|
+
:host is the address running ScaleDown
|
16
24
|
|
17
25
|
:path_to_file is the public path of the original file
|
18
26
|
|
27
|
+
`scaled` keyword
|
28
|
+
|
29
|
+
:geometry is width x height and an optional `-crop`
|
30
|
+
|
19
31
|
:filename is the name of the image to scale
|
20
32
|
|
21
33
|
:hmac_signature a security measure to validate the request
|
22
34
|
|
23
|
-
|
35
|
+
== Geometry & Cropping
|
24
36
|
|
25
|
-
|
37
|
+
To crop an image include the `-crop` option. The image will be scaled and cropped to fit the geometry.
|
26
38
|
|
27
|
-
|
39
|
+
http://images.example.com/images/scaled/400x300-crop/logo.png?A3SDACEDF
|
28
40
|
|
29
|
-
|
41
|
+
Using `auto` as a dimension will fit the image to other dimension.
|
30
42
|
|
31
|
-
|
43
|
+
For example, to ensure an image is 300 pixels wide set the height to auto
|
32
44
|
|
33
|
-
http://images.example.com/
|
45
|
+
http://images.example.com/images/scaled/300xauto/logo.png/?A3SDACEDF
|
34
46
|
|
35
|
-
|
47
|
+
There is a very simple `/info` function for getting image dimensions. It just returns a string with the WIDTHxHEIGHT.
|
36
48
|
|
37
|
-
|
49
|
+
http://images.example.com/images/logo.png/info
|
50
|
+
|
51
|
+
== HMAC
|
52
|
+
|
53
|
+
You don't want someone taking down your server with malicious URLs, so an HMAC signature is used. This ensures that your URL was generated by a trusted source.
|
54
|
+
|
55
|
+
HMAC requires a shared key between the application generating the URL and the ScaleDown server.
|
38
56
|
|
39
|
-
|
57
|
+
=== Sample Ruby URL Generator
|
40
58
|
|
41
|
-
|
59
|
+
require 'ruby-hmac'
|
42
60
|
|
43
|
-
|
61
|
+
def signed_image_url(absolute_path, filename, geometry)
|
62
|
+
shared_secret = "secret"
|
63
|
+
hmac = HMAC::SHA1.new(shared_secret).update([absolute_path, 'scaled', geometry, filename].join("/")).to_s[0...8]
|
64
|
+
"http://images.example.com#{[absolute_path, 'scaled', geometry, CGI.escape(filename)].join("/")}?#{hmac}"
|
65
|
+
end
|
66
|
+
|
67
|
+
=== Sample Node.js URL Generator
|
68
|
+
|
69
|
+
// Uses the Node.js crypot library
|
70
|
+
var crypto = require('crypto')
|
71
|
+
|
72
|
+
function hmac(string){
|
73
|
+
var shared_secret = "secret"
|
74
|
+
return crypto.createHmac('sha1',shared_secret).update(string).digest('hex').substr(0,8)
|
75
|
+
}
|
76
|
+
|
77
|
+
function signed_image_url(absolute_path, filename, geometry){
|
78
|
+
signature = hmac( [ absolute_path, '/scaled', "/" + geometry, "/", filename].join("") )
|
79
|
+
return [global.$FD.assetHost, absolute_path, '/scaled', "/", geometry, "/",escape(filename)].join("") + "?"+ signature
|
80
|
+
}
|
44
81
|
|
45
82
|
== Installation and Configuration
|
46
83
|
|
47
84
|
gem install scale_down
|
48
85
|
|
49
|
-
Create a
|
86
|
+
Create a Rackup file (config.ru). See https://github.com/jweir/ScaleDown/tree/master/config_sample.ru more options
|
50
87
|
|
51
88
|
require 'rubygems'
|
52
89
|
require 'scale_down'
|
@@ -61,36 +98,12 @@ Create a rackup file (config.ru). See http://rubydoc.info/gems/scale_down/0.2.1/
|
|
61
98
|
|
62
99
|
run ScaleDown::Controller
|
63
100
|
|
64
|
-
Configure Nginx, Apache, etc to run the server.
|
65
|
-
|
66
|
-
=== Generating the URL
|
67
|
-
|
68
|
-
Your application will need to generate the image's URL and HMAC signature.
|
69
|
-
|
70
|
-
# Example ruby function to generate signed URL
|
71
|
-
require 'HMAC::SHA1'
|
72
|
-
require 'cgi'
|
73
|
-
|
74
|
-
# ie signed_image_url('images', 'picture.png', '400x300-cropped')
|
75
|
-
def signed_image_url(path, filename, geometry)
|
76
|
-
hmac = HMAC::SHA1.new("secret").update("/#{geometry}/#{path}/#{filename}").to_s[0..8]
|
77
|
-
"http://images.myserver.com/#{geometry}/#{path}/#{CGI.escape(filename)}?#{hmac}"
|
78
|
-
end
|
79
|
-
|
80
|
-
Of course this could be done in PHP, Node, Python, or other languages.
|
101
|
+
Configure Nginx, Apache, etc to run the server.
|
81
102
|
|
82
103
|
== Known Issues
|
83
104
|
|
84
105
|
Pluses in filenames will not route properly. Filenames need to have these removed or replaced.
|
85
106
|
|
86
|
-
== TODO
|
87
|
-
|
88
|
-
Custom Read/Write methods to allow for more than just local storage.
|
89
|
-
|
90
|
-
Examples using Node.js
|
91
|
-
|
92
|
-
There is an issue on some systems with pluses in filenames.
|
93
|
-
|
94
107
|
== Dependencies
|
95
108
|
|
96
109
|
* Sinatra
|
@@ -17,25 +17,30 @@ class ScaleDown::Controller < Sinatra::Application
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
# get '/*/:filename
|
20
|
+
# get '/*/:geometry/:filename?:hmac'
|
21
21
|
# is what I want, but this fails when the URL includes things like %23 (an encoded hash tag)
|
22
22
|
get '/*' do
|
23
23
|
parts = params[:splat].join("/").split("/")
|
24
24
|
|
25
25
|
params = {
|
26
26
|
:hmac => request.env["QUERY_STRING"],
|
27
|
-
:geometry => parts.shift,
|
28
27
|
:filename => parts.pop,
|
28
|
+
:geometry => parts.pop,
|
29
29
|
:splat => parts
|
30
30
|
}
|
31
31
|
|
32
32
|
path, status = dispatch(params)
|
33
33
|
|
34
34
|
ScaleDown.logger.info "Controller#get #{path} #{status}"
|
35
|
-
|
36
|
-
|
35
|
+
case status
|
36
|
+
when 302 then
|
37
|
+
# File is found or scaled, use Sinatra's built in send file method
|
38
|
+
static!
|
39
|
+
when 403 then
|
40
|
+
[status, "Error: the the HMAC is invalid for this request"]
|
41
|
+
when 404 then
|
42
|
+
[status, "Error: the orignal image could not be found"]
|
37
43
|
else
|
38
|
-
# TODO error messages which explain what went wrong
|
39
44
|
[status, "Error: this image could not be processed"]
|
40
45
|
end
|
41
46
|
end
|
@@ -10,12 +10,12 @@ class ScaleDown::Dispatcher
|
|
10
10
|
ScaleDown.logger.info "Dipatcher#process #{dispatcher.root_path}"
|
11
11
|
|
12
12
|
return ["Missing file", 404] unless dispatcher.root_file_exists?
|
13
|
-
return [dispatcher.redirect_path,
|
13
|
+
return [dispatcher.redirect_path, 302] if dispatcher.scaled_file_exists?
|
14
14
|
|
15
15
|
return ["Invalid HMAC signature", 403] unless dispatcher.valid_hmac?
|
16
16
|
return ["File failed to scale. The file may be corrupt.", 500] unless dispatcher.scale
|
17
17
|
|
18
|
-
[dispatcher.redirect_path,
|
18
|
+
[dispatcher.redirect_path, 302]
|
19
19
|
end
|
20
20
|
|
21
21
|
# TODO return a JSON response with a full set of image details
|
@@ -55,7 +55,7 @@ class ScaleDown::Dispatcher
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def redirect_path
|
58
|
-
["/"+@params[:path],
|
58
|
+
["/"+@params[:path], @params[:geometry], scaled_filename].join("/")
|
59
59
|
end
|
60
60
|
|
61
61
|
def root_file_exists?
|
@@ -67,7 +67,8 @@ class ScaleDown::Dispatcher
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def root_path
|
70
|
-
|
70
|
+
root = @params[:path].gsub(/\/scaled$/,"")
|
71
|
+
File.join(ScaleDown.public_path, root, @params[:filename])
|
71
72
|
end
|
72
73
|
|
73
74
|
def scaled_file_path
|
@@ -75,7 +76,7 @@ class ScaleDown::Dispatcher
|
|
75
76
|
end
|
76
77
|
|
77
78
|
def scaled_filename
|
78
|
-
"#{filename}
|
79
|
+
"#{filename}.#{scaled_extension}"
|
79
80
|
end
|
80
81
|
|
81
82
|
def filename
|
data/lib/scale_down/image.rb
CHANGED
data/lib/scale_down/version.rb
CHANGED
data/lib/scale_down.rb
CHANGED
@@ -10,23 +10,22 @@ class ScaleDown::Controller::Test < Test::Unit::TestCase
|
|
10
10
|
context "parsing a request" do
|
11
11
|
should "have an image path" do
|
12
12
|
ScaleDown::Dispatcher.expects(:process).with(
|
13
|
-
:path => "user/path",
|
13
|
+
:path => "user/path/scaled",
|
14
14
|
:filename => "filename.png",
|
15
15
|
:geometry => "400x300-crop-grayscale",
|
16
16
|
:hmac => "HMAC").
|
17
17
|
returns ["path","status"]
|
18
18
|
|
19
|
-
get '/400x300-crop-grayscale/
|
19
|
+
get '/user/path/scaled/400x300-crop-grayscale/filename.png?HMAC'
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
context "a valid request" do
|
24
24
|
should "redirect to the image path" do
|
25
|
-
ScaleDown::Dispatcher.expects(:process).returns ["/image-path",
|
26
|
-
get "/geo/
|
25
|
+
ScaleDown::Dispatcher.expects(:process).returns ["/image-path", 302]
|
26
|
+
get "/path/geo/filename?hmac"
|
27
27
|
|
28
|
-
assert_equal
|
29
|
-
assert_equal "http://example.org/image-path", last_response["Location"]
|
28
|
+
assert_equal 200, last_response.status
|
30
29
|
end
|
31
30
|
end
|
32
31
|
|
@@ -35,7 +34,7 @@ class ScaleDown::Controller::Test < Test::Unit::TestCase
|
|
35
34
|
should "respond with a 403 and error message" do
|
36
35
|
ScaleDown::Dispatcher.expects(:process).returns ["Error description", 403]
|
37
36
|
|
38
|
-
get "/geo/
|
37
|
+
get "/path/geo/filename?hmac"
|
39
38
|
|
40
39
|
assert_equal 403, last_response.status
|
41
40
|
assert_match "Error", last_response.body
|
@@ -9,10 +9,10 @@ class ScaleDown::Dispatcher::Test < Test::Unit::TestCase
|
|
9
9
|
ScaleDown.hmac_length = 8
|
10
10
|
ScaleDown.public_path = "/tmp"
|
11
11
|
|
12
|
-
hmac = HMAC::SHA1.new("secret").update("file/path/filename.png
|
12
|
+
hmac = HMAC::SHA1.new("secret").update("file/path/400x300-crop/filename.png").to_s
|
13
13
|
|
14
14
|
@params = {
|
15
|
-
:path => "file/path",
|
15
|
+
:path => "file/path/scaled",
|
16
16
|
:filename => "filename.png",
|
17
17
|
:geometry => "400x300-crop",
|
18
18
|
:hmac => hmac[0...8]
|
@@ -34,8 +34,8 @@ class ScaleDown::Dispatcher::Test < Test::Unit::TestCase
|
|
34
34
|
assert @dispatcher.root_file_exists?
|
35
35
|
end
|
36
36
|
|
37
|
-
should "
|
38
|
-
File.expects(:exists?).with("/tmp/file/path/scaled/
|
37
|
+
should "determine the scaled image's existance" do
|
38
|
+
File.expects(:exists?).with("/tmp/file/path/scaled/400x300-crop/filename.png").returns true
|
39
39
|
assert @dispatcher.scaled_file_exists?
|
40
40
|
end
|
41
41
|
|
@@ -44,7 +44,7 @@ class ScaleDown::Dispatcher::Test < Test::Unit::TestCase
|
|
44
44
|
end
|
45
45
|
|
46
46
|
should "have a redirect path" do
|
47
|
-
assert_equal "/file/path/scaled/
|
47
|
+
assert_equal "/file/path/scaled/400x300-crop/filename.png", @dispatcher.redirect_path
|
48
48
|
end
|
49
49
|
|
50
50
|
should "process the image" do
|
@@ -74,7 +74,7 @@ class ScaleDown::Dispatcher::Test < Test::Unit::TestCase
|
|
74
74
|
context "for an existing, unscaled image" do
|
75
75
|
setup do
|
76
76
|
File.expects(:exists?).with("/tmp/file/path/filename.png").returns true
|
77
|
-
File.expects(:exists?).with("/tmp/file/path/scaled/
|
77
|
+
File.expects(:exists?).with("/tmp/file/path/scaled/400x300-crop/filename.png").returns false
|
78
78
|
end
|
79
79
|
|
80
80
|
context "with a valid HMAC" do
|
@@ -87,8 +87,8 @@ class ScaleDown::Dispatcher::Test < Test::Unit::TestCase
|
|
87
87
|
ScaleDown::Dispatcher.process(@params)
|
88
88
|
end
|
89
89
|
|
90
|
-
should "return a
|
91
|
-
assert_equal ["/file/path/scaled/
|
90
|
+
should "return a 302 redirect to the processed image's URL" do
|
91
|
+
assert_equal ["/file/path/scaled/400x300-crop/filename.png", 302], ScaleDown::Dispatcher.process(@params)
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
@@ -103,11 +103,11 @@ class ScaleDown::Dispatcher::Test < Test::Unit::TestCase
|
|
103
103
|
context "for an existing, scaled, image" do
|
104
104
|
setup do
|
105
105
|
File.expects(:exists?).with("/tmp/file/path/filename.png").returns true
|
106
|
-
File.expects(:exists?).with("/tmp/file/path/scaled/
|
106
|
+
File.expects(:exists?).with("/tmp/file/path/scaled/400x300-crop/filename.png").returns true
|
107
107
|
end
|
108
108
|
|
109
|
-
should "return a
|
110
|
-
assert_equal ["/file/path/scaled/
|
109
|
+
should "return a 302 redirect to the processed image's URL" do
|
110
|
+
assert_equal ["/file/path/scaled/400x300-crop/filename.png", 302], ScaleDown::Dispatcher.process(@params)
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
@@ -17,16 +17,16 @@ class ScaleDown::Image::Test < Test::Unit::TestCase
|
|
17
17
|
setup do
|
18
18
|
@subject = create \
|
19
19
|
fixture_path("files/graphic.png"),
|
20
|
-
fixture_path("scaled_test/
|
20
|
+
fixture_path("scaled_test/scaled/graphic.png"),
|
21
21
|
{ :width => 100, :height => 180}
|
22
22
|
end
|
23
23
|
|
24
24
|
should "save the file (and generate the path)" do
|
25
|
-
assert File.exists?(fixture_path('scaled_test/
|
25
|
+
assert File.exists?(fixture_path('scaled_test/scaled/graphic.png'))
|
26
26
|
end
|
27
27
|
|
28
28
|
should "scale the image" do
|
29
|
-
image = Magick::Image.read(fixture_path("scaled_test/
|
29
|
+
image = Magick::Image.read(fixture_path("scaled_test/scaled/graphic.png")).first
|
30
30
|
assert_equal 90, image.columns
|
31
31
|
assert_equal 180, image.rows
|
32
32
|
end
|
@@ -46,10 +46,10 @@ class ScaleDown::Image::Test < Test::Unit::TestCase
|
|
46
46
|
should "auto scale any one dimensions" do
|
47
47
|
assert create \
|
48
48
|
fixture_path("files/graphic.png"),
|
49
|
-
fixture_path("scaled_test/
|
49
|
+
fixture_path("scaled_test/scaled/graphic.png"),
|
50
50
|
{ :width => "auto", :height => 150 }
|
51
51
|
|
52
|
-
image = Magick::Image.read(fixture_path("scaled_test/
|
52
|
+
image = Magick::Image.read(fixture_path("scaled_test/scaled/graphic.png")).first
|
53
53
|
assert_equal 150, image.rows
|
54
54
|
assert_equal 75, image.columns
|
55
55
|
end
|
@@ -77,7 +77,7 @@ class ScaleDown::Image::Test < Test::Unit::TestCase
|
|
77
77
|
setup do
|
78
78
|
@subject = create \
|
79
79
|
fixture_path("files/invalid_jpeg.jpg"),
|
80
|
-
fixture_path("scaled_test/
|
80
|
+
fixture_path("scaled_test/scaled/graphic.jpg"),
|
81
81
|
{ :width => 100, :height => 105 }
|
82
82
|
end
|
83
83
|
|
@@ -86,7 +86,7 @@ class ScaleDown::Image::Test < Test::Unit::TestCase
|
|
86
86
|
end
|
87
87
|
|
88
88
|
should "not create a scaled image" do
|
89
|
-
assert !File.exists?(fixture_path("scaled_test/
|
89
|
+
assert !File.exists?(fixture_path("scaled_test/scaled/graphic.jpg"))
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
@@ -99,7 +99,7 @@ class ScaleDown::Image::Test < Test::Unit::TestCase
|
|
99
99
|
assert_raises ScaleDown::FileSizeTooLarge do
|
100
100
|
@subject = create \
|
101
101
|
fixture_path("files/graphic.png"),
|
102
|
-
fixture_path("scaled_test/
|
102
|
+
fixture_path("scaled_test/scaled/graphic.png"),
|
103
103
|
{ :width => 100, :height => 105 }
|
104
104
|
end
|
105
105
|
end
|
@@ -109,12 +109,12 @@ class ScaleDown::Image::Test < Test::Unit::TestCase
|
|
109
109
|
setup do
|
110
110
|
@subject = create \
|
111
111
|
fixture_path("files/graphic.png"),
|
112
|
-
fixture_path("scaled_test/
|
112
|
+
fixture_path("scaled_test/scaled/graphic.png"),
|
113
113
|
{ :width => 25, :height => 25, :crop => true }
|
114
114
|
end
|
115
115
|
|
116
116
|
should "crop the image to the dimensions" do
|
117
|
-
image = Magick::Image.read(fixture_path("scaled_test/
|
117
|
+
image = Magick::Image.read(fixture_path("scaled_test/scaled/graphic.png")).first
|
118
118
|
assert_equal 25, image.columns
|
119
119
|
assert_equal 25, image.rows
|
120
120
|
end
|
@@ -124,12 +124,12 @@ class ScaleDown::Image::Test < Test::Unit::TestCase
|
|
124
124
|
setup do
|
125
125
|
@subject = create \
|
126
126
|
fixture_path("files/orient.jpg"),
|
127
|
-
fixture_path("scaled_test/
|
127
|
+
fixture_path("scaled_test/scaled/graphic.jpg"),
|
128
128
|
{ :width => "auto", :height => 800}
|
129
129
|
end
|
130
130
|
|
131
131
|
should "be automatic" do
|
132
|
-
image = Magick::Image.read(fixture_path("scaled_test/
|
132
|
+
image = Magick::Image.read(fixture_path("scaled_test/scaled/graphic.jpg")).first
|
133
133
|
assert_equal 600, image.columns
|
134
134
|
assert_equal 800, image.rows
|
135
135
|
end
|
@@ -137,10 +137,10 @@ class ScaleDown::Image::Test < Test::Unit::TestCase
|
|
137
137
|
should "ignore files without orientation EXIF" do
|
138
138
|
@subject = create \
|
139
139
|
fixture_path("files/no_orient.tif"),
|
140
|
-
fixture_path("scaled_test/
|
140
|
+
fixture_path("scaled_test/scaled/graphic.jpg"),
|
141
141
|
{ :width => "auto", :height => 424}
|
142
142
|
|
143
|
-
image = Magick::Image.read(fixture_path("scaled_test/
|
143
|
+
image = Magick::Image.read(fixture_path("scaled_test/scaled/graphic.jpg")).first
|
144
144
|
assert_equal 330, image.columns
|
145
145
|
assert_equal 424, image.rows
|
146
146
|
end
|
@@ -150,20 +150,20 @@ class ScaleDown::Image::Test < Test::Unit::TestCase
|
|
150
150
|
should "be converted to RGB" do
|
151
151
|
create \
|
152
152
|
fixture_path("files/cmyk.tif"),
|
153
|
-
fixture_path("scaled_test/
|
153
|
+
fixture_path("scaled_test/scaled/graphic.jpg"),
|
154
154
|
{ :width => "auto", :height => 200}
|
155
155
|
|
156
|
-
image = Magick::Image.read(fixture_path("scaled_test/
|
156
|
+
image = Magick::Image.read(fixture_path("scaled_test/scaled/graphic.jpg")).first
|
157
157
|
assert_equal Magick::RGBColorspace, image.colorspace
|
158
158
|
end
|
159
159
|
|
160
160
|
should "convert JPGs to RGB JPEGS" do
|
161
161
|
create \
|
162
162
|
fixture_path("files/cmyk_gray.jpg"),
|
163
|
-
fixture_path("scaled_test/
|
163
|
+
fixture_path("scaled_test/scaled/graphic_2.jpg"),
|
164
164
|
{ :width => "auto", :height => 200}
|
165
165
|
|
166
|
-
image = Magick::Image.read(fixture_path("scaled_test/
|
166
|
+
image = Magick::Image.read(fixture_path("scaled_test/scaled/graphic_2.jpg")).first
|
167
167
|
assert_equal Magick::RGBColorspace, image.colorspace
|
168
168
|
end
|
169
169
|
end
|
data/test/scale_down_test.rb
CHANGED
@@ -21,7 +21,7 @@ class ScaleDown::Test < Test::Unit::TestCase
|
|
21
21
|
|
22
22
|
context "HMAC" do
|
23
23
|
setup do
|
24
|
-
hmac = HMAC::SHA1.new("secret").update("/400x300-crop/
|
24
|
+
hmac = HMAC::SHA1.new("secret").update("/file/path/400x300-crop/filename.png").to_s
|
25
25
|
|
26
26
|
@params = {
|
27
27
|
:path => "file/path",
|
@@ -59,19 +59,19 @@ class ScaleDown::Test < Test::Unit::TestCase
|
|
59
59
|
end
|
60
60
|
|
61
61
|
should "get an image and scale it" do
|
62
|
-
valid_get '/400x300-cropped/
|
63
|
-
assert_equal
|
64
|
-
|
65
|
-
|
62
|
+
valid_get '/test_images/example_1/scaled/400x300-cropped/graphic.png'
|
63
|
+
assert_equal 200, last_response.status
|
64
|
+
assert File.exists?("/tmp/scale_down/test_images/example_1/scaled/400x300-cropped/graphic.png")
|
65
|
+
assert_match "/test_images/example_1/scaled/400x300-cropped/graphic.png", last_response["Location"]
|
66
66
|
end
|
67
67
|
|
68
68
|
should "get a nonexistant image and return a 404" do
|
69
|
-
valid_get "/
|
69
|
+
valid_get "/test_images/example_none/scaled/400x300/image.jpg"
|
70
70
|
assert_equal 404, last_response.status
|
71
71
|
end
|
72
72
|
|
73
73
|
should "get an invalid image and return a 500" do
|
74
|
-
valid_get '/400x300-cropped/
|
74
|
+
valid_get '/test_images/example_2/scaled/400x300-cropped/invalid_jpeg.jpg'
|
75
75
|
|
76
76
|
assert_equal 500, last_response.status
|
77
77
|
assert !File.exists?("/tmp/scale_down/test_images/example_2/scaled/400x300-cropped/invalid_jpeg.jpg")
|
@@ -4,9 +4,9 @@ require 'cgi'
|
|
4
4
|
|
5
5
|
class ScaleDown::Test < Test::Unit::TestCase
|
6
6
|
|
7
|
-
def signed_image_url(path, filename,
|
8
|
-
hmac = HMAC::SHA1.new("secret").update([path,
|
9
|
-
"http://images.myserver.com#{[path, CGI.escape(filename)
|
7
|
+
def signed_image_url(path, filename, geometry)
|
8
|
+
hmac = HMAC::SHA1.new("secret").update([path, 'scaled', geometry, filename].join("/")).to_s[0...8]
|
9
|
+
"http://images.myserver.com#{[path, 'scaled', geometry, CGI.escape(filename)].join("/")}?#{hmac}"
|
10
10
|
end
|
11
11
|
|
12
12
|
setup do
|
@@ -17,17 +17,17 @@ class ScaleDown::Test < Test::Unit::TestCase
|
|
17
17
|
end
|
18
18
|
|
19
19
|
should "create a URL with the HMAC signature" do
|
20
|
-
hmac = ScaleDown.hmac("/images/
|
20
|
+
hmac = ScaleDown.hmac("/images/scaled/400x300-cropped/graphic.png")
|
21
21
|
assert_equal\
|
22
|
-
"http://images.myserver.com/images/
|
22
|
+
"http://images.myserver.com/images/scaled/400x300-cropped/graphic.png?#{hmac}",
|
23
23
|
signed_image_url("/images","graphic.png","400x300-cropped")
|
24
24
|
end
|
25
25
|
|
26
26
|
should "create a URL when the filename has URI break characters" do
|
27
27
|
filename = "# !%23?.png"
|
28
|
-
hmac = ScaleDown.hmac("/images/#{filename}
|
28
|
+
hmac = ScaleDown.hmac("/images/scaled/400x300-cropped/#{filename}")
|
29
29
|
assert_equal\
|
30
|
-
"http://images.myserver.com/images/#{CGI.escape filename}
|
30
|
+
"http://images.myserver.com/images/scaled/400x300-cropped/#{CGI.escape filename}?#{hmac}",
|
31
31
|
signed_image_url("/images", filename, "400x300-cropped")
|
32
32
|
end
|
33
33
|
end
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: scale_down
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.5.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- John Weir
|
@@ -10,8 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-
|
14
|
-
default_executable:
|
13
|
+
date: 2011-12-09 00:00:00 Z
|
15
14
|
dependencies:
|
16
15
|
- !ruby/object:Gem::Dependency
|
17
16
|
name: rmagick
|
@@ -118,7 +117,6 @@ files:
|
|
118
117
|
- test/scale_down_test.rb
|
119
118
|
- test/scaled_image_tag_test.rb
|
120
119
|
- test/test_helper.rb
|
121
|
-
has_rdoc: true
|
122
120
|
homepage: http://github.com/jweir/ScaleDown
|
123
121
|
licenses: []
|
124
122
|
|
@@ -142,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
142
140
|
requirements: []
|
143
141
|
|
144
142
|
rubyforge_project: scale_down
|
145
|
-
rubygems_version: 1.
|
143
|
+
rubygems_version: 1.8.8
|
146
144
|
signing_key:
|
147
145
|
specification_version: 3
|
148
146
|
summary: A Sinatra based server for quickly scaling and serving images. Nothing more.
|