httpthumbnailer-client 0.0.1 → 0.0.2

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/Gemfile CHANGED
@@ -12,5 +12,5 @@ group :development do
12
12
  gem "rcov", ">= 0"
13
13
  gem "rdoc", "~> 3.9"
14
14
  gem "daemon", "~> 1"
15
- gem "httpthumbnailer", "~> 0.0.1"
15
+ gem "httpthumbnailer", "~> 0.0.5"
16
16
  end
data/Gemfile.lock CHANGED
@@ -17,9 +17,9 @@ GEM
17
17
  gherkin (2.6.7)
18
18
  json (>= 1.4.6)
19
19
  git (1.2.5)
20
- haml (3.1.3)
20
+ haml (3.1.4)
21
21
  httpclient (2.2.3)
22
- httpthumbnailer (0.0.1)
22
+ httpthumbnailer (0.0.5)
23
23
  haml (~> 3)
24
24
  mongrel (>= 1.1.5)
25
25
  rmagick (~> 2)
@@ -64,7 +64,7 @@ DEPENDENCIES
64
64
  cucumber
65
65
  daemon (~> 1)
66
66
  httpclient (>= 2.2.1)
67
- httpthumbnailer (~> 0.0.1)
67
+ httpthumbnailer (~> 0.0.5)
68
68
  jeweler (~> 1.6.4)
69
69
  rcov
70
70
  rdoc (~> 3.9)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.2
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "httpthumbnailer-client"
8
- s.version = "0.0.1"
8
+ s.version = "0.0.2"
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 = "2011-11-23"
12
+ s.date = "2011-11-29"
13
13
  s.description = "Thumbnails images using httpthumbniler server"
14
14
  s.email = "jpastuszek@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -33,7 +33,8 @@ Gem::Specification.new do |s|
33
33
  "spec/httpthumbnailer-client_spec.rb",
34
34
  "spec/multipart_response_spec.rb",
35
35
  "spec/spec_helper.rb",
36
- "spec/test.jpg"
36
+ "spec/test.jpg",
37
+ "spec/test.txt"
37
38
  ]
38
39
  s.homepage = "http://github.com/jpastuszek/httpthumbnailer-client"
39
40
  s.licenses = ["MIT"]
@@ -53,7 +54,7 @@ Gem::Specification.new do |s|
53
54
  s.add_development_dependency(%q<rcov>, [">= 0"])
54
55
  s.add_development_dependency(%q<rdoc>, ["~> 3.9"])
55
56
  s.add_development_dependency(%q<daemon>, ["~> 1"])
56
- s.add_development_dependency(%q<httpthumbnailer>, ["~> 0.0.1"])
57
+ s.add_development_dependency(%q<httpthumbnailer>, ["~> 0.0.5"])
57
58
  else
58
59
  s.add_dependency(%q<httpclient>, [">= 2.2.1"])
59
60
  s.add_dependency(%q<rspec>, ["~> 2.3.0"])
@@ -63,7 +64,7 @@ Gem::Specification.new do |s|
63
64
  s.add_dependency(%q<rcov>, [">= 0"])
64
65
  s.add_dependency(%q<rdoc>, ["~> 3.9"])
65
66
  s.add_dependency(%q<daemon>, ["~> 1"])
66
- s.add_dependency(%q<httpthumbnailer>, ["~> 0.0.1"])
67
+ s.add_dependency(%q<httpthumbnailer>, ["~> 0.0.5"])
67
68
  end
68
69
  else
69
70
  s.add_dependency(%q<httpclient>, [">= 2.2.1"])
@@ -74,7 +75,7 @@ Gem::Specification.new do |s|
74
75
  s.add_dependency(%q<rcov>, [">= 0"])
75
76
  s.add_dependency(%q<rdoc>, ["~> 3.9"])
76
77
  s.add_dependency(%q<daemon>, ["~> 1"])
