Skip to content

Commit fc5a2bc

Browse files
RobovirtuosoHackuman Rodriguez (bullseye)
authored andcommitted
Make response object
1 parent 8a71b9f commit fc5a2bc

File tree

7 files changed

+128
-44
lines changed

7 files changed

+128
-44
lines changed

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
source :rubygems
1+
source 'https://rubygems.org'
22

33
gemspec

kraken-io.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Gem::Specification.new do |s|
1616
s.add_dependency('json')
1717
s.add_dependency('httparty')
1818
s.add_dependency('multipart-post')
19+
s.add_dependency('activesupport')
1920
s.add_development_dependency('rspec')
2021
s.add_development_dependency('webmock', '~> 1.17')
2122
end

lib/kraken-io.rb

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,59 @@
11
require 'json'
22
require 'httparty'
3-
require 'net/http/post/multipart'
3+
require 'active_support/hash_with_indifferent_access'
4+
require 'active_support/core_ext/hash'
5+
6+
require 'kraken-io/http_multi_part'
7+
require 'kraken-io/response'
48

59
module Kraken
610
class API
711
include HTTParty
12+
extend HTTPMultiPart
13+
14+
base_uri 'https://api.kraken.io/v1'
815

916
attr_accessor :api_key, :api_secret
1017

11-
def initialize(api_key = '', api_secret = '')
12-
@api_key = api_key
13-
@api_secret = api_secret
18+
def initialize(options = {})
19+
@api_key = options.fetch(:api_key)
20+
@api_secret = options.fetch(:api_secret)
1421
end
1522

16-
def url(params = {})
17-
params.merge!({
18-
'auth' => {
19-
'api_key' => @api_key,
20-
'api_secret' => @api_secret
21-
}
22-
})
23-
24-
self.class.post('https://api.kraken.io/v1/url', {:body => JSON.generate(params)})
23+
def url(url, params = {})
24+
params = normalized_params(params).merge!(auth_hash)
25+
params[:url] = url
26+
res = self.class.post('/url', body: params.to_json)
27+
res = Kraken::Response.new(res)
28+
yield res if block_given? or return res
2529
end
2630

27-
def upload(params = {})
28-
params.merge!({
29-
'auth' => {
30-
'api_key' => @api_key,
31-
'api_secret' => @api_secret
32-
}
33-
})
31+
def upload(file_name, params = {})
32+
params = normalized_params(params).merge!(auth_hash)
33+
res = self.class.multipart_post('/upload', file: file_name, body: params.to_json)
34+
res = Kraken::Response.new(res)
35+
yield res if block_given? or return res
36+
end
3437

35-
url = URI.parse("https://api.kraken.io/v1/upload")
38+
private
3639

37-
File.open(params['file']) do |file|
38-
params.delete('file')
40+
def normalized_params(params)
41+
params = params.with_indifferent_access
3942

40-
req = Net::HTTP::Post::Multipart.new url.path, "body" => JSON.generate(params), "file" => UploadIO.new(file, 'logotyp.png')
43+
unless params.keys.include?(:callback)
44+
params[:wait] = true
45+
end
4146

42-
https = Net::HTTP.new(url.host, url.port)
43-
https.use_ssl = true
47+
params
48+
end
4449

45-
res = https.start() {|conn| conn.request(req)}
46-
response = JSON.parse(res.body)
47-
end
50+
def auth_hash
51+
{
52+
auth: {
53+
api_key: api_key,
54+
api_secret: api_secret
55+
}
56+
}
4857
end
4958
end
5059
end

lib/kraken-io/http_multi_part.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
require 'net/http/post/multipart'
2+
3+
module HTTPMultiPart
4+
def multipart_post(url, params = {})
5+
unless params.has_key?(:file)
6+
post(url, params)
7+
end
8+
9+
url = URI.parse(base_uri + url)
10+
11+
req = Net::HTTP::Post::Multipart.new(url.path, {
12+
file: UploadIO.new(File.open(params[:file]), 'file'),
13+
body: params[:body] })
14+
15+
https = Net::HTTP.new(url.host, url.port)
16+
https.use_ssl = true
17+
https.request(req)
18+
end
19+
end

