httpthumbnailer 0.2.0 → 0.3.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/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