77
- s.add_dependency(%q<httpthumbnailer>, ["~> 0.0.1"])
78
+ s.add_dependency(%q<httpthumbnailer>, ["~> 0.0.5"])
78
79
  end
79
80
  end
80
81
 
@@ -3,6 +3,15 @@ require 'httpclient'
3
3
  require 'httpthumbnailer-client/multipart_response'
4
4
 
5
5
  class HTTPThumbnailerClient
6
+ class UnsupportedMediaTypeError < ArgumentError
7
+ end
8
+
9
+ class UnknownResponseType < ArgumentError
10
+ end
11
+
12
+ class RemoteServerError < ArgumentError
13
+ end
14
+
6
15
  class URIBuilder
7
16
  def initialize(service_uri, &block)
8
17
  @specs = []
@@ -42,15 +51,46 @@ class HTTPThumbnailerClient
42
51
  attr_reader :mime_type, :data
43
52
  end
44
53
 
54
+ class ThumbnailingError
55
+ def initialize(msg)
56
+ @message = msg
57
+ end
58
+
59
+ attr_reader :message
60
+ end
61
+
45
62
  def initialize(server_url)
46
63
  @server_url = server_url
47
64
  end
48
65
 
49
66
  def thumbnail(data, &block)
50
67
  uri = URIBuilder.thumbnail(&block)
51
- res = HTTPClient.new.request('PUT', "#{@server_url}#{uri}", nil, data)
52
- MultipartResponse.new(res.header['Content-Type'].last, res.body).parts.map do |part|
53
- Thumbnail.new(part.header['Content-Type'], part.body)
68
+ response = HTTPClient.new.request('PUT', "#{@server_url}#{uri}", nil, data)
69
+ content_type = response.header['Content-Type'].last
70
+
71
+ case content_type
72
+ when 'text/plain'
73
+ case response.status
74
+ when 415
75
+ raise UnsupportedMediaTypeError, response.body.delete("\r")
76
+ else
77
+ raise RemoteServerError, response.body.delete("\r")
78
+ end
79
+ when /^multipart\/mixed/
80
+ MultipartResponse.new(content_type, response.body).parts.map do |part|
81
+ part_content_type = part.header['Content-Type']
82
+
83
+ case part_content_type
84
+ when 'text/plain'
85
+ ThumbnailingError.new(part.body.delete("\r"))
86
+ when /^image\//
87
+ Thumbnail.new(part_content_type, part.body)
88
+ else
89
+ raise UnknownResponseType, part_content_type
90
+ end
91
+ end
92
+ else
93
+ raise UnknownResponseType, content_type
54
94
  end
55
95
  end
56
96
  end
@@ -13,35 +13,90 @@ end
13
13
 
14
14
  describe HTTPThumbnailerClient do
15
15
  before :all do
16
- server_start
17
- @data = File.read(spec_dir + 'test.jpg')
16
+ log = spec_dir + 'server.log'
17
+ log.truncate(0)
18
+
19
+ start_server(
20
+ "httpthumbnailer",
21
+ '/tmp/httpthumbnailer.pid',
22
+ log,
23
+ 'http://localhost:3100/'
24
+ )
18
25
  end
19
26
 
20
27
  after :all do
21
- server_stop
28
+ stop_server('/tmp/httpthumbnailer.pid')
22
29
  end
23
30
 
24
31
  it "should return set of thumbnails matching specified specification" do
25
- thumbs = HTTPThumbnailerClient.new('http://localhost:3100').thumbnail(@data) do
32
+ thumbs = HTTPThumbnailerClient.new('http://localhost:3100').thumbnail((spec_dir + 'test.jpg').read) do
26
33
  thumbnail 'crop', 6, 3, 'JPEG'
27
34
  thumbnail 'crop', 8, 8, 'PNG'
28
35
  thumbnail 'crop', 4, 4, 'PNG'
29
36
  end
30
37
 
38
+ thumbs[0].should be_kind_of HTTPThumbnailerClient::Thumbnail
31
39
  thumbs[0].mime_type.should == 'image/jpeg'
