rakuten_api 0.1.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/.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
|