api_bucket 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +19 -0
- data/.rspec +1 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +22 -0
- data/README.md +54 -0
- data/Rakefile +1 -0
- data/VERSION +1 -0
- data/api-bucket.gemspec +23 -0
- data/lib/api_bucket/amazon/client/http.rb +61 -0
- data/lib/api_bucket/amazon/client.rb +73 -0
- data/lib/api_bucket/amazon/configration.rb +13 -0
- data/lib/api_bucket/amazon/item.rb +63 -0
- data/lib/api_bucket/amazon/response.rb +28 -0
- data/lib/api_bucket/amazon.rb +12 -0
- data/lib/api_bucket/base/client/http.rb +40 -0
- data/lib/api_bucket/base/element.rb +54 -0
- data/lib/api_bucket/base/item.rb +39 -0
- data/lib/api_bucket/base/response.rb +20 -0
- data/lib/api_bucket/itunes/client/http.rb +9 -0
- data/lib/api_bucket/itunes/client.rb +61 -0
- data/lib/api_bucket/itunes/configuration.rb +13 -0
- data/lib/api_bucket/itunes/item.rb +71 -0
- data/lib/api_bucket/itunes/response.rb +35 -0
- data/lib/api_bucket/itunes.rb +13 -0
- data/lib/api_bucket/rakuten/client/http.rb +9 -0
- data/lib/api_bucket/rakuten/client.rb +80 -0
- data/lib/api_bucket/rakuten/configuration.rb +13 -0
- data/lib/api_bucket/rakuten/item.rb +52 -0
- data/lib/api_bucket/rakuten/response.rb +32 -0
- data/lib/api_bucket/rakuten.rb +13 -0
- data/lib/api_bucket/version.rb +3 -0
- data/lib/api_bucket/yahooauction/client/http.rb +26 -0
- data/lib/api_bucket/yahooauction/client.rb +65 -0
- data/lib/api_bucket/yahooauction/configuration.rb +13 -0
- data/lib/api_bucket/yahooauction/item.rb +29 -0
- data/lib/api_bucket/yahooauction/response.rb +39 -0
- data/lib/api_bucket/yahooauction.rb +16 -0
- data/lib/api_bucket.rb +91 -0
- data/spec/api_bucket/amazon_spec.rb +66 -0
- data/spec/api_bucket/itunes_spec.rb +65 -0
- data/spec/api_bucket/rakuten_spec.rb +67 -0
- data/spec/api_bucket/yahooauction_spec.rb +69 -0
- data/spec/api_bucket_spec.rb +90 -0
- data/spec/secret.rb.skel +14 -0
- data/spec/spec_helper.rb +12 -0
- metadata +146 -0
data/.document
ADDED
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 nakajijapan
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# ApiBucket
|
2
|
+
|
3
|
+
We can use sevral APIs with common interface.
|
4
|
+
|
5
|
+
* APIs
|
6
|
+
* Amazon ECS
|
7
|
+
* iTunes
|
8
|
+
* Rakuten(楽天)
|
9
|
+
* Yahoo Auction
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
gem 'api_bucket'
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install api_bucket
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
### use Amazon
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
require 'api_bucket'
|
31
|
+
require 'api_bucket/amazon'
|
32
|
+
|
33
|
+
ApiBucket::Amazon::Client.configure do |o|
|
34
|
+
o.a_w_s_access_key_id = 'hogehoge'
|
35
|
+
o.a_w_s_secret_key = 'mogemoge'
|
36
|
+
o.associate_tag = 'nakajijapan'
|
37
|
+
end
|
38
|
+
|
39
|
+
service = ApiBucket::Service::instance(:amazon)
|
40
|
+
res = service.item_search('ruby')
|
41
|
+
|
42
|
+
res.items.each do |item|
|
43
|
+
p item.product_code
|
44
|
+
p item.title
|
45
|
+
end
|
46
|
+
```
|
47
|
+
|
48
|
+
## Contributing
|
49
|
+
|
50
|
+
1. Fork it
|
51
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
52
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
53
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
54
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/api-bucket.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'api_bucket/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "api_bucket"
|
8
|
+
gem.version = ApiBucket::VERSION
|
9
|
+
gem.authors = ["nakajijapan"]
|
10
|
+
gem.email = ["pp.kupepo.gattyanmo@gmail.com"]
|
11
|
+
gem.description = %q{We can use sevral APIs with common interface.}
|
12
|
+
gem.summary = %q{We can use sevral APIs with common interface}
|
13
|
+
gem.homepage = "https://github.com/nakajijapan/api_bucket"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency "nokogiri"
|
21
|
+
gem.add_dependency "ruby-hmac"
|
22
|
+
gem.add_development_dependency('rspec', ['~> 2.8.0'])
|
23
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module ApiBucket::Amazon
|
2
|
+
class Client
|
3
|
+
module Http
|
4
|
+
def send_request(options)
|
5
|
+
request_url = "#{REQUEST_URL}?#{self.prepare_query(options)}"
|
6
|
+
uri = URI::parse(request_url)
|
7
|
+
res = Net::HTTP.get_response(uri)
|
8
|
+
res.body
|
9
|
+
end
|
10
|
+
|
11
|
+
def sign_request(url, key)
|
12
|
+
openssl_digest = OpenSSL::Digest::Digest.new( 'sha256' )
|
13
|
+
signature = OpenSSL::HMAC.digest(openssl_digest, key, url)
|
14
|
+
signature = [signature].pack('m').chomp
|
15
|
+
signature = URI.escape(signature, Regexp.new("[+=]"))
|
16
|
+
return signature
|
17
|
+
end
|
18
|
+
|
19
|
+
def url_encode(string)
|
20
|
+
string.gsub( /([^a-zA-Z0-9_.~-]+)/ ) do
|
21
|
+
'%' + $1.unpack( 'H2' * $1.bytesize ).join( '%' ).upcase
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def prepare_query(options)
|
26
|
+
query = ''
|
27
|
+
|
28
|
+
secret_key = options.delete(:a_w_s_secret_key)
|
29
|
+
request_host = URI.parse(REQUEST_URL).host
|
30
|
+
|
31
|
+
options = options.sort do |c,d|
|
32
|
+
c[0].to_s <=> d[0].to_s
|
33
|
+
end
|
34
|
+
|
35
|
+
options = options.collect do |a,b|
|
36
|
+
[camelize(a.to_s), b.to_s]
|
37
|
+
end
|
38
|
+
|
39
|
+
options.each do |key, value|
|
40
|
+
next if value.nil?
|
41
|
+
query << "&#{key}=#{self.url_encode(value)}"
|
42
|
+
end
|
43
|
+
|
44
|
+
query.slice!(0)
|
45
|
+
|
46
|
+
# only amazon
|
47
|
+
signature = ''
|
48
|
+
unless secret_key.nil?
|
49
|
+
request_to_sign="GET\n#{request_host}\n/onca/xml\n#{query}"
|
50
|
+
signature = "&Signature=#{sign_request(request_to_sign, secret_key)}"
|
51
|
+
end
|
52
|
+
|
53
|
+
"#{query}#{signature}"
|
54
|
+
end
|
55
|
+
|
56
|
+
def camelize(s)
|
57
|
+
s.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require "api_bucket/amazon/client/http"
|
2
|
+
|
3
|
+
module ApiBucket::Amazon
|
4
|
+
class Client
|
5
|
+
attr_accessor :version, :service, :a_w_s_access_key_id, :a_w_s_secret_key, :associate_tag
|
6
|
+
attr_accessor :country, :count, :item_page
|
7
|
+
|
8
|
+
REQUEST_URL = 'http://ecs.amazonaws.jp/onca/xml'
|
9
|
+
|
10
|
+
def categories
|
11
|
+
{
|
12
|
+
ALL: '----',
|
13
|
+
DVD: 'DVD / BD',
|
14
|
+
ForeignBooks: 'ForeignBooks',
|
15
|
+
VideoGames: 'VideoGames',
|
16
|
+
Music: 'Music',
|
17
|
+
Software: 'Software',
|
18
|
+
Electronics: 'Electronics',
|
19
|
+
Watches: 'Watches',
|
20
|
+
KindleStore: 'KindleStore',
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(options={})
|
25
|
+
options = ApiBucket::Amazon.options.merge(options)
|
26
|
+
self.version = '2011-08-01'
|
27
|
+
self.service = 'AWSECommerceService'
|
28
|
+
self.a_w_s_access_key_id = options[:a_w_s_access_key_id]
|
29
|
+
self.a_w_s_secret_key = options[:a_w_s_secret_key]
|
30
|
+
self.associate_tag = options[:associate_tag]
|
31
|
+
self.country = 'ja'
|
32
|
+
self.count = 20
|
33
|
+
self.item_page = 1
|
34
|
+
end
|
35
|
+
|
36
|
+
def search(keywords, params={})
|
37
|
+
options = {
|
38
|
+
a_w_s_access_key_id: self.a_w_s_access_key_id,
|
39
|
+
a_w_s_secret_key: self.a_w_s_secret_key,
|
40
|
+
associate_tag: self.associate_tag,
|
41
|
+
|
42
|
+
operation: 'ItemSearch',
|
43
|
+
response_group: 'Large,EditorialReview,ItemAttributes',
|
44
|
+
item_page: @page,
|
45
|
+
count: @limit,
|
46
|
+
search_index: 'All',
|
47
|
+
keywords: keywords,
|
48
|
+
timestamp: Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
|
49
|
+
}
|
50
|
+
options.merge!(params)
|
51
|
+
|
52
|
+
ApiBucket::Amazon::Response.new(send_request(options))
|
53
|
+
end
|
54
|
+
|
55
|
+
def lookup(id, params={})
|
56
|
+
options = {
|
57
|
+
a_w_s_access_key_id: self.a_w_s_access_key_id,
|
58
|
+
a_w_s_secret_key: self.a_w_s_secret_key,
|
59
|
+
associate_tag: self.associate_tag,
|
60
|
+
|
61
|
+
operation: 'ItemLookup',
|
62
|
+
response_group: 'Large,EditorialReview,ItemAttributes',
|
63
|
+
item_id: id,
|
64
|
+
timestamp: Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
|
65
|
+
}
|
66
|
+
options.merge!(params)
|
67
|
+
|
68
|
+
ApiBucket::Amazon::Response.new(send_request(options))
|
69
|
+
end
|
70
|
+
|
71
|
+
include ApiBucket::Amazon::Client::Http
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module ApiBucket::Amazon
|
2
|
+
module Configuration
|
3
|
+
attr_accessor :a_w_s_access_key_id, :a_w_s_secret_key, :associate_tag
|
4
|
+
|
5
|
+
def configure
|
6
|
+
yield self
|
7
|
+
end
|
8
|
+
|
9
|
+
def options
|
10
|
+
[:a_w_s_access_key_id, :a_w_s_secret_key, :associate_tag].inject({}){|o,k| o.merge!(k => send(k))}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require "api_bucket/base/item"
|
3
|
+
require "api_bucket/base/element"
|
4
|
+
|
5
|
+
module ApiBucket::Amazon
|
6
|
+
class Item < ApiBucket::Base::Item
|
7
|
+
def initialize(element)
|
8
|
+
@element = ApiBucket::Base::Element.new(element)
|
9
|
+
|
10
|
+
@product_code = @element.get('ASIN')
|
11
|
+
@detail_url = @element.get('DetailPageURL')
|
12
|
+
|
13
|
+
# get item attributes element
|
14
|
+
item_attributes = @element.get_element('ItemAttributes')
|
15
|
+
|
16
|
+
# 最安値を優先的に格納する
|
17
|
+
offers = @element.get_element('Offers/Offer/OfferListing')
|
18
|
+
if @element.get('Offers/LowestNewPrice')
|
19
|
+
@price = @element.get('Offers/LowestNewPrice')
|
20
|
+
# ?????
|
21
|
+
#elsif offers.hash('Price')
|
22
|
+
# @price = offers.hash('Price')['Amount']
|
23
|
+
else
|
24
|
+
@price= item_attributes.get('ListPrice/Amount')
|
25
|
+
end
|
26
|
+
|
27
|
+
@release_date = item_attributes.get('ReleaseDate')
|
28
|
+
@title = item_attributes.get('Title')
|
29
|
+
|
30
|
+
# image
|
31
|
+
@image = {}
|
32
|
+
keys = {
|
33
|
+
l: 'LargeImage',
|
34
|
+
m: 'MediumImage',
|
35
|
+
s: 'SmallImage'
|
36
|
+
}
|
37
|
+
keys.each do |key, attr|
|
38
|
+
image = @element.get_element(attr)
|
39
|
+
if image
|
40
|
+
|
41
|
+
@image[key] = {
|
42
|
+
url: image.get('URL'),
|
43
|
+
width: image.get('Width'),
|
44
|
+
height: image.get('Height')
|
45
|
+
}
|
46
|
+
else
|
47
|
+
@image[key] = {
|
48
|
+
url: nil,
|
49
|
+
width: 0,
|
50
|
+
height: 0
|
51
|
+
}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
if @element.hash('Offers/Offer/OfferListing')
|
56
|
+
@availablity = @element.hash('Offers/Offer/OfferListing')['Availability']
|
57
|
+
end
|
58
|
+
|
59
|
+
editor_review = @element.get_element('EditorialReviews/EditorialReview')
|
60
|
+
@description = editor_review.get('Content') if editor_review
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "api_bucket/base/response"
|
2
|
+
|
3
|
+
module ApiBucket::Amazon
|
4
|
+
class Response < ApiBucket::Base::Response
|
5
|
+
def items
|
6
|
+
@items ||= (@doc/"Item").collect { |item| ApiBucket::Amazon::Item.new(item) }
|
7
|
+
end
|
8
|
+
|
9
|
+
def first_item
|
10
|
+
@items[0]
|
11
|
+
end
|
12
|
+
|
13
|
+
# Return current page no if :item_page option is when initiating the request.
|
14
|
+
def item_page
|
15
|
+
@item_page ||= ApiBucket::Base::Element.get(@doc, "//ItemPage").to_i
|
16
|
+
end
|
17
|
+
|
18
|
+
# Return total results.
|
19
|
+
def total_results
|
20
|
+
@total_results ||= ApiBucket::Base::Element.get(@doc, "//TotalResults").to_i
|
21
|
+
end
|
22
|
+
|
23
|
+
# Return total pages.
|
24
|
+
def total_pages
|
25
|
+
@total_pages ||= ApiBucket::Base::Element.get(@doc, "//TotalPages").to_i
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'api_bucket'
|
3
|
+
|
4
|
+
require "api_bucket/amazon/configration"
|
5
|
+
require "api_bucket/amazon/item"
|
6
|
+
require "api_bucket/amazon/response"
|
7
|
+
require "api_bucket/amazon/client"
|
8
|
+
|
9
|
+
# ApiBucket::Amazon
|
10
|
+
module ApiBucket::Amazon
|
11
|
+
extend Configuration
|
12
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module ApiBucket::Base
|
2
|
+
module Client
|
3
|
+
module Http
|
4
|
+
def send_request(options, url)
|
5
|
+
request_url = "#{url}?#{prepare_query(options)}"
|
6
|
+
|
7
|
+
res = nil
|
8
|
+
begin
|
9
|
+
res = open(request_url, {}) do |f|
|
10
|
+
@raw_response = f.read
|
11
|
+
JSON.parse(@raw_response)
|
12
|
+
end
|
13
|
+
rescue => e
|
14
|
+
#p "#{e.message} : #{request_url}"
|
15
|
+
end
|
16
|
+
|
17
|
+
res
|
18
|
+
end
|
19
|
+
|
20
|
+
def prepare_query(options)
|
21
|
+
query = ''
|
22
|
+
|
23
|
+
# sort to asc
|
24
|
+
options = options.sort do |c,d|
|
25
|
+
c[0].to_s <=> d[0].to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
# generate query_string from options
|
29
|
+
options.each do |key, value|
|
30
|
+
next if value.nil?
|
31
|
+
query << "&#{key}=#{URI.encode(value.to_s)}"
|
32
|
+
end
|
33
|
+
|
34
|
+
# sub string first charactor
|
35
|
+
query.slice!(0)
|
36
|
+
query
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module ApiBucket::Base
|
2
|
+
class Element
|
3
|
+
def initialize(e)
|
4
|
+
@element = e
|
5
|
+
end
|
6
|
+
|
7
|
+
def get(path)
|
8
|
+
return nil unless @element
|
9
|
+
result = @element.at_xpath(path)
|
10
|
+
result = result.inner_html if result
|
11
|
+
result
|
12
|
+
end
|
13
|
+
|
14
|
+
def /(elements, path)
|
15
|
+
items = self./(elements, path)
|
16
|
+
return nil if items.size = 0
|
17
|
+
items
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns a Nokogiri::XML::NodeSet of elements matching the given path.
|
21
|
+
# Example: element/"author".
|
22
|
+
def /(path)
|
23
|
+
elements = @element/path
|
24
|
+
return nil if elements.size == 0
|
25
|
+
elements
|
26
|
+
end
|
27
|
+
|
28
|
+
# Return an array of Amazon::Element matching the given path
|
29
|
+
def get_elements(path)
|
30
|
+
elements = self./(path)
|
31
|
+
return nil unless elements
|
32
|
+
elements = elements.map{|element| Element.new(element)}
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_element(path)
|
36
|
+
elements = self.get_elements(path)
|
37
|
+
elements[0] if elements
|
38
|
+
end
|
39
|
+
|
40
|
+
def hash(path='.')
|
41
|
+
return unless @element
|
42
|
+
|
43
|
+
result = @element.at_xpath(path)
|
44
|
+
if result
|
45
|
+
hash = {}
|
46
|
+
result = result.children
|
47
|
+
result.each do |item|
|
48
|
+
hash[item.name] = item.inner_html
|
49
|
+
end
|
50
|
+
hash
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module ApiBucket::Base
|
2
|
+
class Item
|
3
|
+
attr_accessor :product_code #:ASIN
|
4
|
+
attr_accessor :detail_url #:DetailPageURL
|
5
|
+
attr_accessor :preview_url #:PreviewURL
|
6
|
+
attr_accessor :price #:Amount
|
7
|
+
attr_accessor :title #:Title
|
8
|
+
attr_accessor :image
|
9
|
+
attr_accessor :image_l #:ImageL
|
10
|
+
attr_accessor :image_m #:ImageM
|
11
|
+
attr_accessor :image_s #:ImageS
|
12
|
+
attr_accessor :description #:Content
|
13
|
+
attr_accessor :release_date #:ReleaseDate
|
14
|
+
|
15
|
+
attr_accessor :availablity #:Availablity for amazon
|
16
|
+
|
17
|
+
def adult?
|
18
|
+
false
|
19
|
+
end
|
20
|
+
|
21
|
+
def hash_all
|
22
|
+
@image ||= {}
|
23
|
+
%w(l m s).collect {|size| @image[size] ||= {}}
|
24
|
+
{
|
25
|
+
product_code: @product_code,
|
26
|
+
detail_url: @detail_url,
|
27
|
+
preview_url: @preview_url,
|
28
|
+
price: @price,
|
29
|
+
title: @title,
|
30
|
+
image_l: @image[:l],
|
31
|
+
image_m: @image[:m],
|
32
|
+
image_s: @image[:s],
|
33
|
+
description: @description,
|
34
|
+
release_date: @release_date,
|
35
|
+
availablity: @availablity
|
36
|
+
}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "api_bucket/base/response"
|
2
|
+
|
3
|
+
module ApiBucket::Base
|
4
|
+
class Response
|
5
|
+
attr_accessor :page, :count
|
6
|
+
|
7
|
+
def initialize(xml)
|
8
|
+
@doc = Nokogiri::XML(xml, nil, 'UTF-8')
|
9
|
+
@doc.remove_namespaces!
|
10
|
+
end
|
11
|
+
|
12
|
+
def doc
|
13
|
+
@doc
|
14
|
+
end
|
15
|
+
|
16
|
+
def dump
|
17
|
+
@doc.to_s
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require "api_bucket/itunes/client/http"
|
2
|
+
|
3
|
+
module ApiBucket::Itunes
|
4
|
+
class Client
|
5
|
+
include ApiBucket::Itunes::Client::Http
|
6
|
+
|
7
|
+
attr_accessor :country, :limit
|
8
|
+
|
9
|
+
REQUEST_URL = 'http://itunes.apple.com/search'
|
10
|
+
REQUEST_URL_ITEM = 'http://itunes.apple.com/lookup'
|
11
|
+
|
12
|
+
def categories
|
13
|
+
{
|
14
|
+
all: 'All',
|
15
|
+
movie: 'Movie',
|
16
|
+
podcast: 'Podcast',
|
17
|
+
music: 'Music',
|
18
|
+
musicVideo: 'MusicVideo',
|
19
|
+
audiobook: 'Audiobook',
|
20
|
+
shortFilm: 'ShortFilm',
|
21
|
+
tvShow: 'TvShow',
|
22
|
+
software: 'Software',
|
23
|
+
ebook: 'Ebook',
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(options={})
|
28
|
+
options = ApiBucket::Itunes.options.merge(options)
|
29
|
+
self.country = options[:country] || 'JP'
|
30
|
+
self.limit = options[:limit] || 20
|
31
|
+
end
|
32
|
+
|
33
|
+
def search(keywords, params={})
|
34
|
+
options = {
|
35
|
+
limit: self.limit,
|
36
|
+
country: self.country,
|
37
|
+
media: params[:search_index],
|
38
|
+
term: keywords,
|
39
|
+
}
|
40
|
+
options.merge!(params)
|
41
|
+
|
42
|
+
# delete no needed keys
|
43
|
+
options.delete(:keywords)
|
44
|
+
options.delete(:search_index)
|
45
|
+
options[:media] = 'all' if options[:media].nil?
|
46
|
+
|
47
|
+
ApiBucket::Itunes::Response.new(send_request(options, REQUEST_URL))
|
48
|
+
end
|
49
|
+
|
50
|
+
# lookup
|
51
|
+
def lookup(id, params={})
|
52
|
+
options = {
|
53
|
+
country: self.country,
|
54
|
+
id: id,
|
55
|
+
}
|
56
|
+
options.merge!(params)
|
57
|
+
|
58
|
+
ApiBucket::Itunes::Response.new(send_request(options, REQUEST_URL_ITEM))
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|