32
- t, s = identify(thumbs[0].data)
33
- t.should == 'JPEG'
34
- s.should == '6x3'
40
+ i = identify(thumbs[0].data)
41
+ i.format.should == 'JPEG'
42
+ i.width.should == 6
43
+ i.height.should == 3
35
44
 
45
+ thumbs[1].should be_kind_of HTTPThumbnailerClient::Thumbnail
36
46
  thumbs[1].mime_type.should == 'image/png'
37
- t, s = identify(thumbs[1].data)
38
- t.should == 'PNG'
39
- s.should == '8x8'
47
+ i = identify(thumbs[1].data)
48
+ i.format.should == 'PNG'
49
+ i.width.should == 8
50
+ i.height.should == 8
40
51
 
52
+ thumbs[2].should be_kind_of HTTPThumbnailerClient::Thumbnail
41
53
  thumbs[2].mime_type.should == 'image/png'
42
- t, s = identify(thumbs[2].data)
43
- t.should == 'PNG'
44
- s.should == '4x4'
54
+ i = identify(thumbs[2].data)
55
+ i.format.should == 'PNG'
56
+ i.width.should == 4
57
+ i.height.should == 4
58
+ end
59
+
60
+ it "should raise HTTPThumbnailerClient::UnsupportedMediaTypeError error on unsupported media type" do
61
+ lambda {
62
+ HTTPThumbnailerClient.new('http://localhost:3100').thumbnail((spec_dir + 'test.txt').read) do
63
+ thumbnail 'crop', 6, 3, 'JPEG'
64
+ thumbnail 'crop', 8, 8, 'PNG'
65
+ end
66
+ }.should raise_error HTTPThumbnailerClient::UnsupportedMediaTypeError
67
+ end
68
+
69
+ it "should raise HTTPThumbnailerClient::RemoteServerError error on 404 server error" do
70
+ lambda {
71
+ HTTPThumbnailerClient.new('http://localhost:3100/blah').thumbnail((spec_dir + 'test.jpg').read) do
72
+ thumbnail 'crop', 6, 3, 'JPEG'
73
+ end
74
+ }.should raise_error HTTPThumbnailerClient::RemoteServerError
75
+ end
76
+
77
+ it "should return HTTPThumbnailerClient::ThumbnailingError object with set of returned thumbnail in case of error with particluar thumbanil" do
78
+ thumbs = HTTPThumbnailerClient.new('http://localhost:3100').thumbnail((spec_dir + 'test.jpg').read) do
79
+ thumbnail 'crop', 6, 3, 'JPEG'
80
+ thumbnail 'crop', 0, 0, 'PNG'
81
+ thumbnail 'crop', 4, 4, 'PNG'
82
+ end
83
+
84
+ thumbs[0].should be_kind_of HTTPThumbnailerClient::Thumbnail
85
+ thumbs[0].mime_type.should == 'image/jpeg'
86
+ i = identify(thumbs[0].data)
87
+ i.format.should == 'JPEG'
88
+ i.width.should == 6
89
+ i.height.should == 3
90
+
91
+ thumbs[1].should be_kind_of HTTPThumbnailerClient::ThumbnailingError
92
+ thumbs[1].message.should == "Error: ArgumentError: invalid result dimension (0, 0 given)\n"
93
+
94
+ thumbs[2].should be_kind_of HTTPThumbnailerClient::Thumbnail
95
+ thumbs[2].mime_type.should == 'image/png'
96
+ i = identify(thumbs[2].data)
97
+ i.format.should == 'PNG'
98
+ i.width.should == 4
99
+ i.height.should == 4
45
100
  end
46
101
  end
47
102
 
data/spec/spec_helper.rb CHANGED
@@ -11,6 +11,7 @@ RSpec.configure do |config|
11
11
  end
12
12
 
13
13
  require 'daemon'
14
+ require 'RMagick'
14
15
 
15
16
  def gem_dir
