rakuten_web_service 1.10.0 → 1.13.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +12 -0
- data/.github/workflows/ci.yml +30 -0
- data/CHANGELOG.md +103 -48
- data/Gemfile +3 -3
- data/README.ja.md +118 -48
- data/README.md +35 -10
- data/examples/ichiba_item_search.rb +1 -1
- data/examples/recipe_search.rb +16 -0
- data/lib/rakuten_web_service/all_proxy.rb +2 -1
- data/lib/rakuten_web_service/books/genre.rb +1 -1
- data/lib/rakuten_web_service/books/resource.rb +1 -1
- data/lib/rakuten_web_service/books/total.rb +1 -1
- data/lib/rakuten_web_service/client.rb +9 -9
- data/lib/rakuten_web_service/configuration.rb +0 -16
- data/lib/rakuten_web_service/error.rb +5 -0
- data/lib/rakuten_web_service/genre.rb +1 -1
- data/lib/rakuten_web_service/gora/course.rb +1 -1
- data/lib/rakuten_web_service/gora/course_detail.rb +1 -1
- data/lib/rakuten_web_service/gora/plan.rb +1 -1
- data/lib/rakuten_web_service/ichiba/item.rb +3 -3
- data/lib/rakuten_web_service/ichiba/product.rb +1 -1
- data/lib/rakuten_web_service/ichiba/ranking.rb +1 -1
- data/lib/rakuten_web_service/ichiba/tag.rb +16 -0
- data/lib/rakuten_web_service/ichiba/tag_group.rb +23 -0
- data/lib/rakuten_web_service/ichiba.rb +2 -0
- data/lib/rakuten_web_service/kobo/ebook.rb +1 -1
- data/lib/rakuten_web_service/kobo/genre.rb +1 -1
- data/lib/rakuten_web_service/recipe/category.rb +3 -1
- data/lib/rakuten_web_service/recipe.rb +1 -1
- data/lib/rakuten_web_service/resource.rb +29 -20
- data/lib/rakuten_web_service/response.rb +5 -4
- data/lib/rakuten_web_service/search_result.rb +14 -15
- data/lib/rakuten_web_service/travel/area_class.rb +30 -29
- data/lib/rakuten_web_service/travel/hotel.rb +3 -1
- data/lib/rakuten_web_service/travel/search_result.rb +1 -1
- data/lib/rakuten_web_service/version.rb +1 -1
- data/lib/rakuten_web_service.rb +17 -1
- data/rakuten_web_service.gemspec +6 -4
- data/spec/fixtures/ichiba/item_search_with_no_items.json +8 -0
- data/spec/fixtures/ichiba/tag_search.json +15 -0
- data/spec/rakuten_web_service/configuration_spec.rb +0 -52
- data/spec/rakuten_web_service/genre_spec.rb +1 -1
- data/spec/rakuten_web_service/ichiba/item_spec.rb +13 -0
- data/spec/rakuten_web_service/ichiba/tag_group_spec.rb +68 -0
- data/spec/rakuten_web_service/ichiba/tag_spec.rb +35 -0
- data/spec/rakuten_web_service/resource_spec.rb +2 -2
- data/spec/rakuten_web_service/response_spec.rb +7 -7
- data/spec/rakuten_web_service/travel/search_result_spec.rb +4 -4
- data/spec/rakuten_web_service_spec.rb +48 -0
- metadata +56 -16
- data/.travis.yml +0 -46
- data/spec/integration/integration_spec.rb +0 -78
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# RakutenWebService
|
2
|
-
|
2
|
+
[![CI](https://github.com/rakuten-ws/rws-ruby-sdk/workflows/CI/badge.svg)](https://github.com/rakuten-ws/rws-ruby-sdk/actions?query=workflow%3ACI+branch%3Amaster)
|
3
3
|
[![Build Status](https://travis-ci.org/rakuten-ws/rws-ruby-sdk.svg?branch=master)](https://travis-ci.org/rakuten-ws/rws-ruby-sdk)
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/rakuten_web_service.svg)](https://badge.fury.io/rb/rakuten_web_service)
|
5
5
|
[![Test Coverage](https://codeclimate.com/github/rakuten-ws/rws-ruby-sdk/badges/coverage.svg)](https://codeclimate.com/github/rakuten-ws/rws-ruby-sdk/coverage)
|
@@ -8,6 +8,8 @@
|
|
8
8
|
|
9
9
|
This gem provides a client for easily accessing [Rakuten Web Service APIs](https://webservice.rakuten.co.jp/).
|
10
10
|
|
11
|
+
日本語のドキュメントは[こちら](http://github.com/rakuten-ws/rws-ruby-sdk/blob/master/README.ja.md)。
|
12
|
+
|
11
13
|
## Table of Contents
|
12
14
|
|
13
15
|
* [Prerequisite](#prerequisite)
|
@@ -30,23 +32,27 @@ This gem provides a client for easily accessing [Rakuten Web Service APIs](https
|
|
30
32
|
|
31
33
|
## Prerequisite
|
32
34
|
|
33
|
-
* Ruby 2.
|
35
|
+
* Ruby 2.5 or later
|
34
36
|
|
35
37
|
## Installation
|
36
38
|
|
37
39
|
Add this line to your application's Gemfile:
|
38
40
|
|
39
41
|
```ruby
|
40
|
-
|
42
|
+
gem 'rakuten_web_service'
|
41
43
|
```
|
42
44
|
|
43
45
|
And then execute:
|
44
46
|
|
45
|
-
|
47
|
+
```sh
|
48
|
+
bundle
|
49
|
+
```
|
46
50
|
|
47
51
|
Or install it yourself as:
|
48
52
|
|
49
|
-
|
53
|
+
```sh
|
54
|
+
gem install rakuten_web_service
|
55
|
+
```
|
50
56
|
|
51
57
|
## Usage
|
52
58
|
|
@@ -57,12 +63,12 @@ If you have not got it, register your application [here](https://webservice.raku
|
|
57
63
|
|
58
64
|
### Configuration
|
59
65
|
|
60
|
-
At first, you have to specify your application's key. And you can tell the client your afiiliate id with `RakutenWebService.
|
66
|
+
At first, you have to specify your application's key. And you can tell the client your afiiliate id with `RakutenWebService.configure`.
|
61
67
|
|
62
68
|
#### In Your Code
|
63
69
|
|
64
70
|
```ruby
|
65
|
-
RakutenWebService.
|
71
|
+
RakutenWebService.configure do |c|
|
66
72
|
# (Required) Appliction ID for your application.
|
67
73
|
c.application_id = 'YOUR_APPLICATION_ID'
|
68
74
|
|
@@ -107,7 +113,7 @@ Responses of resources' `search` such as `RakutenWebService::Ichiba::Item.search
|
|
107
113
|
last_items = items.page(3) # Skips first 2 pages.
|
108
114
|
|
109
115
|
# Go to the last page
|
110
|
-
while last_items.
|
116
|
+
while last_items.next_page?
|
111
117
|
last_items = last_items.next_page
|
112
118
|
end
|
113
119
|
|
@@ -143,12 +149,30 @@ Genre class provides an interface to traverse sub genres.
|
|
143
149
|
ranking_by_age = RakutenWebService::Ichiba::Item.ranking(age: 30, sex: 1) # returns the TOP 30 items for Male in 30s
|
144
150
|
# For attributes other than 'itemName', see: http://webservice.rakuten.co.jp/api/ichibaitemsearch/#outputParameter
|
145
151
|
ranking_by_age.each do |ranking|
|
146
|
-
puts
|
152
|
+
puts item.name
|
147
153
|
end
|
148
154
|
|
149
155
|
ranking_by_genre = RakutenWebService::Ichiba::Genre[200162].ranking # the TOP 30 items in "水・ソフトドリンク" genre
|
150
156
|
ranking_by_genre.each do |ranking|
|
151
|
-
puts
|
157
|
+
puts item.name
|
158
|
+
end
|
159
|
+
```
|
160
|
+
|
161
|
+
### Recipe
|
162
|
+
|
163
|
+
```ruby
|
164
|
+
categories = RakutenWebService::Recipe.small_categories
|
165
|
+
|
166
|
+
# Search all small recipe categories.
|
167
|
+
categories.each do |category|
|
168
|
+
category.name
|
169
|
+
end
|
170
|
+
|
171
|
+
recipes = categories.first.ranking
|
172
|
+
|
173
|
+
# Search category recipes.
|
174
|
+
recipes.each do |recipe|
|
175
|
+
recipe.title
|
152
176
|
end
|
153
177
|
```
|
154
178
|
|
@@ -162,6 +186,7 @@ Now rakuten\_web\_service is supporting the following APIs:
|
|
162
186
|
* [Rakuten Ichiba Genre Search API](http://webservice.rakuten.co.jp/api/ichibagenresearch/)
|
163
187
|
* [Rakuten Ichiba Ranking API](http://webservice.rakuten.co.jp/api/ichibaitemranking/)
|
164
188
|
* [Rakuten Product API](http://webservice.rakuten.co.jp/api/productsearch/)
|
189
|
+
* [Rakuten Ichiba Tag Search API](https://webservice.rakuten.co.jp/api/ichibatagsearch/)
|
165
190
|
|
166
191
|
### Rakuten Books APIs
|
167
192
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rakuten_web_service'
|
2
|
+
|
3
|
+
application_id = ARGV.shift
|
4
|
+
keyword = ARGV[0..-1].join(' ')
|
5
|
+
|
6
|
+
RakutenWebService.configure do |c|
|
7
|
+
c.application_id = application_id
|
8
|
+
end
|
9
|
+
|
10
|
+
category = RakutenWebService::Recipe.small_categories.find { |c| c.name.match(keyword) }
|
11
|
+
|
12
|
+
recipes = category.ranking
|
13
|
+
|
14
|
+
recipes.first(10).each do |recipe|
|
15
|
+
puts "#{recipe.title} is made by #{recipe.nickname}"
|
16
|
+
end
|
@@ -5,7 +5,7 @@ require 'rakuten_web_service/genre'
|
|
5
5
|
module RakutenWebService
|
6
6
|
module Books
|
7
7
|
class Genre < RakutenWebService::BaseGenre
|
8
|
-
|
8
|
+
self.resource_name = 'books_genre'
|
9
9
|
|
10
10
|
endpoint 'https://app.rakuten.co.jp/services/api/BooksGenre/Search/20121128'
|
11
11
|
|
@@ -7,7 +7,7 @@ module RakutenWebService
|
|
7
7
|
class Total < Books::Resource
|
8
8
|
endpoint 'https://app.rakuten.co.jp/services/api/BooksTotal/Search/20170404'
|
9
9
|
|
10
|
-
|
10
|
+
parser do |response|
|
11
11
|
response['Items'].map do |item|
|
12
12
|
resource_class = find_resource_by_genre_id(item['booksGenreId'])
|
13
13
|
resource_class.new(item)
|
@@ -9,6 +9,8 @@ require 'rakuten_web_service/error'
|
|
9
9
|
|
10
10
|
module RakutenWebService
|
11
11
|
class Client
|
12
|
+
USER_AGENT = "RakutenWebService SDK for Ruby v#{RWS::VERSION}(ruby-#{RUBY_VERSION} [#{RUBY_PLATFORM}])".freeze
|
13
|
+
|
12
14
|
attr_reader :url
|
13
15
|
|
14
16
|
def initialize(resource_class)
|
@@ -20,25 +22,23 @@ module RakutenWebService
|
|
20
22
|
params = RakutenWebService.configuration.generate_parameters(params)
|
21
23
|
response = request(url.path, params)
|
22
24
|
body = JSON.parse(response.body)
|
23
|
-
|
24
|
-
|
25
|
-
return RakutenWebService::Response.new(@resource_class, body)
|
25
|
+
unless response.is_a?(Net::HTTPSuccess)
|
26
|
+
raise RakutenWebService::Error.for(response)
|
26
27
|
end
|
27
|
-
|
28
|
+
|
29
|
+
RakutenWebService::Response.new(@resource_class, body)
|
28
30
|
end
|
29
31
|
|
30
32
|
private
|
31
33
|
|
32
34
|
def request(path, params)
|
33
|
-
http = Net::HTTP.new(
|
35
|
+
http = Net::HTTP.new(url.host, url.port)
|
34
36
|
http.use_ssl = true
|
35
37
|
if RakutenWebService.configuration.debug_mode?
|
36
38
|
http.set_debug_output($stderr)
|
37
39
|
end
|
38
|
-
path = "#{path}?#{
|
39
|
-
header = {
|
40
|
-
'User-Agent' => "RakutenWebService SDK for Ruby v#{RWS::VERSION}(ruby-#{RUBY_VERSION} [#{RUBY_PLATFORM}])"
|
41
|
-
}
|
40
|
+
path = "#{path}?#{URI.encode_www_form(params)}"
|
41
|
+
header = { 'User-Agent' => USER_AGENT }
|
42
42
|
http.get(path, header)
|
43
43
|
end
|
44
44
|
end
|
@@ -41,20 +41,4 @@ module RakutenWebService
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
44
|
-
|
45
|
-
def configure(&block)
|
46
|
-
@configuration ||= Configuration.new
|
47
|
-
if block
|
48
|
-
raise ArgumentError, 'Block is required to have one argument' if block.arity != 1
|
49
|
-
yield @configuration
|
50
|
-
end
|
51
|
-
@configuration
|
52
|
-
end
|
53
|
-
|
54
|
-
def configuration(&block)
|
55
|
-
warn 'Warning: RakutenWebService.configuration is deprecated. Use RakutenWebService.configure.' if block_given?
|
56
|
-
configure(&block)
|
57
|
-
end
|
58
|
-
|
59
|
-
module_function :configure, :configuration
|
60
44
|
end
|
@@ -6,6 +6,11 @@ module RakutenWebService
|
|
6
6
|
repository[status_code] = error
|
7
7
|
end
|
8
8
|
|
9
|
+
def self.for(response)
|
10
|
+
error_class = repository[response.code.to_i]
|
11
|
+
error_class.new(JSON.parse(response.body)['error_description'])
|
12
|
+
end
|
13
|
+
|
9
14
|
def self.repository
|
10
15
|
@repository ||= {}
|
11
16
|
end
|
@@ -7,7 +7,7 @@ module RakutenWebService
|
|
7
7
|
def self.inherited(klass)
|
8
8
|
super
|
9
9
|
|
10
|
-
klass.
|
10
|
+
klass.parser do |response|
|
11
11
|
current = response['current']
|
12
12
|
%w[children parents brothers].each do |type|
|
13
13
|
elements = Array(response[type]).map { |e| klass.new(e) }
|
@@ -17,8 +17,8 @@ module RakutenWebService
|
|
17
17
|
|
18
18
|
endpoint 'https://app.rakuten.co.jp/services/api/IchibaItem/Search/20170706'
|
19
19
|
|
20
|
-
|
21
|
-
response['Items'].map { |item| Item.new(item) }
|
20
|
+
parser do |response|
|
21
|
+
(response['Items'] || []).map { |item| Item.new(item) }
|
22
22
|
end
|
23
23
|
|
24
24
|
attribute :itemName, :catchcopy, :itemCode, :itemPrice,
|
@@ -34,7 +34,7 @@ module RakutenWebService
|
|
34
34
|
:reviewCount, :reviewAverage,
|
35
35
|
:pointRate, :pointRateStartTime, :pointRateEndTime,
|
36
36
|
:shopName, :shopCode, :shopUrl, :shopAffiliateUrl,
|
37
|
-
:genreId
|
37
|
+
:genreId, :tagIds
|
38
38
|
|
39
39
|
def genre
|
40
40
|
Genre.new(genre_id)
|
@@ -7,7 +7,7 @@ module RakutenWebService
|
|
7
7
|
class RankingItem < RakutenWebService::Ichiba::Item
|
8
8
|
endpoint 'https://app.rakuten.co.jp/services/api/IchibaItem/Ranking/20170628'
|
9
9
|
|
10
|
-
|
10
|
+
parser do |response|
|
11
11
|
response['Items'].map { |item| RankingItem.new(item) }
|
12
12
|
end
|
13
13
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rakuten_web_service/resource'
|
4
|
+
|
5
|
+
module RakutenWebService
|
6
|
+
module Ichiba
|
7
|
+
class Tag < Resource
|
8
|
+
attribute :tagId, :tagName, :parentTagId
|
9
|
+
|
10
|
+
def search(params = {})
|
11
|
+
params = params.merge(tagId: id)
|
12
|
+
RakutenWebService::Ichiba::Item.search(params)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rakuten_web_service/resource'
|
4
|
+
|
5
|
+
module RakutenWebService
|
6
|
+
module Ichiba
|
7
|
+
class TagGroup < Resource
|
8
|
+
endpoint 'https://app.rakuten.co.jp/services/api/IchibaTag/Search/20140222'
|
9
|
+
|
10
|
+
parser do |response|
|
11
|
+
response['tagGroups'].map { |tag_group| TagGroup.new(tag_group) }
|
12
|
+
end
|
13
|
+
|
14
|
+
attribute :tagGroupName, :tagGroupId
|
15
|
+
|
16
|
+
def tags
|
17
|
+
get_attribute('tags').map do |tag|
|
18
|
+
Tag.new(tag)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -8,3 +8,5 @@ require 'rakuten_web_service/ichiba/item'
|
|
8
8
|
require 'rakuten_web_service/ichiba/genre'
|
9
9
|
require 'rakuten_web_service/ichiba/ranking'
|
10
10
|
require 'rakuten_web_service/ichiba/product'
|
11
|
+
require 'rakuten_web_service/ichiba/tag_group'
|
12
|
+
require 'rakuten_web_service/ichiba/tag'
|
@@ -37,7 +37,9 @@ module RakutenWebService
|
|
37
37
|
|
38
38
|
def parent_category
|
39
39
|
return nil if parent_category_type.nil?
|
40
|
-
Recipe.categories(parent_category_type).find
|
40
|
+
Recipe.categories(parent_category_type).find do |c|
|
41
|
+
c.id.to_i == parent_category_id.to_i
|
42
|
+
end
|
41
43
|
end
|
42
44
|
|
43
45
|
def absolute_category_id
|
@@ -12,6 +12,8 @@ module RakutenWebService
|
|
12
12
|
using RakutenWebService::StringSupport
|
13
13
|
|
14
14
|
class << self
|
15
|
+
attr_writer :resource_name
|
16
|
+
|
15
17
|
def inherited(subclass)
|
16
18
|
@@subclasses ||= []
|
17
19
|
@@subclasses.push(subclass)
|
@@ -24,20 +26,11 @@ module RakutenWebService
|
|
24
26
|
def attribute(*attribute_names)
|
25
27
|
attribute_names.each do |attribute_name|
|
26
28
|
attribute_name = attribute_name.to_s
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
get_attribute(attribute_name)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
next if method_name !~ /(.+)_flag$/
|
36
|
-
instance_eval do
|
37
|
-
define_method "#{$1}?" do
|
38
|
-
get_attribute(attribute_name) == 1
|
39
|
-
end
|
40
|
-
end
|
29
|
+
|
30
|
+
define_getter_for_attribute(attribute_name)
|
31
|
+
next unless attribute_name.end_with?('Flag')
|
32
|
+
|
33
|
+
define_asking_method_for_attribute(attribute_name)
|
41
34
|
end
|
42
35
|
end
|
43
36
|
|
@@ -57,19 +50,36 @@ module RakutenWebService
|
|
57
50
|
@resource_name ||= name.split('::').last.downcase
|
58
51
|
end
|
59
52
|
|
60
|
-
def set_resource_name(name)
|
61
|
-
@resource_name = name
|
62
|
-
end
|
63
|
-
|
64
53
|
def endpoint(url = nil)
|
65
54
|
@endpoint = url || @endpoint
|
66
55
|
end
|
67
56
|
|
68
|
-
def
|
57
|
+
def parser(&block)
|
69
58
|
instance_eval do
|
70
59
|
define_singleton_method :parse_response, block
|
71
60
|
end
|
72
61
|
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def define_getter_for_attribute(attribute_name)
|
66
|
+
method_name = attribute_name.to_snake
|
67
|
+
method_name.sub!(/^#{resource_name}_(\w+)$/, '\1')
|
68
|
+
|
69
|
+
define_method method_name do
|
70
|
+
get_attribute(attribute_name)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def define_asking_method_for_attribute(attribute_name)
|
75
|
+
method_name = attribute_name.to_snake
|
76
|
+
method_name.sub!(/^#{resource_name}_(\w+)$/, '\1')
|
77
|
+
method_name.sub!(/(.+)_flag$/, '\1')
|
78
|
+
|
79
|
+
define_method "#{method_name}?" do
|
80
|
+
get_attribute(attribute_name) == 1
|
81
|
+
end
|
82
|
+
end
|
73
83
|
end
|
74
84
|
|
75
85
|
def initialize(params)
|
@@ -79,7 +89,6 @@ module RakutenWebService
|
|
79
89
|
|
80
90
|
def [](key)
|
81
91
|
camel_key = key.to_camel
|
82
|
-
# camel_key[0] = camel_key[0].downcase
|
83
92
|
@params[key] || @params[camel_key]
|
84
93
|
end
|
85
94
|
|