httpthumbnailer 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.3.0
data/bin/httpthumbnailer CHANGED
@@ -50,18 +50,18 @@ sinatra.before do
50
50
  if $thumbnailer.nil?
51
51
  $thumbnailer = Thumbnailer.new(:logger => logger, :limit_memory => settings.limit_memory, :limit_map => settings.limit_map, :limit_disk => settings.limit_disk)
52
52
 
53
- $thumbnailer.method('crop') do |image, spec|
54
- image.resize_to_fill!(spec.width, spec.height)
53
+ $thumbnailer.method('crop') do |image, width, height, options|
54
+ image.resize_to_fill!(width, height)
55
55
  end
56
56
 
57
- $thumbnailer.method('fit') do |image, spec|
58
- image.resize_to_fit!(spec.width, spec.height)
57
+ $thumbnailer.method('fit') do |image, width, height, options|
58
+ image.resize_to_fit!(width, height)
59
59
  end
60
60
 
61
- $thumbnailer.method('pad') do |image, spec|
62
- image.resize_to_fit!(spec.width, spec.height)
61
+ $thumbnailer.method('pad') do |image, width, height, options|
62
+ image.resize_to_fit!(width, height)
63
63
 
64
- out = Magick::Image.new(spec.width, spec.height) {
64
+ out = Magick::Image.new(width, height) {
65
65
  self.background_color = Magick::Pixel.new(Magick::MaxRGB, Magick::MaxRGB, Magick::MaxRGB, Magick::MaxRGB) # transparent
66
66
  }.composite!(image, Magick::CenterGravity, Magick::OverCompositeOp)
67
67
 
@@ -63,6 +63,18 @@ Feature: Generating set of thumbnails with single PUT request
63
63
  Then third part will contain PNG image of size 16x32
64
64
  And third part mime type will be image/png
65
65
 
66
+ Scenario: Thumbnails of width or height INPUT will have input image width or height
67
+ Given test.jpg file content as request body
68
+ When I do PUT request http://localhost:3100/thumbnail/crop,INPUT,16,JPEG/crop,4,INPUT,PNG/crop,INPUT,INPUT,PNG
69
+ Then response status will be 200
70
+ And I will get multipart response
71
+ Then first part will contain JPEG image of size 509x16
72
+ And first part mime type will be image/jpeg
73
+ Then second part will contain PNG image of size 4x719
74
+ And second part mime type will be image/png
75
+ Then third part will contain PNG image of size 509x719
76
+ And third part mime type will be image/png
77
+
66
78
  Scenario: Fit thumbnailing method
67
79
  Given test.jpg file content as request body
68
80
  When I do PUT request http://localhost:3100/thumbnail/fit,128,128,PNG
@@ -129,6 +141,16 @@ Feature: Generating set of thumbnails with single PUT request
129
141
  Error: Thumbnailer::UnsupportedMediaTypeError: Magick::ImageMagickError:
130
142
  """
131
143
 
144
+ Scenario: Reporitng of bad thumbanil spec format - bad dimmension value
145
+ Given test.txt file content as request body
146
+ When I do PUT request http://localhost:3100/thumbnail/crop,128,bogous,PNG
147
+ Then response status will be 500
148
+ And response content type will be text/plain
149
+ And response body will be CRLF endend lines
150
+ """
151
+ Error: ThumbnailSpecs::BadThubnailSpecError::BadDimmensionValueError: bad dimmension value: bogous
152
+ """
153
+
132
154
  Scenario: Reporitng of bad thumbanil spec format - missing param
133
155
  Given test.txt file content as request body
134
156
  When I do PUT request http://localhost:3100/thumbnail/crop,128,PNG
@@ -136,7 +158,7 @@ Feature: Generating set of thumbnails with single PUT request
136
158
  And response content type will be text/plain
137
159
  And response body will be CRLF endend lines
138
160
  """
139
- Error: ThumbnailSpecs::BadThubnailSpecFormat: missing argument in: crop,128,PNG
161
+ Error: ThumbnailSpecs::BadThubnailSpecError::MissingArgumentError: missing argument in: crop,128,PNG
140
162
  """
141
163
 
142
164
  Scenario: Reporitng of bad thumbanil spec format - bad options format
@@ -146,7 +168,7 @@ Feature: Generating set of thumbnails with single PUT request
146
168
  And response content type will be text/plain
147
169
  And response body will be CRLF endend lines
148
170
  """
149
- Error: ThumbnailSpecs::BadThubnailSpecFormat: missing option key or value in: fas-fda
171
+ Error: ThumbnailSpecs::BadThubnailSpecError::MissingOptionKeyOrValueError: missing option key or value in: fas-fda
150
172
  """
151
173
 
152
174
  Scenario: Reporitng of image thumbnailing errors
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "httpthumbnailer"
8
- s.version = "0.2.0"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jakub Pastuszek"]
12
- s.date = "2012-01-12"
12
+ s.date = "2012-01-16"
13
13
  s.description = "Provides HTTP API for thumbnailing images"
14
14
  s.email = "jpastuszek@gmail.com"
15
15
  s.executables = ["httpthumbnailer"]
@@ -1,22 +1,60 @@
1
1
  require 'httpthumbnailer/thumbnailer'
2
2
 
3
3
  class ThumbnailSpecs < Array
4
- class BadThubnailSpecFormat < ArgumentError
4
+ class BadThubnailSpecError < ArgumentError
5
+ class MissingArgumentError < BadThubnailSpecError
6
+ def initialize(spec)
7
+ super "missing argument in: #{spec}"
8
+ end
9
+ end
10
+
11
+ class MissingOptionKeyOrValueError < BadThubnailSpecError
12
+ def initialize(option)
13
+ super "missing option key or value in: #{option}"
14
+ end
15
+ end
16
+
17
+ class BadDimmensionValueError < BadThubnailSpecError
18
+ def initialize(value)
19
+ super "bad dimmension value: #{value}"
20
+ end
21
+ end
22
+ end
23
+
24
+ class ThumbnailSpec
25
+ def initialize(method, width, height, format, options = {})
26
+ @method = method
27
+ @width = cast_dimmension(width)
28
+ @height = cast_dimmension(height)
29
+ @format = (format == 'INPUT' ? :input : format.upcase)
30
+ @options = options
31
+ end
32
+
33
+ attr_reader :method, :width, :height, :format, :options
34
+
35
+ def to_s
36
+ "#{method} #{width}x#{height} (#{format}) #{options.inspect}"
37
+ end
38
+
39
+ private
40
+
41
+ def cast_dimmension(string)
42
+ return :input if string == 'INPUT'
43
+ raise BadThubnailSpecError::BadDimmensionValueError.new(string) unless string =~ /^\d+$/
44
+ string.to_i
45
+ end
5
46
  end
6
47
 
7
48
  def self.from_uri(specs)
8
49
  ts = ThumbnailSpecs.new
9
50
  specs.split('/').each do |spec|
10
51
  method, width, height, format, *options = *spec.split(',')
11
- raise BadThubnailSpecFormat, "missing argument in: #{spec}" unless method and width and height and format
12
-
13
- width = width.to_i
14
- height = height.to_i
52
+ raise BadThubnailSpecError::MissingArgumentError.new(spec) unless method and width and height and format
15
53
 
16
54
  opts = {}
17
55
  options.each do |option|
18
56
  key, value = option.split(':')
19
- raise BadThubnailSpecFormat, "missing option key or value in: #{option}" unless key and value
57
+ raise BadThubnailSpecError::MissingOptionKeyOrValueError.new(option) unless key and value
20
58
  opts[key] = value
21
59
  end
22
60
 
@@ -26,25 +64,17 @@ class ThumbnailSpecs < Array
26
64
  end
27
65
 
28
66
  def max_width
29
- map{|spec| spec.width}.max
67
+ map do |spec|
68
+ return nil unless spec.width.is_a? Integer
69
+ spec.width
70
+ end.max
30
71
  end
31
72
 
32
73
  def max_height
33
- map{|spec| spec.height}.max
34
- end
35
-
36
- def biggest_spec
37
- max_field = -1
38
- max_spec = nil
39
- each do |spec|
40
- field = spec.width * spec.height
41
- if max_field < field
42
- max_field = field
43
- max_spec = spec
44
- end
45
- end
46
-
47
- max_spec
74
+ map do |spec|
75
+ return nil unless spec.height.is_a? Integer
76
+ spec.height
77
+ end.max
48
78
  end
49
79
  end
50
80
 
@@ -12,23 +12,6 @@ class Magick::Image
12
12
  end
13
13
  end
14
14
 
15
-
16
- class ThumbnailSpec
17
- def initialize(method, width, height, format, options = {})
18
- @method = method
19
- @width = width
20
- @height = height
21
- @format = format.upcase
22
- @options = options
23
- end
24
-
25
- attr_reader :method, :width, :height, :format, :options
26
-
27
- def to_s
28
- "#{method} #{width}x#{height} (#{format}) #{options.inspect}"
29
- end
30
- end
31
-
32
15
  class Thumbnailer
33
16
  class UnsupportedMethodError < ArgumentError
34
17
  def initialize(method)
@@ -92,7 +75,6 @@ class Thumbnailer
92
75
  @options = options
93
76
  @logger = (options[:logger] or Logger.new('/dev/null'))
94
77
 
95
-
96
78
  mw = options['max-width']
97
79
  mh = options['max-height']
98
80
  if mw and mh
@@ -132,9 +114,14 @@ class Thumbnailer
132
114
  def thumbnail(spec)
133
115
  begin
134
116
  ImageHandler.new do
135
- process_image(@image, spec).render_on_background!((spec.options['background-color'] or 'white').sub(/^0x/, '#'))
117
+ width = spec.width == :input ? @image.columns : spec.width
118
+ height = spec.height == :input ? @image.rows : spec.height
119
+
120
+ process_image(@image, spec.method, width, height, spec.options).render_on_background!((spec.options['background-color'] or 'white').sub(/^0x/, '#'))
136
121
  end.use do |image|
137
- yield Thumbnail.new(image, spec.format == 'INPUT' ? @image.format : spec.format, spec.options['quality'])
122
+ format = spec.format == :input ? @image.format : spec.format
123
+
124
+ yield Thumbnail.new(image, format, spec.options)
138
125
  end
139
126
  rescue Magick::ImageMagickError => e
140
127
  raise ImageTooLargeError, e if e.message =~ /cache resources exhausted/
@@ -161,11 +148,11 @@ class Thumbnailer
161
148
  end
162
149
  end
163
150
 
164
- def process_image(image, spec)
165
- impl = @methods[spec.method] or raise UnsupportedMethodError.new(spec.method)
151
+ def process_image(image, method, width, height, options)
152
+ impl = @methods[method] or raise UnsupportedMethodError.new(method)
166
153
  copy = image.copy
167
154
  begin
168
- impl.call(copy, spec)
155
+ impl.call(copy, width, height, options)
169
156
  rescue
170
157
  copy.destroy!
171
158
  raise
@@ -174,10 +161,10 @@ class Thumbnailer
174
161
  end
175
162
 
176
163
  class Thumbnail
177
- def initialize(image, format, quality = nil)
164
+ def initialize(image, format, options = {})
178
165
  @image = image
179
166
  @format = format
180
- @quality = (quality or default_quality(format))
167
+ @quality = (options['quality'] or default_quality(format))
181
168
  @quality &&= @quality.to_i
182
169
  end
183
170
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: httpthumbnailer
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 2
8
+ - 3
9
9
  - 0
10
- version: 0.2.0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jakub Pastuszek
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-01-12 00:00:00 Z
18
+ date: 2012-01-16 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  type: :runtime