16
17
  Pathname.new(__FILE__).dirname + '..'
@@ -20,16 +21,34 @@ def spec_dir
20
21
  gem_dir + 'spec'
21
22
  end
22
23
 
23
- def server_start
24
- File.exist?("/tmp/httpthumbnailer.pid") and server_stop
25
- fork do
26
- Daemon.daemonize("/tmp/httpthumbnailer.pid", spec_dir + 'server.log')
27
- exec("httpthumbnailer")
24
+ def identify(data)
25
+ image = Magick::Image.from_blob(data).first
26
+ out = Struct.new(:format, :width, :height).new(image.format, image.columns, image.rows)
27
+ image.destroy!
28
+ out
29
+ end
30
+
31
+ def get(url)
32
+ HTTPClient.new.get_content(url)
33
+ end
34
+
35
+ def start_server(cmd, pid_file, log_file, test_url)
36
+ stop_server(pid_file)
37
+
38
+ fork do
39
+ Daemon.daemonize(pid_file, log_file)
40
+ exec(cmd)
41
+ end
42
+ Process.wait
43
+
44
+ ppid = Process.pid
45
+ at_exit do
46
+ stop_server(pid_file) if Process.pid == ppid
28
47
  end
29
48
 
30
49
  Timeout.timeout(10) do
31
- begin
32
- server_get '/'
50
+ begin
51
+ get test_url
33
52
  rescue Errno::ECONNREFUSED
34
53
  sleep 0.1
35
54
  retry
@@ -37,32 +56,21 @@ def server_start
37
56
  end
38
57
  end
39
58
 
40
- def server_stop
41
- File.open("/tmp/httpthumbnailer.pid") do |pidf|
42
- pid = pidf.read
59
+ def stop_server(pid_file)
60
+ pid_file = Pathname.new(pid_file)
61
+ return unless pid_file.exist?
43
62
 
44
- Timeout.timeout(10) do
45
- begin
46
- loop do
47
- ret = Process.kill("TERM", pid.strip.to_i)
48
- sleep 0.1
49
- end
50
- rescue Errno::ESRCH
63
+ pid = pid_file.read.strip.to_i
64
+
65
+ Timeout.timeout(20) do
66
+ begin
67
+ loop do
68
+ Process.kill("TERM", pid)
69
+ sleep 0.1
51
70
  end
71
+ rescue Errno::ESRCH
72
+ pid_file.unlink
52
73
  end
53
74
  end
54
75
  end
55
76
 
56
- def server_get(uri)
57
- HTTPClient.new.get_content("http://localhost:3100#{uri}")
58
- end
59
-
60
- def identify(data)
61
- Open3.popen3('identify -') do |stdin, stdout, stderr|
62
- stdin.write data
63
- stdin.close
64
- path, type, size, *rest = *stdout.read.split(' ')
65
- return type, size
66
- end
67
- end
68
-
data/spec/test.txt ADDED
@@ -0,0 +1 @@
1
+ hello world
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: httpthumbnailer-client
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
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: 2011-11-23 00:00:00 Z
18
+ date: 2011-11-29 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  type: :runtime
@@ -145,12 +145,12 @@ dependencies:
145
145
  requirements:
146
146
  - - ~>
147
147
  - !ruby/object:Gem::Version
148
- hash: 29
148
+ hash: 21
149
149
  segments:
150
150
  - 0
151
151
  - 0
152
- - 1
153
- version: 0.0.1
152
+ - 5
153
+ version: 0.0.5
154
154
  prerelease: false
155
155
  name: httpthumbnailer
156
156
  version_requirements: *id009
@@ -181,6 +181,7 @@ files:
181
181
  - spec/multipart_response_spec.rb
182
182
  - spec/spec_helper.rb
183
183
  - spec/test.jpg
184
+ - spec/test.txt
184
185
  homepage: http://github.com/jpastuszek/httpthumbnailer-client
185
186
  licenses:
186
187
  - MIT