rakumarket 0.0.1
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 +24 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +43 -0
- data/README.rdoc +79 -0
- data/Rakefile +2 -0
- data/fixtures/vcr_casettes/item_search.yml +20787 -0
- data/lib/rakumarket/client.rb +84 -0
- data/lib/rakumarket/item_search_client.rb +455 -0
- data/lib/rakumarket/version.rb +3 -0
- data/lib/rakumarket.rb +67 -0
- data/rakumarket.gemspec +28 -0
- data/spec/rakumarket_spec.rb +125 -0
- data/spec/spec_helper.rb +11 -0
- metadata +170 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
module Rakumarket
|
2
|
+
class Client
|
3
|
+
attr_accessor :developer_id
|
4
|
+
include HTTParty
|
5
|
+
base_uri "http://api.rakuten.co.jp/rws/3.0"
|
6
|
+
format :json
|
7
|
+
|
8
|
+
def initialize(options={})
|
9
|
+
@developer_id = options[:developer_id] || Rakumarket.developer_id
|
10
|
+
end
|
11
|
+
|
12
|
+
def request(query={})
|
13
|
+
@options = default_options.merge(query).slice(*valid_request_keys)
|
14
|
+
transform_request!
|
15
|
+
@response = self.class.get("/json",:query => @options)
|
16
|
+
respond
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def transform_request!
|
21
|
+
transform_request_keys!
|
22
|
+
transform_request_values!
|
23
|
+
end
|
24
|
+
|
25
|
+
def transform_request_keys!
|
26
|
+
transform_keys! @options, request_keys_to_transform
|
27
|
+
end
|
28
|
+
|
29
|
+
def transform_request_values!
|
30
|
+
transform_values! @options, request_values_to_transform
|
31
|
+
end
|
32
|
+
|
33
|
+
def respond
|
34
|
+
transform_response!
|
35
|
+
end
|
36
|
+
|
37
|
+
def transform_response!
|
38
|
+
transform_response_values!
|
39
|
+
transform_response_keys!
|
40
|
+
end
|
41
|
+
|
42
|
+
def transform_response_keys!
|
43
|
+
transform_keys! @response, response_keys_to_transform
|
44
|
+
end
|
45
|
+
|
46
|
+
def transform_response_values!
|
47
|
+
transform_values! @response, response_values_to_transform
|
48
|
+
end
|
49
|
+
|
50
|
+
def transform_keys! hash, transformation_index
|
51
|
+
transformation_index.each do |k,v|
|
52
|
+
hash[v] = hash.delete(k) if hash.has_key?(k)
|
53
|
+
end
|
54
|
+
hash
|
55
|
+
end
|
56
|
+
|
57
|
+
def transform_values! hash, transformation_index
|
58
|
+
transformation_index.each do |k,v|
|
59
|
+
hash[k] = v[hash[k]] if hash[k] && v.has_key?(hash[k])
|
60
|
+
end
|
61
|
+
hash
|
62
|
+
end
|
63
|
+
|
64
|
+
def custom_transform(hash,key)
|
65
|
+
yield hash, key if block_given? && hash.has_key?(key)
|
66
|
+
end
|
67
|
+
def custom_transform!(hash,key)
|
68
|
+
hash[key] = yield hash, key if block_given? && hash.has_key?(key)
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.get(*args); handle_response super end
|
72
|
+
def self.post(*args); handle_response super end
|
73
|
+
|
74
|
+
def self.handle_response(response)
|
75
|
+
case response["Header"]["Status"]
|
76
|
+
when "Success"; response
|
77
|
+
else; raise RakumarketError.new(Hashie::Mash.new(response["Header"].slice("Status","StatusMsg")).rubyify_keys!)
|
78
|
+
end
|
79
|
+
|
80
|
+
Hashie::Mash.new(response)
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,455 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
module Rakumarket
|
3
|
+
class ItemSearchClient < Client
|
4
|
+
|
5
|
+
OPERATION = "ItemSearch"
|
6
|
+
VERSION = "2010-09-15"
|
7
|
+
|
8
|
+
INTERNATIONAL_DELIVERY_AREA_CODES = {
|
9
|
+
"worldwide" => "ALL",
|
10
|
+
"usa" => "US",
|
11
|
+
"argentina" => "AR",
|
12
|
+
"brazil" => "BR",
|
13
|
+
"canada" => "CA",
|
14
|
+
"mexico" => "MX",
|
15
|
+
"austria" => "AT",
|
16
|
+
"belgium" => "BE",
|
17
|
+
"denmark" => "DK",
|
18
|
+
"france" => "FR",
|
19
|
+
"germany" => "DE",
|
20
|
+
"greece" => "GR",
|
21
|
+
"italy" => "IT",
|
22
|
+
"morocco" => "MA",
|
23
|
+
"netherlands" => "NL",
|
24
|
+
"poland" => "PL",
|
25
|
+
"portugal" => "PT",
|
26
|
+
"russia" => "RU",
|
27
|
+
"spain" => "ES",
|
28
|
+
"sweden" => "SE",
|
29
|
+
"switzerland" => "CH",
|
30
|
+
"turkey" => "TR",
|
31
|
+
"england" => "GB",
|
32
|
+
"australia" => "AU",
|
33
|
+
"china" => "CN",
|
34
|
+
"hong kong" => "HK",
|
35
|
+
"india" => "IN",
|
36
|
+
"indonesia" => "ID",
|
37
|
+
"south korea" => "KR",
|
38
|
+
"malaysia" => "MY",
|
39
|
+
"new zealand" => "NZ",
|
40
|
+
"philipines" => "PH",
|
41
|
+
"singapore" => "SG",
|
42
|
+
"taiwan" => "TW",
|
43
|
+
"thailand" => "TH",
|
44
|
+
"vietnam" => "VN"
|
45
|
+
}
|
46
|
+
|
47
|
+
INTERNATIONAL_DELIVERY_AREA_NAMES = {
|
48
|
+
"ワールドワイド" => "worldwide",
|
49
|
+
"アメリカ" => "usa",
|
50
|
+
"アルゼンチン" => "argentina",
|
51
|
+
"ブラジル" => "brazil",
|
52
|
+
"カナダ" => "canada",
|
53
|
+
"メキシコ" => "mexico",
|
54
|
+
"オーストリア" => "austria",
|
55
|
+
"ベルギー" => "belgium",
|
56
|
+
"デンマーク" => "denmark",
|
57
|
+
"フランス" => "france",
|
58
|
+
"ドイツ" => "germany",
|
59
|
+
"ギリシャ" => "greece",
|
60
|
+
"イタリア" => "italy",
|
61
|
+
"モロッコ" => "morocco",
|
62
|
+
"オランダ" => "netherlands",
|
63
|
+
"ポーランド" => "poland",
|
64
|
+
"ポルトガル" => "portugal",
|
65
|
+
"ロシア" => "russia",
|
66
|
+
"スペイン" => "spain",
|
67
|
+
"スウェーデン" => "sweden",
|
68
|
+
"スイス" => "switzerland",
|
69
|
+
"トルコ" => "turkey",
|
70
|
+
"英国" => "england",
|
71
|
+
"オーストラリア" => "australia",
|
72
|
+
"中国" => "china",
|
73
|
+
"香港" => "hong kong",
|
74
|
+
"インド" => "india",
|
75
|
+
"インドネシア" => "indonesia",
|
76
|
+
"韓国" => "south korea",
|
77
|
+
"マレーシア" => "malaysia",
|
78
|
+
"ニュージーランド" => "new zealand",
|
79
|
+
"フィリピン" => "philipines",
|
80
|
+
"シンガポール" => "singapore",
|
81
|
+
"台湾" => "taiwan",
|
82
|
+
"タイ" => "thailand",
|
83
|
+
"ベトナム" => "vietnam",
|
84
|
+
}
|
85
|
+
|
86
|
+
ASURAKU_DELIVERY_AREA_CODES = {
|
87
|
+
"all" => "0",
|
88
|
+
"hokkaido" => "1",
|
89
|
+
"tohoku" => "101",
|
90
|
+
"aomori" => "2",
|
91
|
+
"iwate" => "3",
|
92
|
+
"miyagi" => "4",
|
93
|
+
"akita" => "5",
|
94
|
+
"yamagata" => "6",
|
95
|
+
"fukushima" => "7",
|
96
|
+
"kanto" => "102",
|
97
|
+
"ibaraki" => "8",
|
98
|
+
"tochigi" => "9",
|
99
|
+
"gunma" => "10",
|
100
|
+
"saitama" => "11",
|
101
|
+
"chiba" => "12",
|
102
|
+
"tokyo" => "13",
|
103
|
+
"kanagawa" => "14",
|
104
|
+
"koshinetsu" => "103",
|
105
|
+
"niigata" => "15",
|
106
|
+
"yamanashi" => "19",
|
107
|
+
"nagano" => "20",
|
108
|
+
"hokuriku" => "104",
|
109
|
+
"toyama" => "16",
|
110
|
+
"ishikawa" => "17",
|
111
|
+
"fukui" => "18",
|
112
|
+
"tokai" => "105",
|
113
|
+
"gifu" => "21",
|
114
|
+
"shizuoka" => "22",
|
115
|
+
"aichi" => "23",
|
116
|
+
"mie" => "24",
|
117
|
+
"kansai" => "106",
|
118
|
+
"shiga" => "25",
|
119
|
+
"kyoto" => "26",
|
120
|
+
"osaka" => "27",
|
121
|
+
"hyogo" => "28",
|
122
|
+
"nara" => "29",
|
123
|
+
"wakayama" => "30",
|
124
|
+
"chugoku" => "107",
|
125
|
+
"tottori" => "31",
|
126
|
+
"shimane" => "32",
|
127
|
+
"okayama" => "33",
|
128
|
+
"hiroshima" => "34",
|
129
|
+
"yamaguchi" => "35",
|
130
|
+
"shikoku" => "108",
|
131
|
+
"tokushima" => "36",
|
132
|
+
"kagawa" => "37",
|
133
|
+
"ehime" => "38",
|
134
|
+
"kochi" => "39",
|
135
|
+
"kyushu" => "109",
|
136
|
+
"fukuoka" => "40",
|
137
|
+
"saga" => "41",
|
138
|
+
"nagasaki" => "42",
|
139
|
+
"kumamoto" => "43",
|
140
|
+
"ooita" => "44",
|
141
|
+
"miyaza" => "45",
|
142
|
+
"kagoshima" => "46",
|
143
|
+
"okinawa" => "47"
|
144
|
+
}
|
145
|
+
|
146
|
+
ASURAKU_DELIVERY_AREA_NAMES = {
|
147
|
+
"全地域" => "all",
|
148
|
+
"北海道エリアのすべて" => "hokkaido",
|
149
|
+
"北海道" => "hokkaido",
|
150
|
+
"東北エリアのすべて" => "tohoku",
|
151
|
+
"青森県" => "aomori",
|
152
|
+
"岩手県" => "iwate",
|
153
|
+
"宮城県" => "miyagi",
|
154
|
+
"秋田県" => "akita",
|
155
|
+
"山形県" => "yamagata",
|
156
|
+
"福島県" => "fukushima",
|
157
|
+
"関東エリアのすべて" => "kanto",
|
158
|
+
"茨城県" => "ibaraki",
|
159
|
+
"栃木県" => "tochigi",
|
160
|
+
"群馬県" => "gunma",
|
161
|
+
"埼玉県" => "saitama",
|
162
|
+
"千葉県" => "chiba",
|
163
|
+
"東京都" => "tokyo",
|
164
|
+
"神奈川県" => "kanagawa",
|
165
|
+
"甲信越エリアのすべて" => "koshinetsu",
|
166
|
+
"新潟県" => "niigata",
|
167
|
+
"山梨県" => "yamanashi",
|
168
|
+
"長野県" => "nagano",
|
169
|
+
"北陸エリアのすべて" => "hokuriku",
|
170
|
+
"富山県" => "toyama",
|
171
|
+
"石川県" => "ishikawa",
|
172
|
+
"福井県" => "fukui",
|
173
|
+
"東海エリアのすべて" => "tokai",
|
174
|
+
"岐阜県" => "gifu",
|
175
|
+
"静岡県" => "shizuoka",
|
176
|
+
"愛知県" => "aichi",
|
177
|
+
"三重県" => "mie",
|
178
|
+
"関西エリアのすべて" => "kansai",
|
179
|
+
"滋賀県" => "shiga",
|
180
|
+
"京都府" => "kyoto",
|
181
|
+
"大阪府" => "osaka",
|
182
|
+
"兵庫県" => "hyogo",
|
183
|
+
"奈良県" => "nara",
|
184
|
+
"和歌山県" => "wakayama",
|
185
|
+
"中国エリアのすべて" => "chugoku",
|
186
|
+
"鳥取県" => "tottori",
|
187
|
+
"島根県" => "shimane",
|
188
|
+
"岡山県" => "okayama",
|
189
|
+
"広島県" => "hiroshima",
|
190
|
+
"山口県" => "yamaguchi",
|
191
|
+
"四国エリアのすべて" => "shikoku",
|
192
|
+
"徳島県" => "tokushima",
|
193
|
+
"香川県" => "kagawa",
|
194
|
+
"愛媛県" => "ehime",
|
195
|
+
"高知県" => "kochi",
|
196
|
+
"九州エリアのすべて" => "kyushu",
|
197
|
+
"福岡県" => "fukuoka",
|
198
|
+
"佐賀県" => "saga",
|
199
|
+
"長崎県" => "nagasaki",
|
200
|
+
"熊本県" => "kumamoto",
|
201
|
+
"大分県" => "ooita",
|
202
|
+
"宮崎県" => "miyaza",
|
203
|
+
"鹿児島県" => "kagoshima",
|
204
|
+
"沖縄エリアのすべて" => "okinawa",
|
205
|
+
"沖縄県" => "okinawa"
|
206
|
+
}
|
207
|
+
|
208
|
+
VALID_REQUEST_KEYS = [
|
209
|
+
:developer_id,
|
210
|
+
:affiliate_id,
|
211
|
+
:operation,
|
212
|
+
:call_back,
|
213
|
+
:keyword,
|
214
|
+
:version,
|
215
|
+
:shop_code,
|
216
|
+
:genre_id,
|
217
|
+
:items_per_page,
|
218
|
+
:page,
|
219
|
+
:order,
|
220
|
+
:price,
|
221
|
+
:must_be_available,
|
222
|
+
:deep_search,
|
223
|
+
:mobile,
|
224
|
+
:must_have_image,
|
225
|
+
:or_search,
|
226
|
+
:exclude_keyword,
|
227
|
+
:include_genre_info,
|
228
|
+
:purchase_type,
|
229
|
+
:shipping,
|
230
|
+
:must_have_point_multiplication,
|
231
|
+
:point_multiplication_factor,
|
232
|
+
:must_accept_credit_cards
|
233
|
+
]
|
234
|
+
|
235
|
+
REQUEST_KEYS_TO_TRANSFORM = {
|
236
|
+
:developer_id => :developerId,
|
237
|
+
:affiliate_id => :affiliateId,
|
238
|
+
:call_back => :callBack,
|
239
|
+
:items_per_page => :hits,
|
240
|
+
:shop_code => :shopCode,
|
241
|
+
:genre_id => :genreId,
|
242
|
+
:order => :sort,
|
243
|
+
:must_be_available => :availability,
|
244
|
+
:deep_search => :field,
|
245
|
+
:mobile => :carrier,
|
246
|
+
:must_have_image => :imageFlag,
|
247
|
+
:or_search => :orFlag,
|
248
|
+
:exclude_keyword => :NGKeyword,
|
249
|
+
:include_genre_info => :genreInformationFlag,
|
250
|
+
:purchase_type => :purchaseType,
|
251
|
+
:must_have_point_multiplication => :pointRateFlag,
|
252
|
+
:point_multiplication_factor => :pointRate,
|
253
|
+
:must_accept_credit_cards => :creditCardFlag
|
254
|
+
}
|
255
|
+
|
256
|
+
REQUEST_VALUES_TO_TRANSFORM = {
|
257
|
+
:availability => {true => 1, false => 0},
|
258
|
+
:field => {true => 0, false => 1},
|
259
|
+
:sort => { "affiliate_rate" => "+affiliateRate",
|
260
|
+
"affiliate_rate asc" => "+affiliateRate",
|
261
|
+
"affiliate_rate desc" => "-affiliateRate",
|
262
|
+
"review_count" => "+reviewCount",
|
263
|
+
"review_count asc" => "+reviewCount",
|
264
|
+
"review_count desc" => "-reviewCount",
|
265
|
+
"review_average" => "+reviewAverage",
|
266
|
+
"review_average asc" => "+reviewAverage",
|
267
|
+
"review_average desc" => "-reviewAverage",
|
268
|
+
"price" => "+itemPrice",
|
269
|
+
"price asc" => "+itemPrice",
|
270
|
+
"price desc" => "-itemPrice",
|
271
|
+
"updated_at" => "+updateTimestamp",
|
272
|
+
"updated_at asc" => "+updateTimestamp",
|
273
|
+
"updated_at desc" => "-updateTimestamp" },
|
274
|
+
:carrier => {true => 1, false => 0},
|
275
|
+
:imageFlag => {true => 1, false => 0},
|
276
|
+
:orFlag => {true => 1, false => 0},
|
277
|
+
:genreInformationFlag => {true => 1, false => 0},
|
278
|
+
:purchaseType => {"normal" => 0, "regular" => 1, "distribution" => 2},
|
279
|
+
:shipOverseasFlag => {false => 0, true => 1},
|
280
|
+
:shipOverseasArea => INTERNATIONAL_DELIVERY_AREA_CODES,
|
281
|
+
:asurakuFlag => {false => 0, true => 1},
|
282
|
+
:asurakuArea => ASURAKU_DELIVERY_AREA_CODES,
|
283
|
+
:pointRateFlag => {false => 0, true => 1},
|
284
|
+
:postageFlag => {false => 0, true => 1},
|
285
|
+
:creditCardFlag => {false => 0, true => 1}
|
286
|
+
}
|
287
|
+
|
288
|
+
RESPONSE_VALUES_TO_TRANSFORM = {
|
289
|
+
'carrier' => {0 => false, 1 => true},
|
290
|
+
}
|
291
|
+
|
292
|
+
RESPONSE_ITEM_VALUES_TO_TRANSFORM = {
|
293
|
+
'imageFlag' => {0 => false, 1 => true},
|
294
|
+
'availability' => {0 => false, 1 => true},
|
295
|
+
'taxFlag' => {0 => true, 1 => false},
|
296
|
+
'postageFlag' => {0 => true, 1 => false},
|
297
|
+
'creditCardFlag' => {0 => false, 1 => true},
|
298
|
+
'shopOfTheYearFlag' => {0 => false, 1 => true},
|
299
|
+
'shipOverseasFlag' => {0 => false, 1 => true},
|
300
|
+
'asurakuFlag' => {0 => false, 1 => true}
|
301
|
+
}
|
302
|
+
|
303
|
+
RESPONSE_KEYS_TO_TRANSFORM = {
|
304
|
+
:developerId => :developer_id,
|
305
|
+
:affiliateId => :affiliate_id,
|
306
|
+
:Status => :status,
|
307
|
+
:StatusMsg => :status_msg,
|
308
|
+
:first => :first_page,
|
309
|
+
:last => :last_page,
|
310
|
+
:hits => :items_per_page,
|
311
|
+
:carrier => :mobile?,
|
312
|
+
:pageCount => :page_count,
|
313
|
+
:Items => :items,
|
314
|
+
:genreInformation => :genre_info
|
315
|
+
}
|
316
|
+
|
317
|
+
RESPONSE_ITEM_KEYS_TO_TRANSFORM = {
|
318
|
+
:itemName => :name,
|
319
|
+
:itemCode => :code,
|
320
|
+
:itemPrice => :price,
|
321
|
+
:itemCaption => :caption,
|
322
|
+
:itemUrl => :url,
|
323
|
+
:affiliateUrl => :affiliate_url,
|
324
|
+
:imageFlag => :has_image?,
|
325
|
+
:smallImageUrl => :small_image_url,
|
326
|
+
:mediumImageUrl => :medium_image_url,
|
327
|
+
:availability => :available?,
|
328
|
+
:taxFlag => :tax_included?,
|
329
|
+
:creditCardFlag => :credit_cards_accepted?,
|
330
|
+
:shopOfTheYearFlag => :shop_of_the_year?,
|
331
|
+
:affiliateRate => :affiliate_rate,
|
332
|
+
:startTime => :start_time,
|
333
|
+
:endTime => :end_time,
|
334
|
+
:reviewCount => :review_count,
|
335
|
+
:reviewAverage => :review_average,
|
336
|
+
:pointRate => :point_multiplication_factor,
|
337
|
+
:pointRateStartTime => :point_multiplication_start_time,
|
338
|
+
:pointRateEndTime => :point_multiplication_end_time,
|
339
|
+
:genreId => :genre_id
|
340
|
+
}
|
341
|
+
|
342
|
+
RESPONSE_GENRE_INFO_KEYS_TO_TRANSFORM = {
|
343
|
+
:genreId => :genre_id,
|
344
|
+
:genreName => :genre_name,
|
345
|
+
:itemCount => :item_count,
|
346
|
+
:genreLevel => :genre_level
|
347
|
+
}
|
348
|
+
|
349
|
+
private
|
350
|
+
def respond
|
351
|
+
@response = @response['Body']['ItemSearch']
|
352
|
+
super
|
353
|
+
end
|
354
|
+
|
355
|
+
def transform_request_keys!
|
356
|
+
if price = @options.delete(:price)
|
357
|
+
@options[:minPrice] = price[:minimum] if price[:minimum]
|
358
|
+
@options[:maxPrice] = price[:maximum] if price[:maximum]
|
359
|
+
end
|
360
|
+
if shipping = @options.delete(:shipping)
|
361
|
+
@options[:shipOverseasFlag] = shipping[:must_ship_international] if shipping[:must_ship_international]
|
362
|
+
@options[:shipOverseasArea] = shipping[:country] if shipping[:country]
|
363
|
+
@options[:asurakuFlag] = shipping[:must_ship_next_day] if shipping[:must_ship_next_day]
|
364
|
+
@options[:asurakuArea] = shipping[:next_day_area] if shipping[:next_day_area]
|
365
|
+
@options[:postageFlag] = shipping[:must_include_cost] if shipping[:must_include_cost]
|
366
|
+
end
|
367
|
+
@options[:order].downcase! if @options[:order].is_a?(String)
|
368
|
+
super
|
369
|
+
end
|
370
|
+
|
371
|
+
def transform_response_values!
|
372
|
+
transform_response_item_values!
|
373
|
+
transform_response_genre_info_values! if @response.has_key?('genreInformation')
|
374
|
+
super
|
375
|
+
end
|
376
|
+
|
377
|
+
def transform_response_item_values!
|
378
|
+
@response['Items'] = @response['Items']['Item'].is_a?(Array) ? @response['Items']['Item'] : []
|
379
|
+
@response['Items'].each do |item|
|
380
|
+
custom_transform!(item,'shipOverseasArea'){|h,k| h[k].split('/').map{|a| INTERNATIONAL_DELIVERY_AREA_NAMES[a] || a } if h[k].is_a?(String) }
|
381
|
+
custom_transform!(item,'asurakuArea'){|h,k| h[k].split('/').map{|a| ASURAKU_DELIVERY_AREA_NAMES[a] || a} if h[k].is_a?(String) }
|
382
|
+
custom_transform!(item, 'startTime'){|h,k| Time.parse(h[k]) if h[k].present? }
|
383
|
+
custom_transform!(item, 'endTime'){|h,k| Time.parse(h[k]) if h[k].present? }
|
384
|
+
custom_transform!(item, 'pointRateStartTime'){|h,k| Time.parse(h[k]) if h[k].present? }
|
385
|
+
custom_transform!(item, 'pointRateEndTime'){|h,k| Time.parse(h[k]) if h[k].present? }
|
386
|
+
transform_values! item, RESPONSE_ITEM_VALUES_TO_TRANSFORM
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
def transform_response_genre_info_values!
|
391
|
+
genre_info = @response['genreInformation']
|
392
|
+
custom_transform!(genre_info, 'parent'){|h,k| h[k].first }
|
393
|
+
custom_transform!(genre_info, 'current'){|h,k| h[k].first }
|
394
|
+
end
|
395
|
+
|
396
|
+
def transform_response_keys!
|
397
|
+
transform_response_item_keys!
|
398
|
+
transform_response_genre_info_keys! if @response.has_key?('genreInformation')
|
399
|
+
super
|
400
|
+
end
|
401
|
+
|
402
|
+
def transform_response_item_keys!
|
403
|
+
@response['Items'].each do |item|
|
404
|
+
item[:shipping] = {}
|
405
|
+
custom_transform(item,'postageFlag'){|h,k| h[:shipping][:cost_included?] = h.delete(k) }
|
406
|
+
custom_transform(item,'shipOverseasFlag'){|h,k| h[:shipping][:international?] = h.delete(k) }
|
407
|
+
custom_transform(item,'shipOverseasArea'){|h,k| h[:shipping][:countries] = h.delete(k) }
|
408
|
+
custom_transform(item,'asurakuFlag'){|h,k| h[:shipping][:next_day?] = h.delete(k) }
|
409
|
+
custom_transform(item,'asurakuArea'){|h,k| h[:shipping][:next_day_areas] = h.delete(k) }
|
410
|
+
item[:shop] = {}
|
411
|
+
custom_transform(item,'shopName'){|h,k| h[:shop][:name] = h.delete(k) }
|
412
|
+
custom_transform(item,'shopCode'){|h,k| h[:shop][:code] = h.delete(k) }
|
413
|
+
custom_transform(item,'shopUrl'){|h,k| h[:shop][:url] = h.delete(k) }
|
414
|
+
transform_keys! item, RESPONSE_ITEM_KEYS_TO_TRANSFORM
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
def transform_response_genre_info_keys!
|
419
|
+
genre_info = @response['genreInformation']
|
420
|
+
custom_transform(genre_info,'child'){|h,k| h[:children] = h.delete(k) }
|
421
|
+
genre_info['children'].each do |child|
|
422
|
+
transform_keys! child, RESPONSE_GENRE_INFO_KEYS_TO_TRANSFORM
|
423
|
+
end
|
424
|
+
transform_keys! genre_info['parent'], RESPONSE_GENRE_INFO_KEYS_TO_TRANSFORM if genre_info['parent']
|
425
|
+
transform_keys! genre_info['current'], RESPONSE_GENRE_INFO_KEYS_TO_TRANSFORM if genre_info['current']
|
426
|
+
end
|
427
|
+
|
428
|
+
def default_options
|
429
|
+
{ :developer_id => @developer_id,
|
430
|
+
:operation => OPERATION,
|
431
|
+
:version => VERSION }
|
432
|
+
end
|
433
|
+
|
434
|
+
def valid_request_keys
|
435
|
+
VALID_REQUEST_KEYS
|
436
|
+
end
|
437
|
+
|
438
|
+
def request_keys_to_transform
|
439
|
+
REQUEST_KEYS_TO_TRANSFORM
|
440
|
+
end
|
441
|
+
|
442
|
+
def request_values_to_transform
|
443
|
+
REQUEST_VALUES_TO_TRANSFORM
|
444
|
+
end
|
445
|
+
|
446
|
+
def response_keys_to_transform
|
447
|
+
RESPONSE_KEYS_TO_TRANSFORM
|
448
|
+
end
|
449
|
+
|
450
|
+
def response_values_to_transform
|
451
|
+
RESPONSE_VALUES_TO_TRANSFORM
|
452
|
+
end
|
453
|
+
|
454
|
+
end
|
455
|
+
end
|
data/lib/rakumarket.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'hashie'
|
3
|
+
require 'active_support'
|
4
|
+
|
5
|
+
directory = File.expand_path(File.dirname(__FILE__))
|
6
|
+
|
7
|
+
Hash.send :include, Hashie::HashExtensions
|
8
|
+
|
9
|
+
module Rakumarket
|
10
|
+
|
11
|
+
def self.item_search(keyword, options={})
|
12
|
+
Rakumarket::ItemSearchClient.new.request({:keyword => keyword}.merge(options).hashie_symbolify_keys!)
|
13
|
+
end
|
14
|
+
|
15
|
+
#def self.genre_search(genre_id, options={})
|
16
|
+
# Rakumarket::GenreSearchClient.new.request({:genre_id => genre_id}.merge(options).hashie_symbolify_keys!)
|
17
|
+
#end
|
18
|
+
|
19
|
+
#def self.item_code_search(item_code, options={})
|
20
|
+
# Rakumarket::ItemCodeSearchClient.new.request({:item_code => item_code}.merge(options).hashie_symbolify_keys!)
|
21
|
+
#end
|
22
|
+
|
23
|
+
|
24
|
+
class << self
|
25
|
+
attr_accessor :developer_id
|
26
|
+
end
|
27
|
+
|
28
|
+
# Contains information for errors returned by the API
|
29
|
+
class RakumarketError < StandardError
|
30
|
+
attr_reader :data
|
31
|
+
|
32
|
+
def initialize(data)
|
33
|
+
@data = data
|
34
|
+
super data.status_msg
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class Hashie::Mash
|
40
|
+
# Converts all of the keys to strings, optionally formatting key name
|
41
|
+
def rubyify_keys!
|
42
|
+
keys.each{|k|
|
43
|
+
v = delete(k)
|
44
|
+
regular_writer(k.to_s.underscore, v)
|
45
|
+
v.rubyify_keys! if v.is_a?(Hash)
|
46
|
+
v.each{|p| p.rubyify_keys! if p.is_a?(Hash)} if v.is_a?(Array)
|
47
|
+
}
|
48
|
+
self
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
module Hashie::HashExtensions
|
53
|
+
# Destructively convert all of the keys of a Hash
|
54
|
+
# to their symbol representations.
|
55
|
+
def hashie_symbolify_keys!
|
56
|
+
self.keys.each do |k|
|
57
|
+
unless Symbol === k
|
58
|
+
self[k.to_sym] = self.delete(k)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
self
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
require File.join(directory, 'rakumarket', 'client')
|
67
|
+
require File.join(directory, 'rakumarket', 'item_search_client')
|
data/rakumarket.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.expand_path('../lib/rakumarket/version', __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{rakumarket}
|
5
|
+
s.version = Rakumarket::VERSION
|
6
|
+
s.platform = Gem::Platform::RUBY
|
7
|
+
s.required_rubygems_version = ">= 1.3.6"
|
8
|
+
s.authors = ["Benjamin Sullivan"]
|
9
|
+
s.email = %q{bsullivan2@gmail.com}
|
10
|
+
s.homepage = %q{http://github.com/bonsaiben/rakumarket}
|
11
|
+
s.summary = %q{A reader-friendly Ruby abstraction of the Rakuten Market API}
|
12
|
+
s.description = %q{A reader-friendly Ruby abstraction of the Rakuten Market API}
|
13
|
+
|
14
|
+
s.required_rubygems_version = ">= 1.3.6"
|
15
|
+
|
16
|
+
s.add_dependency "hashie", ">= 0.1.3"
|
17
|
+
s.add_dependency "httparty", ">= 0.1.0"
|
18
|
+
s.add_dependency 'activesupport', '~> 2.3.2'
|
19
|
+
s.add_development_dependency "bundler", ">= 1.0.0"
|
20
|
+
s.add_development_dependency "rspec", "~> 2.6"
|
21
|
+
s.add_development_dependency "webmock"
|
22
|
+
s.add_development_dependency "vcr"
|
23
|
+
|
24
|
+
s.files = `git ls-files`.split("\n")
|
25
|
+
s.require_path = 'lib'
|
26
|
+
|
27
|
+
end
|
28
|
+
|