lib/kraken-io/response.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
require 'active_support/ordered_options'
2+
require 'forwardable'
3+
require 'delegate'
4+
require 'json'
5+
6+
module Kraken
7+
class Response < SimpleDelegator
8+
extend Forwardable
9+
10+
def_delegators :@parsed, :success, :file_name, :original_size,
11+
:kraked_size, :saved_bytes, :kraked_url
12+
13+
def initialize(response)
14+
super(response)
15+
@parsed = ActiveSupport::InheritableOptions.new(JSON.parse(response.body).with_indifferent_access)
16+
end
17+
18+
alias_method :original_response, :__getobj__
19+
end
20+
end

spec/kraken-io/response_spec.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
require 'spec_helper'
2+
3+
describe Kraken::Response do
4+
subject do
5+
Kraken::Response.new(WebMock::Response.new(body: result.to_json))
6+
end
7+
8+
let(:result) do
9+
{
10+
"success" => true,
11+
"file_name" => "header.jpg",
12+
"original_size" => 324520,
13+
"kraked_size" => 165358,
14+
"saved_bytes" => 159162,
15+
"kraked_url" => "http://dl.kraken.io/ecdfa5c55d5668b1b5fe9e420554c4ee/header.jpg"
16+
}
17+
end
18+
19+
describe "delegates to the response object" do
20+
its(:success) { should == result['success'] }
21+
its(:file_name) { should == result['file_name'] }
22+
its(:original_size) { should == result['original_size'] }
23+
its(:kraked_size) { should == result['kraked_size'] }
24+
its(:saved_bytes) { should == result['saved_bytes'] }
25+
its(:kraked_url) { should == result['kraked_url'] }
26+
end
27+
28+
describe "still responds to HTTP response methods" do
29+
its(:status) { should eq [200, ''] }
30+
end
31+
end

spec/kraken-io_spec.rb

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,33 @@
99
"kraked_size" => 165358,
1010
"saved_bytes" => 159162,
1111
"kraked_url" => "http://dl.kraken.io/ecdfa5c55d5668b1b5fe9e420554c4ee/header.jpg"
12-
}.to_json
12+
}
13+
end
14+
15+
subject { Kraken::API.new(api_key: 1, api_secret: 2) }
16+
17+
describe 'initialize' do
18+
it 'is an error to leave out the key or secret' do
19+
expect { Kraken::API.new(api_secret: 2) }.to raise_error KeyError
20+
expect { Kraken::API.new(api_key: 2) }.to raise_error KeyError
21+
end
1322
end
1423

15-
subject { Kraken::API.new(1,2) }
1624
describe '#url' do
1725
let(:expected_params) do
1826
{
19-
'url' => 'http://farts.gallery',
2027
'wait' => true,
21-
'auth' => { 'api_key' => 1, 'api_secret' => 2}
28+
'auth' => { 'api_key' => 1, 'api_secret' => 2},
29+
'url' => 'http://farts.gallery'
2230
}
2331
end
2432

2533
it 'provides a url to the kraken api' do
2634
stub_request(:post, "https://api.kraken.io/v1/url")
27-
.with(:body => expected_params.to_json).to_return(body: result)
35+
.with(:body => expected_params.to_json).to_return(body: result.to_json)
2836

29-
subject.url(
30-
'url' => 'http://farts.gallery',
31-
'wait' => true
32-
)
37+
res = subject.url('http://farts.gallery')
38+
expect(res.code).to eq 200
3339
end
3440
end
3541

@@ -46,12 +52,10 @@
4652
expect(req.body).to include(expected_params.to_json)
4753
expect(req.body).to include('filename="test.gif"')
4854
expect(req.headers['Content-Type']).to include('multipart/form-data')
49-
end.to_return(body: result)
55+
end.to_return(body: result.to_json)
5056

51-
subject.upload(
52-
'wait' => true,
53-
'file' => File.expand_path('test.gif', File.dirname(__FILE__))
54-
)
57+
res = subject.upload(File.expand_path('test.gif', File.dirname(__FILE__)))
58+
expect(res).to be_kind_of Kraken::Response
5559
end
5660
end
5761
end

0 commit comments

Comments
 (0)