rakuten_api 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +14 -0
- data/Guardfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +151 -0
- data/Rakefile +1 -0
- data/examples/show_ranking.rb +20 -0
- data/lib/rakuten_api/base/client.rb +41 -0
- data/lib/rakuten_api/base/item.rb +55 -0
- data/lib/rakuten_api/base/model.rb +41 -0
- data/lib/rakuten_api/base/params.rb +72 -0
- data/lib/rakuten_api/base/response.rb +39 -0
- data/lib/rakuten_api/configuration.rb +27 -0
- data/lib/rakuten_api/dummy_module.rb +6 -0
- data/lib/rakuten_api/error.rb +14 -0
- data/lib/rakuten_api/genre_search/client.rb +41 -0
- data/lib/rakuten_api/genre_search/model.rb +22 -0
- data/lib/rakuten_api/genre_search/response.rb +43 -0
- data/lib/rakuten_api/item_ranking/client.rb +29 -0
- data/lib/rakuten_api/item_ranking/model.rb +17 -0
- data/lib/rakuten_api/item_ranking/response.rb +57 -0
- data/lib/rakuten_api/item_search/client.rb +34 -0
- data/lib/rakuten_api/item_search/model.rb +15 -0
- data/lib/rakuten_api/item_search/response.rb +71 -0
- data/lib/rakuten_api/version.rb +3 -0
- data/lib/rakuten_api.rb +45 -0
- data/rakuten_api.gemspec +24 -0
- data/spec/fixtures/vcr_cassettes/genre_search_response.yml +75 -0
- data/spec/fixtures/vcr_cassettes/genre_search_response_0.yml +75 -0
- data/spec/fixtures/vcr_cassettes/genre_search_response_551169.yml +62 -0
- data/spec/fixtures/vcr_cassettes/genre_search_response_551172.yml +62 -0
- data/spec/fixtures/vcr_cassettes/item_ranking_error_response.yml +56 -0
- data/spec/fixtures/vcr_cassettes/item_ranking_response.yml +853 -0
- data/spec/fixtures/vcr_cassettes/item_ranking_response_next_ranking.yml +789 -0
- data/spec/fixtures/vcr_cassettes/item_ranking_response_prev_ranking.yml +853 -0
- data/spec/fixtures/vcr_cassettes/item_search_response.yml +116 -0
- data/spec/fixtures/vcr_cassettes/item_search_response_next_page.yml +89 -0
- data/spec/fixtures/vcr_cassettes/item_search_response_prev_page.yml +107 -0
- data/spec/rakuten_api/base/params_spec.rb +42 -0
- data/spec/rakuten_api/genre_search/client_spec.rb +37 -0
- data/spec/rakuten_api/genre_search/model_spec.rb +32 -0
- data/spec/rakuten_api/genre_search/response_spec.rb +47 -0
- data/spec/rakuten_api/item_ranking/client_spec.rb +19 -0
- data/spec/rakuten_api/item_ranking/model_spec.rb +19 -0
- data/spec/rakuten_api/item_ranking/response_spec.rb +64 -0
- data/spec/rakuten_api/item_search/client_spec.rb +35 -0
- data/spec/rakuten_api/item_search/model_spec.rb +33 -0
- data/spec/rakuten_api/item_search/response_spec.rb +73 -0
- data/spec/spec_helper.rb +34 -0
- metadata +181 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in rakuten_api.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :development, :test do
|
7
|
+
gem 'tapp', git: 'git://github.com/esminc/tapp.git'
|
8
|
+
gem 'guard'
|
9
|
+
gem 'guard-rspec'
|
10
|
+
gem 'libnotify', require: false
|
11
|
+
gem 'rb-inotify', require: false
|
12
|
+
gem 'rb-fsevent', require: false
|
13
|
+
gem 'growl', require: false
|
14
|
+
end
|
data/Guardfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 kengos
|
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,151 @@
|
|
1
|
+
# RakutenApi
|
2
|
+
|
3
|
+
楽天ウェブサービス(http://webservice.rakuten.co.jp/) のAPIクライアントです。
|
4
|
+
|
5
|
+
以下のAPIに対応しています。
|
6
|
+
|
7
|
+
- [楽天商品検索API2](http://webservice.rakuten.co.jp/api/ichibaitemsearch/) (version:2012-07-23)
|
8
|
+
- [楽天ジャンル検索API2](https://webservice.rakuten.co.jp/api/ichibagenresearch/) (version:2012-07-23)
|
9
|
+
- [未実装] [楽天商品ランキングAPI2](https://webservice.rakuten.co.jp/api/ichibaitemranking/) (version:2012-09-27)
|
10
|
+
|
11
|
+
## Supported Ruby Interpreters
|
12
|
+
|
13
|
+
* MRI 1.9.3
|
14
|
+
|
15
|
+
## Installation
|
16
|
+
|
17
|
+
Add this line to your application's Gemfile:
|
18
|
+
|
19
|
+
gem 'rakuten_api'
|
20
|
+
|
21
|
+
And then execute:
|
22
|
+
|
23
|
+
$ bundle
|
24
|
+
|
25
|
+
Or install it yourself as:
|
26
|
+
|
27
|
+
$ gem install rakuten_api
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
|
31
|
+
### 共通設定
|
32
|
+
|
33
|
+
どこでもいいので、以下を追加します。
|
34
|
+
|
35
|
+
Railsアプリケーション等の場合は、initializer等に登録してください。
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
RakutenApi.configure do |config|
|
39
|
+
config.application_id = "[applicationId]"
|
40
|
+
config.affiliate_id = "[affiliateId]"
|
41
|
+
end
|
42
|
+
```
|
43
|
+
|
44
|
+
### 商品検索API 2
|
45
|
+
|
46
|
+
* keyword: 'りんご', hits: '2'(2商品だけ表示)での検索
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
client = RakutenApi::GenreSearch::Client.new do |params|
|
50
|
+
params.add_param :keyword, 'りんご'
|
51
|
+
params.add_param :hits, 2
|
52
|
+
end
|
53
|
+
|
54
|
+
response = client.request
|
55
|
+
|
56
|
+
p response.status # => 200
|
57
|
+
p response.body # => APIのレスポンスBodyをJSONデコードした値が入っている
|
58
|
+
p response.page_count # => 100 (取得可能なページ数)(この場合は100まで指定可能を意味する)
|
59
|
+
p response.page # => 1 (現在のページ番号)
|
60
|
+
p response.carrier # => 0 (キャリア) (0: PC, 1: 携帯, 2: スマートフォン)
|
61
|
+
p response.first # => 1 (現在の表示商品始)(1つめを意味する)
|
62
|
+
p response.last # => 2 (現在の表示商品終)(2つめを意味する)
|
63
|
+
p response.simple_mapping
|
64
|
+
# => [
|
65
|
+
# #<RakutenApi::ItemSearch::Model:0x007fcb6cd6a350 @item_name="グルメ大賞2010 青森県産 りんご サンふじ...略", @catchcopy="【送料無料】りんご 青森産 サンふじ...略" @item_url="http://item.rakuten.co.jp/cameashi/10000323/", @affiliate_url="", @small_image_urls=["http://thumbnail.image.rakuten.co.jp/@0_mall/cameashi/cabinet/00473472/2012fuji-f5kgb.jpg?_ex=64x64", "http://thumbnail.image.rakuten.co.jp/@0_mall/cameashi/cabinet/00473472/img58491689.jpg?_ex=64x64", "http://thumbnail.image.rakuten.co.jp/@0_mall/cameashi/cabinet/00473472/img55339932.gif?_ex=64x64"], @medium_image_urls=["http://thumbnail.image.rakuten.co.jp/@0_mall/cameashi/cabinet/00473472/2012fuji-f5kgb.jpg?_ex=128x128", "http://thumbnail.image.rakuten.co.jp/@0_mall/cameashi/cabinet/00473472/img58491689.jpg?_ex=128x128", "http://thumbnail.image.rakuten.co.jp/@0_mall/cameashi/cabinet/00473472/img55339932.gif?_ex=128x128"], @image_flag=true, @availability=true, @tax_flag=false, @postage_flag=false, @creadit_card_flag=true, @shop_of_the_year_flag=false, @ship_overseas_flag=false, @asuraku_flag=false, @gift_flag=false, @ship_overseas_area="", @asuraku_closing_time="", @asuraku_area="", @affiliate_rate=1, @start_time="", @end_time="", @review_count=2371, @review_average=4.4, @point_rate=1, @point_rate_start_time="", @point_rate_end_time="", @shop_name="かめあし商店", @shop_code="cameashi", @shop_url="http://www.rakuten.co.jp/cameashi/", @genre_id="304637">
|
66
|
+
# ...
|
67
|
+
# ]
|
68
|
+
```
|
69
|
+
|
70
|
+
`simple_mapping`を呼び出すと、
|
71
|
+
|
72
|
+
[RakutenApi::ItemSearch::Model](https://github.com/kengos/rakuten_api/blob/master/lib/rakuten_api/item_search/model.rb) の配列で返却されます。
|
73
|
+
|
74
|
+
|
75
|
+
### add_param について
|
76
|
+
|
77
|
+
楽天WebService上で表記されている`genreId`を指定する場合
|
78
|
+
|
79
|
+
以下は全て同じパラメータを指定していることになる。
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
params.add_param :genre_id, 0
|
83
|
+
params.add_param :genreId, 0
|
84
|
+
params.add_param 'genre_id', 0
|
85
|
+
params.add_param 'genreId', 0
|
86
|
+
```
|
87
|
+
|
88
|
+
### ジャンル検索API 2
|
89
|
+
|
90
|
+
* genre_id: 0での検索
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
client = RakutenApi::GenreSearch::Client.new do |params|
|
94
|
+
params.add_param :genre_id, 0
|
95
|
+
end
|
96
|
+
|
97
|
+
response = client.request
|
98
|
+
p response.current
|
99
|
+
# => #<RakutenApi::GenreSearch::Model:0x007f956aba3fb8 @genre_id=0, @genre_name="", @genre_level=0>
|
100
|
+
|
101
|
+
p response.parents
|
102
|
+
# => []
|
103
|
+
|
104
|
+
p response.children
|
105
|
+
# => [
|
106
|
+
# #<RakutenApi::GenreSearch::Model:0x007f956aba1ec0 @genre_id=211742, @genre_name="TV・オーディオ・カメラ", @genre_level=1>,
|
107
|
+
# #<RakutenApi::GenreSearch::Model:0x007f956abcb360 @genre_id=100371, @genre_name="レディースファッション", @genre_level=1>,
|
108
|
+
# ...
|
109
|
+
# ]
|
110
|
+
```
|
111
|
+
|
112
|
+
* genre_id: 551172での(genreLevel: 2)検索
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
client = RakutenApi::GenreSearch::Client.new do |params|
|
116
|
+
params.add_param :genre_id, 551172
|
117
|
+
end
|
118
|
+
|
119
|
+
response = client.request
|
120
|
+
p response.current
|
121
|
+
# => <RakutenApi::GenreSearch::Model:0x007fe1a39a28b0 @genre_id=551172, @genre_name="医療計測器", @genre_level=2>
|
122
|
+
|
123
|
+
p response.parents
|
124
|
+
# => [#<RakutenApi::GenreSearch::Model:0x007fe1a39a2540 @genre_id=551169, @genre_name="医薬品・コンタクト・介護", @genre_level=1>]
|
125
|
+
|
126
|
+
p response.children
|
127
|
+
# => [
|
128
|
+
# #<RakutenApi::GenreSearch::Model:0x007fe1a39a21a8 @genre_id=208232, @genre_name="塩素計", @genre_level=3>,
|
129
|
+
# #<RakutenApi::GenreSearch::Model:0x007fe1a39a1fc8 @genre_id=551173, @genre_name="その他", @genre_level=3>,
|
130
|
+
# ...
|
131
|
+
# ]
|
132
|
+
#
|
133
|
+
```
|
134
|
+
|
135
|
+
## Dependencies
|
136
|
+
|
137
|
+
* [faraday](https://github.com/lostisland/faraday)
|
138
|
+
|
139
|
+
### Development dependencies
|
140
|
+
|
141
|
+
* [rspec](https://github.com/rspec)
|
142
|
+
* [vcr](https://github.com/vcr/vcr)
|
143
|
+
* [webmock](https://github.com/bblimke/webmock)
|
144
|
+
|
145
|
+
## Contributing
|
146
|
+
|
147
|
+
1. Fork it
|
148
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
149
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
150
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
151
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
# You need
|
4
|
+
# gem install rakuten_api
|
5
|
+
# gem install faraday
|
6
|
+
|
7
|
+
require 'rakuten_api'
|
8
|
+
require 'faraday'
|
9
|
+
|
10
|
+
RakutenApi.configure do |config|
|
11
|
+
config.application_id = "[Your application_id]"
|
12
|
+
end
|
13
|
+
|
14
|
+
client = RakutenApi::ItemRanking::Client.new
|
15
|
+
response = client.request
|
16
|
+
|
17
|
+
response.simple_mapping.each do |f|
|
18
|
+
# you need another parameters, see: https://webservice.rakuten.co.jp/api/ichibaitemranking/
|
19
|
+
puts f.rank.to_s + ' ' + f.item_name + "\n"
|
20
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module RakutenApi::Base
|
4
|
+
class Client
|
5
|
+
def initialize(application_id = nil, affiliate_id = nil)
|
6
|
+
init_params(application_id, affiliate_id)
|
7
|
+
yield @params if block_given?
|
8
|
+
end
|
9
|
+
|
10
|
+
def init_params(application_id, affiliate_id)
|
11
|
+
raise "not implement"
|
12
|
+
end
|
13
|
+
|
14
|
+
def get
|
15
|
+
raise "not implement"
|
16
|
+
end
|
17
|
+
|
18
|
+
def request
|
19
|
+
raise "not implement"
|
20
|
+
end
|
21
|
+
|
22
|
+
def connection
|
23
|
+
@connection ||= new_connection
|
24
|
+
end
|
25
|
+
|
26
|
+
def params
|
27
|
+
@params.to_hash
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_param(name, value)
|
31
|
+
@params[name] = value
|
32
|
+
end
|
33
|
+
|
34
|
+
def new_connection
|
35
|
+
::Faraday.new(url: ::RakutenApi::APPLICATION_END_POINT) do |faraday|
|
36
|
+
faraday.request :url_encoded
|
37
|
+
faraday.adapter Faraday.default_adapter
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module RakutenApi::Base
|
4
|
+
module Item
|
5
|
+
ITEM_CASTING = {
|
6
|
+
'smallImageUrls' => Proc.new{|o| o.map{|v| v["imageUrl"]}},
|
7
|
+
'mediumImageUrls' => Proc.new{|o| o.map{|v| v["imageUrl"]}},
|
8
|
+
'imageFlag' => Proc.new{|o| o == 1},
|
9
|
+
'availability' => Proc.new{|o| o == 1},
|
10
|
+
'taxFlag' => Proc.new{|o| o == 1},
|
11
|
+
'postageFlag' => Proc.new{|o| o == 1},
|
12
|
+
'creditCardFlag' => Proc.new{|o| o == 1},
|
13
|
+
'shopOfTheYearFlag' => Proc.new{|o| o == 1},
|
14
|
+
'shipOverseasFlag' => Proc.new{|o| o == 1},
|
15
|
+
'asurakuFlag' => Proc.new{|o| o == 1},
|
16
|
+
'giftFlag' => Proc.new{|o| o == 1},
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
attr_accessor :item_name
|
20
|
+
attr_accessor :catchcopy
|
21
|
+
attr_accessor :item_code
|
22
|
+
attr_accessor :item_price
|
23
|
+
attr_accessor :item_caption
|
24
|
+
attr_accessor :item_url
|
25
|
+
attr_accessor :affiliate_url
|
26
|
+
attr_accessor :small_image_urls
|
27
|
+
attr_accessor :medium_image_urls
|
28
|
+
|
29
|
+
attr_accessor :availability
|
30
|
+
attr_accessor :image_flag
|
31
|
+
attr_accessor :tax_flag
|
32
|
+
attr_accessor :postage_flag
|
33
|
+
attr_accessor :credit_card_flag
|
34
|
+
attr_accessor :shop_of_the_year_flag
|
35
|
+
attr_accessor :ship_overseas_flag
|
36
|
+
attr_accessor :asuraku_flag
|
37
|
+
attr_accessor :gift_flag
|
38
|
+
|
39
|
+
attr_accessor :ship_overseas_area
|
40
|
+
attr_accessor :asuraku_closing_time
|
41
|
+
attr_accessor :asuraku_area
|
42
|
+
attr_accessor :affiliate_rate
|
43
|
+
attr_accessor :start_time
|
44
|
+
attr_accessor :end_time
|
45
|
+
attr_accessor :review_count
|
46
|
+
attr_accessor :review_average
|
47
|
+
attr_accessor :point_rate
|
48
|
+
attr_accessor :point_rate_start_time
|
49
|
+
attr_accessor :point_rate_end_time
|
50
|
+
attr_accessor :shop_name
|
51
|
+
attr_accessor :shop_code
|
52
|
+
attr_accessor :shop_url
|
53
|
+
attr_accessor :genre_id
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module RakutenApi::Base
|
4
|
+
class Model
|
5
|
+
def to_hash
|
6
|
+
{}.tap do |h|
|
7
|
+
instance_variables.each do |sym|
|
8
|
+
h[sym.to_s.sub('@', '').to_sym] = instance_variable_get(sym)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def from_hash(hash)
|
15
|
+
obj = self.new
|
16
|
+
hash.each_pair do |k, v|
|
17
|
+
v = casting[k].call(v) if casting.include?(k)
|
18
|
+
attribute = mapping.include?(k) ? mapping[k] : downcase(k)
|
19
|
+
obj.send("#{attribute}=", v) if obj.respond_to?("#{attribute}=")
|
20
|
+
end
|
21
|
+
obj
|
22
|
+
end
|
23
|
+
|
24
|
+
def downcase(word)
|
25
|
+
_word = word.dup
|
26
|
+
_word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
|
27
|
+
_word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
28
|
+
_word.downcase!
|
29
|
+
_word
|
30
|
+
end
|
31
|
+
|
32
|
+
def mapping
|
33
|
+
{}
|
34
|
+
end
|
35
|
+
|
36
|
+
def casting
|
37
|
+
{}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module RakutenApi::Base
|
4
|
+
class Params
|
5
|
+
BASE_VALID_NAMES = %w(applicationId affiliateId).freeze
|
6
|
+
attr_accessor :invalid_params_action
|
7
|
+
|
8
|
+
# Initialize
|
9
|
+
# @param [String] application_id Rakuten Web Service applicationId
|
10
|
+
# If application_id is nil, application_id set to RakutenApi.config.application_id
|
11
|
+
# @param [String] affiliate_id Rakuten Web Service affiliateId
|
12
|
+
# If affiliate_id is nil, affiliate_id set to RakutenApi.config.affiliate_id
|
13
|
+
# @param [Symbol] invalid_params_action :raise or :stdout or :none
|
14
|
+
# If invalid_params_action is nil, invalid_params_action set to RakutenApi.config.invalid_params_action
|
15
|
+
def initialize(application_id = nil, affiliate_id = nil, invalid_params_action = nil)
|
16
|
+
init_params application_id || RakutenApi.config.application_id, affiliate_id || RakutenApi.config.affiliate_id
|
17
|
+
@invalid_params_action = invalid_params_action || RakutenApi.config.invalid_params_action
|
18
|
+
end
|
19
|
+
|
20
|
+
def init_params(application_id, affiliate_id)
|
21
|
+
@params = {}
|
22
|
+
add_param('applicationId', application_id)
|
23
|
+
add_param('affiliateId', affiliate_id)
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_param(name, value)
|
27
|
+
_name = normalize(name)
|
28
|
+
if valid_name?(_name)
|
29
|
+
@params[_name] = value
|
30
|
+
else
|
31
|
+
if @invalid_params_action == :raise
|
32
|
+
raise ::RakutenApi::Error.new('passed invalid param: ' + name.to_s)
|
33
|
+
elsif @invalid_params_action == :stdout
|
34
|
+
puts "Warning: " + name.to_s + ' is invalid name'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def inspect
|
40
|
+
@params
|
41
|
+
end
|
42
|
+
|
43
|
+
def [](name)
|
44
|
+
_name = normalize(name)
|
45
|
+
@params[_name]
|
46
|
+
end
|
47
|
+
|
48
|
+
def []=(name, value)
|
49
|
+
add_param(name, value)
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_hash
|
53
|
+
@params ||= {}
|
54
|
+
@params.reject!{|k,v| v.nil? }
|
55
|
+
@params
|
56
|
+
end
|
57
|
+
|
58
|
+
def valid_name?(name)
|
59
|
+
valid_names.include? name
|
60
|
+
end
|
61
|
+
|
62
|
+
def normalize(name)
|
63
|
+
name = name.to_s
|
64
|
+
name = name.split('_').tap{|names| break names.shift + names.map(&:capitalize).join } if name =~ /.+\_.+/
|
65
|
+
name
|
66
|
+
end
|
67
|
+
|
68
|
+
def valid_names
|
69
|
+
BASE_VALID_NAMES
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module RakutenApi::Base
|
4
|
+
class Response
|
5
|
+
attr_reader :status
|
6
|
+
attr_reader :body
|
7
|
+
|
8
|
+
def initialize(faraday_response = nil)
|
9
|
+
raise RakutenApi::Error.new('not specified Faraday::Response') if !faraday_response.nil? && !faraday_response.kind_of?(::Faraday::Response)
|
10
|
+
@status = faraday_response.status
|
11
|
+
@body = json_parse(faraday_response.body)
|
12
|
+
end
|
13
|
+
|
14
|
+
def success?
|
15
|
+
@status == 200
|
16
|
+
end
|
17
|
+
|
18
|
+
def error?
|
19
|
+
!success?
|
20
|
+
end
|
21
|
+
|
22
|
+
def error_message
|
23
|
+
nil if success?
|
24
|
+
message = ''
|
25
|
+
message += @body['error'] + ': ' if @body.include? 'error'
|
26
|
+
message += @body['error_description'] if @body.include? 'error_description'
|
27
|
+
message == '' ? 'no error message' : message;
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
def json_parse(data)
|
33
|
+
JSON.parse(data)
|
34
|
+
rescue JSON::ParserError
|
35
|
+
# @todo logger
|
36
|
+
{}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module RakutenApi
|
4
|
+
class Configuration
|
5
|
+
# rakuten application_id (You can get from https://webservice.rakuten.co.jp/app/create)
|
6
|
+
attr_accessor :application_id
|
7
|
+
# rakuten affiliate_id
|
8
|
+
attr_accessor :affiliate_id
|
9
|
+
# behavior when passed an invalid params
|
10
|
+
attr_accessor :invalid_params_action
|
11
|
+
# RakutenApi::GenreSearch::Model include Module
|
12
|
+
attr_accessor :genre_model
|
13
|
+
# RakutenApi::ItemSearch::Model include Module
|
14
|
+
attr_accessor :item_model
|
15
|
+
# RakutenApi::ItemRanking::Model include Module
|
16
|
+
attr_accessor :item_ranking_module
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
@application_id = nil
|
20
|
+
@affiliate_id = nil
|
21
|
+
@invalid_params_action = :stdout
|
22
|
+
@genre_model = 'RakutenApi::DummyModule'
|
23
|
+
@item_model = 'RakutenApi::DummyModule'
|
24
|
+
@item_ranking_module = 'RakutenApi::DummyModule'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module RakutenApi
|
4
|
+
module GenreSearch
|
5
|
+
class Client < RakutenApi::Base::Client
|
6
|
+
REQUEST_PATH = "/services/api/IchibaGenre/Search/20120723"
|
7
|
+
|
8
|
+
def get
|
9
|
+
connection.get(REQUEST_PATH, params)
|
10
|
+
end
|
11
|
+
|
12
|
+
def request
|
13
|
+
Response.new(get)
|
14
|
+
end
|
15
|
+
|
16
|
+
# get rakuten root genres
|
17
|
+
# @param [String] application_id
|
18
|
+
# @param [String] affiliate_id
|
19
|
+
# @return [Array<RakutenApi::GenreSearch::Model>]
|
20
|
+
def self.root_categories(application_id = nil, affiliate_id = nil)
|
21
|
+
response = self.new(application_id, affiliate_id) do |params|
|
22
|
+
params.add_param :genre_id, 0
|
23
|
+
end.request
|
24
|
+
raise ::RakutenApi::ServerError.new($response.error_message, $response.status) if response.error?
|
25
|
+
response.children
|
26
|
+
end
|
27
|
+
|
28
|
+
def init_params(application_id, affiliate_id)
|
29
|
+
@params = Params.new(application_id, affiliate_id)
|
30
|
+
end
|
31
|
+
|
32
|
+
class Params < ::RakutenApi::Base::Params
|
33
|
+
VALID_NAMES = %w(genreId genrePath).freeze
|
34
|
+
|
35
|
+
def valid_names
|
36
|
+
@@valid_names ||= (VALID_NAMES + BASE_VALID_NAMES).freeze
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module RakutenApi
|
4
|
+
module GenreSearch
|
5
|
+
class Model < ::RakutenApi::Base::Model
|
6
|
+
include RakutenApi.constantize 'genre_model'
|
7
|
+
|
8
|
+
GENRE_SEARCH_CASTING = {
|
9
|
+
"genreId" => Proc.new{|o| o.to_i},
|
10
|
+
'genreLevel' => Proc.new{|o| o.to_i}
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
attr_accessor :genre_id
|
14
|
+
attr_accessor :genre_name
|
15
|
+
attr_accessor :genre_level
|
16
|
+
|
17
|
+
def self.casting
|
18
|
+
GENRE_SEARCH_CASTING
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module RakutenApi
|
4
|
+
module GenreSearch
|
5
|
+
class Response < ::RakutenApi::Base::Response
|
6
|
+
def initialize(faraday_response = nil)
|
7
|
+
super(faraday_response)
|
8
|
+
end
|
9
|
+
|
10
|
+
def cache
|
11
|
+
@cache ||= {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def parents
|
15
|
+
return cache['parents'] if cache.include? 'parents'
|
16
|
+
[] unless @body.include? 'parents'
|
17
|
+
cache['parents'] = [].tap do |result|
|
18
|
+
@body['parents'].each do |f|
|
19
|
+
next unless f.include? 'parent'
|
20
|
+
result << Model.from_hash(f['parent'])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def current
|
26
|
+
return cache['current'] if cache.include? 'current'
|
27
|
+
return Model.new unless @body.include? "current"
|
28
|
+
cache['current'] = Model.from_hash(@body['current'])
|
29
|
+
end
|
30
|
+
|
31
|
+
def children
|
32
|
+
return cache['children'] if cache.include? 'children'
|
33
|
+
[] unless @body.include? "children"
|
34
|
+
cache['children'] = [].tap do |result|
|
35
|
+
@body["children"].each do |f|
|
36
|
+
next unless f.include? 'child'
|
37
|
+
result << Model.from_hash(f['child'])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module RakutenApi
|
4
|
+
module ItemRanking
|
5
|
+
class Client < ::RakutenApi::Base::Client
|
6
|
+
REQUEST_PATH = "/services/api/IchibaItem/Ranking/20120927"
|
7
|
+
|
8
|
+
def get
|
9
|
+
connection.get(REQUEST_PATH, params)
|
10
|
+
end
|
11
|
+
|
12
|
+
def request
|
13
|
+
Response.new(get, params.clone)
|
14
|
+
end
|
15
|
+
|
16
|
+
def init_params(application_id, affiliate_id)
|
17
|
+
@params = Params.new(application_id, affiliate_id)
|
18
|
+
end
|
19
|
+
|
20
|
+
class Params < ::RakutenApi::Base::Params
|
21
|
+
VALID_NAMES = %w(genreId age sex carrier page period).freeze
|
22
|
+
|
23
|
+
def valid_names
|
24
|
+
@@valid_names ||= (VALID_NAMES + BASE_VALID_NAMES).freeze
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|