taobaorb 0.8.2 → 0.8.3

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/lib/taobao/base.rb CHANGED
@@ -14,18 +14,12 @@ module Taobao
14
14
  end
15
15
 
16
16
  def self.api_request(options)
17
- options[:app_key] = @public_key
18
- options[:format] = :json
19
- options[:v] = API_VERSION
20
- options[:timestamp] = Date.new.strftime('%Y-%m-%d %H:%M:%S')
21
- options[:sign_method] = :md5
22
- options[:sign] = self.create_signature(options)
23
-
24
17
  uri = URI(PRODUCTION_URL)
25
- response = Net::HTTP.post_form(uri, options)
26
- JSON.parse response.body, {symbolize_names: true}
18
+ response = Net::HTTP.post_form uri, self.append_required_options(options)
19
+ parse_to_hash response
27
20
  end
28
21
 
22
+ private
29
23
  def self.create_signature(options)
30
24
  values_str = options.sort.inject('') do |str, item|
31
25
  str + item.first.to_s + item.last.to_s
@@ -34,4 +28,21 @@ module Taobao
34
28
  Digest::MD5.hexdigest(str).upcase
35
29
  end
36
30
 
31
+ def self.append_required_options(options)
32
+ options.merge!({
33
+ app_key: @public_key,
34
+ format: :json,
35
+ v: API_VERSION,
36
+ timestamp: Time.now.strftime('%Y-%m-%d %H:%M:%S'),
37
+ sign_method: :md5
38
+ })
39
+ options[:sign] = self.create_signature(options)
40
+ options
41
+ end
42
+
43
+ def self.parse_to_hash(response)
44
+ result = JSON.parse response.body, {symbolize_names: true}
45
+ raise Taobao::ApiError.new(result) if result.key? :error_response
46
+ result
47
+ end
37
48
  end
@@ -39,7 +39,7 @@ class Taobao::Category
39
39
  begin
40
40
  result[:itemcats_get_response][:item_cats][:item_cat]
41
41
  rescue NoMethodError
42
- raise Taobao::ApiError, 'Incorrect category ID'
42
+ raise Taobao::IncorrectCategoryId, 'Incorrect category ID'
43
43
  end
44
44
  end
45
45
 
@@ -0,0 +1,9 @@
1
+ class Taobao::ApiError < StandardError
2
+ def initialize(response)
3
+ @msg = response[:error_response][:msg]
4
+ end
5
+
6
+ def to_s
7
+ @msg
8
+ end
9
+ end
@@ -0,0 +1,2 @@
1
+ class Taobao::IncorrectCategoryId < StandardError
2
+ end
@@ -9,42 +9,44 @@ class Taobao::Product
9
9
  :approve_status, :postage_id, :product_id, :auction_point,
10
10
  :property_alias, :item_img, :prop_img, :sku, :video, :outer_id,
11
11
  :is_virtual]
12
-
12
+
13
13
  attr_reader *BASIC_PROPERTIES
14
14
  alias :id :num_iid
15
-
15
+
16
16
  def initialize(product_properties)
17
17
  @all_properties_fetched = false
18
-
18
+ @properties = []
19
+
19
20
  if Hash === product_properties
20
21
  hash_to_object(product_properties)
21
22
  else
22
- @id = product_properties.to_s
23
+ @num_iid = product_properties.to_s
23
24
  fetch_full_data
24
25
  end
25
26
  end
26
-
27
+
27
28
  def method_missing(method_name, *args, &block)
28
- unless OTHER_PROPERTIES.include? method_name
29
- super
30
- else
31
- fetch_full_data unless @all_properties_fetched
32
- self.instance_variable_get "@#{method_name}"
33
- end
29
+ unless @properties.include? method_name
30
+ super
31
+ else
32
+ fetch_full_data unless @all_properties_fetched
33
+ self.instance_variable_get "@#{method_name}"
34
+ end
34
35
  end
35
-
36
+
36
37
  private
37
38
  def hash_to_object(hash)
38
39
  hash.each do |k, v|
39
40
  self.instance_variable_set "@#{k}", v
41
+ @properties.push k unless @properties.include? k
40
42
  end
41
43
  end
42
-
44
+
43
45
  def fetch_full_data
44
46
  fields = (BASIC_PROPERTIES + OTHER_PROPERTIES).join ','
45
- params = {method: 'taobao.item.get', fields: fields, num_iid: @id}
47
+ params = {method: 'taobao.item.get', fields: fields, num_iid: id}
46
48
  result = Taobao.api_request(params)
47
49
  hash_to_object(result[:item_get_response][:item])
48
50
  @all_properties_fetched = true
49
51
  end
50
- end
52
+ end
@@ -11,7 +11,7 @@ class Taobao::ProductList
11
11
  end
12
12
 
13
13
  def total_count
14
- products unless @total_count
14
+ memoize_api_result
15
15
  @total_count
16
16
  end
17
17
 
@@ -34,8 +34,7 @@ class Taobao::ProductList
34
34
  end
35
35
 
36
36
  def method_missing(method_name, *args, &block)
37
- m = /^order_by_(?<field>.+)$/.match(method_name)
38
- if m
37
+ if (m = /^order_by_(?<field>.+)$/.match method_name)
39
38
  order_by m[:field]
40
39
  else
41
40
  super
@@ -48,21 +47,40 @@ class Taobao::ProductList
48
47
 
49
48
  private
50
49
  def products
51
- return @products if @products
52
- fields = [:num_iid, :title, :nick, :pic_url, :cid, :price, :type,
53
- :delist_time, :post_fee, :score, :volume].join ','
54
- params = {method: 'taobao.items.get', fields: fields}
55
- result = Taobao.api_request(params.merge(@opts))
50
+ memoize_api_result
51
+ @products
52
+ end
53
+
54
+ def memoize_api_result
55
+ return if @products
56
+ response = items_get_request
57
+ @total_count = retrieve_total_count(response)
58
+ @products = retrieve_products(response)
59
+ end
60
+
61
+ def retrieve_total_count(response)
62
+ response[:items_get_response][:total_results].to_i
63
+ end
64
+
65
+ def retrieve_products(response)
56
66
  begin
57
- @total_count = result[:items_get_response][:total_results]
58
- @products = []
59
- result[:items_get_response][:items][:item].each do |product|
60
- @products << Taobao::Product.new(product)
61
- end
67
+ products = response[:items_get_response][:items][:item]
68
+ get_products_as_objects(products)
62
69
  rescue NoMethodError
63
- @total_count = 0
64
- @products = []
70
+ []
71
+ end
72
+ end
73
+
74
+ def get_products_as_objects(products)
75
+ products.map do |product|
76
+ Taobao::Product.new(product)
65
77
  end
66
78
  end
67
79
 
80
+ def items_get_request
81
+ fields = [:num_iid, :title, :nick, :pic_url, :cid, :price, :type,
82
+ :delist_time, :post_fee, :score, :volume].join ','
83
+ params = {method: 'taobao.items.get', fields: fields}
84
+ Taobao.api_request(params.merge(@opts))
85
+ end
68
86
  end
data/lib/taobaorb.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'taobao/base'
2
- require 'taobao/exceptions'
2
+ require 'taobao/exceptions/api_error'
3
+ require 'taobao/exceptions/incorrect_category_id'
3
4
  require 'taobao/category'
4
5
  require 'taobao/product'
5
6
  require 'taobao/product_list'
@@ -0,0 +1 @@
1
+ {"error_response":{"code":41,"msg":"Invalid arguments:cid"}}
@@ -0,0 +1 @@
1
+ {"item_get_response":{"item":{"approve_status":"onsale","auction_point":5,"cid":50003678,"delist_time":"2012-06-06 03:29:16","desc":"<p><a href=\"http:\/\/item.taobao.com\/meal_detail.htm?meal_id=7728185\" target=\"_blank\"><img alt=\"\" src=\"http:\/\/img02.taobaocdn.com\/imgextra\/i2\/721217425\/T2_TXmXa8NXXXXXXXX_!!721217425.jpg\"><\/a><\/p><p style=\"text-align: left;\"><span style=\"line-height: 36.0px;font-size: 24.0px;\"><a href=\"http:\/\/tuancums.dian.taobao.com\/\" target=\"_blank\"><\/a><\/span><\/p><p style=\"text-align: left;\"><span style=\"font-size: 24.0px;\"><\/span><\/p><table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" width=\"750\" height=\"340\"><tr><td><span style=\"font-size: 24.0px;\"><a href=\"http:\/\/detail.tmall.com\/item.htm?id=15788895590\" target=\"_blank\"><img border=\"0\" alt=\"\" src=\"http:\/\/img03.taobaocdn.com\/imgextra\/i3\/721217425\/T20eNLXohcXXXXXXXX_!!721217425.jpg\" width=\"245\" height=\"340\"><\/a><\/span><\/td><td><span style=\"font-size: 24.0px;\"><a href=\"http:\/\/detail.tmall.com\/item.htm?id=15536427295\" target=\"_blank\"><img border=\"0\" alt=\"\" src=\"http:\/\/img01.taobaocdn.com\/imgextra\/i1\/721217425\/T2VDlFXXxNXXXXXXXX_!!721217425.jpg\" width=\"253\" height=\"340\"><\/a><\/span><\/td><td><span style=\"font-size: 24.0px;\"><a href=\"http:\/\/detail.tmall.com\/item.htm?id=12827936202\" target=\"_blank\"><img border=\"0\" alt=\"\" src=\"http:\/\/img04.taobaocdn.com\/imgextra\/i4\/721217425\/T2ZS4FXXhNXXXXXXXX_!!721217425.jpg\" width=\"252\" height=\"340\"><\/a><\/span><\/td><\/tr><\/table><p>&nbsp;<\/p><p style=\"text-align: center;\"><span style=\"font-size: 24.0px;\">回馈顾客,<span style=\"color: #ff0000;\">买3送同款1支<\/span>,多买多送!限1000套哦<\/span><\/p><p style=\"text-align: center;\"><span style=\"font-size: 24.0px;\"><a title=\"\" href=\"http:\/\/detail.tmall.com\/item.htm?id=10970032560\" target=\"_blank\"><\/a><\/span><\/p><p style=\"text-align: center;\"><span style=\"font-size: 24.0px;\"><span style=\"color: #ff0000;\">五色随机发货<\/span><\/span><\/p><p style=\"text-align: center;\"><span style=\"font-size: 24.0px;\"><span style=\"color: #ff0000;\"><span style=\"line-height: 36.0px;font-size: 24.0px;\"><a href=\"http:\/\/yingyong.taobao.com\/show.htm?app_id=209002&source=vip\" target=\"_blank\"><\/a><a href=\"http:\/\/tuancums.dian.taobao.com\/\" target=\"_blank\"><\/a><span style=\"color: #000000;\">注:新疆、西藏、内蒙古、甘肃、宁夏、青海(2套以上包邮) 不包邮如需要购买请联系客服补差价不补不发货哦。<a target=\"_self\"><\/a><a target=\"_blank\"><\/a><a target=\"_blank\"><\/a><\/span><\/span><\/span><\/span><\/p><table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" width=\"750\" height=\"560\"><tr><td><span style=\"font-size: 24.0px;\"><span><a href=\"http:\/\/item.taobao.com\/meal_detail.htm?meal_id=7702622\" target=\"_blank\"><img border=\"0\" alt=\"\" src=\"http:\/\/img02.taobaocdn.com\/imgextra\/i2\/721217425\/T2_AFmXa8NXXXXXXXX_!!721217425.jpg\" width=\"750\" height=\"169\"><\/a><\/span><\/span><\/td><\/tr><tr><td><span style=\"font-size: 24.0px;\"><span><a href=\"http:\/\/item.taobao.com\/meal_detail.htm?meal_id=7702625\" target=\"_blank\"><img border=\"0\" alt=\"\" src=\"http:\/\/img01.taobaocdn.com\/imgextra\/i1\/721217425\/T2zUFsXm0MXXXXXXXX_!!721217425.jpg\" width=\"750\" height=\"120\"><\/a><\/span><\/span><\/td><\/tr><tr><td><span style=\"font-size: 24.0px;\"><span><a href=\"http:\/\/detail.taobao.com\/meal_detail.htm?meal_id=7757745\" target=\"_blank\"><img style=\"margin: 0.0px;width: 750.0px;float: none;height: 113.0px;\" alt=\"\" src=\"http:\/\/img03.taobaocdn.com\/imgextra\/i3\/721217425\/T2tlFvXldMXXXXXXXX_!!721217425.jpg\" width=\"750\" height=\"113\"><\/a><\/span><\/span><\/td><\/tr><tr><td><span style=\"font-size: 24.0px;\"><span><a href=\"http:\/\/item.taobao.com\/meal_detail.htm?meal_id=7717656\" target=\"_blank\"><img style=\"margin: 0.0px;width: 750.0px;float: none;height: 158.0px;\" border=\"0\" alt=\"\" src=\"http:\/\/img03.taobaocdn.com\/imgextra\/i3\/721217425\/T2tbJqXbFNXXXXXXXX_!!721217425.jpg\" width=\"750\" height=\"158\"><\/a><\/span><\/span><\/td><\/tr><\/table><table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" width=\"750\"><tr><td><img alt=\"\" src=\"http:\/\/img03.taobaocdn.com\/imgextra\/i3\/721217425\/T2ksKuXkhaXXXXXXXX_!!721217425.jpg\" width=\"750\" height=\"1015\"><\/td><\/tr><tr><td><img alt=\"\" src=\"http:\/\/img03.taobaocdn.com\/imgextra\/i3\/721217425\/T2SsSuXgFaXXXXXXXX_!!721217425.jpg\" width=\"750\" height=\"1157\"><\/td><\/tr><tr><td><img alt=\"\" src=\"http:\/\/img04.taobaocdn.com\/imgextra\/i4\/721217425\/T2XZ1uXeBaXXXXXXXX_!!721217425.jpg\" width=\"750\" height=\"1495\"><\/td><\/tr><tr><td><img alt=\"\" src=\"http:\/\/img02.taobaocdn.com\/imgextra\/i2\/721217425\/T2Ec5uXcFaXXXXXXXX_!!721217425.jpg\" width=\"750\" height=\"1054\"><\/td><\/tr><tr><td><img alt=\"\" src=\"http:\/\/img04.taobaocdn.com\/imgextra\/i4\/721217425\/T2QcSuXgRaXXXXXXXX_!!721217425.gif\" width=\"750\" height=\"182\"><\/td><\/tr><tr><td><img alt=\"\" src=\"http:\/\/img04.taobaocdn.com\/imgextra\/i4\/721217425\/T2f0auXataXXXXXXXX_!!721217425.jpg\" width=\"750\" height=\"900\"><\/td><\/tr><tr><td><img alt=\"\" src=\"http:\/\/img04.taobaocdn.com\/imgextra\/i4\/721217425\/T27JauXXpaXXXXXXXX_!!721217425.jpg\" width=\"750\" height=\"630\"><\/td><\/tr><tr><td><img alt=\"\" src=\"http:\/\/img03.taobaocdn.com\/imgextra\/i3\/721217425\/T2otiuXnFXXXXXXXXX_!!721217425.jpg\" width=\"750\" height=\"673\"><\/td><\/tr><tr><td><img alt=\"\" src=\"http:\/\/img02.taobaocdn.com\/imgextra\/i2\/721217425\/T2gtmuXmpXXXXXXXXX_!!721217425.jpg\" width=\"750\" height=\"694\"><\/td><\/tr><tr><td><img alt=\"\" src=\"http:\/\/img01.taobaocdn.com\/imgextra\/i1\/721217425\/T2mdquXkNXXXXXXXXX_!!721217425.jpg\" width=\"750\" height=\"706\"><\/td><\/tr><tr><td><img alt=\"\" src=\"http:\/\/img02.taobaocdn.com\/imgextra\/i2\/721217425\/T2c0uuXjBXXXXXXXXX_!!721217425.jpg\" width=\"750\" height=\"598\"><\/td><\/tr><tr><td><img alt=\"\" src=\"http:\/\/img01.taobaocdn.com\/imgextra\/i1\/721217425\/T2qtyuXhNXXXXXXXXX_!!721217425.jpg\" width=\"750\" height=\"1014\"><\/td><\/tr><tr><td><img alt=\"\" src=\"http:\/\/img01.taobaocdn.com\/imgextra\/i1\/721217425\/T2NdCuXfNXXXXXXXXX_!!721217425.jpg\" width=\"750\" height=\"1027\"><\/td><\/tr><tr><td><img alt=\"\" src=\"http:\/\/img01.taobaocdn.com\/imgextra\/i1\/721217425\/T2bdGuXfdXXXXXXXXX_!!721217425.jpg\" width=\"750\" height=\"736\"><\/td><\/tr><\/table><p>&nbsp;<\/p>","detail_url":"http:\/\/item.taobao.com\/item.htm?id=14468433043&spm=2014.12129701.0.0","ems_fee":"0.00","express_fee":"0.00","freight_payer":"seller","has_discount":true,"has_invoice":true,"has_showcase":true,"has_warranty":false,"input_pids":"20000","input_str":"Zobo\/正牌","is_virtual":false,"item_imgs":{"item_img":[{"id":0,"position":0,"url":"http:\/\/img01.taobaocdn.com\/bao\/uploaded\/i1\/T1l62cXd8jXXX54OQU_015232.jpg"},{"id":3530250392,"position":1,"url":"http:\/\/img02.taobaocdn.com\/bao\/uploaded\/i2\/T1SbeyXm4WXXb1IA7Z_033254.jpg"},{"id":3530250393,"position":2,"url":"http:\/\/img02.taobaocdn.com\/bao\/uploaded\/i2\/721217425\/T2mFhEXbVNXXXXXXXX_!!721217425.jpg"},{"id":3530250394,"position":3,"url":"http:\/\/img03.taobaocdn.com\/bao\/uploaded\/i3\/T10.9MXlFuXXb6MMna_090902.jpg"},{"id":5039400011,"position":4,"url":"http:\/\/img03.taobaocdn.com\/bao\/uploaded\/i3\/721217425\/T2eNNTXlFcXXXXXXXX_!!721217425.jpg"}]},"list_time":"2012-05-30 03:29:16","location":{"city":"杭州","state":"浙江"},"modified":"2012-06-06 00:35:53","nick":"zobo正牌旗舰店","num":90178,"num_iid":14468433043,"outer_id":"ZB-053","pic_url":"http:\/\/img01.taobaocdn.com\/bao\/uploaded\/i1\/T1l62cXd8jXXX54OQU_015232.jpg","post_fee":"0.00","postage_id":0,"price":"33.00","property_alias":"","props":"21441:41654;20000:3301703;21440:41650","seller_cids":",488348906,371772612,478675766,","stuff_status":"new","title":"ZOBO正牌 烟嘴 过滤烟嘴 正品 双重循环型烟嘴 可清洗 过滤嘴包邮","type":"fixed","valid_thru":7}}}
@@ -29,7 +29,7 @@ describe Taobao::Category do
29
29
  Taobao.stub(:api_request).with(args).and_return(fixture)
30
30
  category = Taobao::Category.new(-20)
31
31
  lambda {category.name}
32
- .should raise_error Taobao::ApiError, 'Incorrect category ID'
32
+ .should raise_error Taobao::IncorrectCategoryId, 'Incorrect category ID'
33
33
  end
34
34
  end
35
35
 
@@ -1,5 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
+ Response = Struct.new('Responce', :body)
4
+
3
5
  describe Taobao do
4
6
  describe 'set the public API key' do
5
7
  it 'should have rw access' do
@@ -13,14 +15,21 @@ describe Taobao do
13
15
  Taobao.method_defined?(:private_key).should == false
14
16
  end
15
17
  end
16
- describe 'api_request' do
18
+ describe 'API request' do
17
19
  it 'should always return a Hash object' do
18
- Response = Struct.new('Responce', :body)
19
- fixture = Response.new(open('./spec/fixtures/category.json').read)
20
+ fixture = Response.new('category.json'.str_fixture)
20
21
  Net::HTTP.stub(:post_form).and_return(fixture)
21
22
  result = Taobao.api_request(method: 'taobao.itemcats.get',
22
23
  fields: 'cid,parent_cid,name,is_parent', cids: 0)
23
24
  result.class.should == Hash
24
25
  end
25
26
  end
27
+ describe 'failed API request' do
28
+ it 'should throws an exception' do
29
+ fixture = Response.new('error.json'.str_fixture)
30
+ Net::HTTP.stub(:post_form).and_return(fixture)
31
+ lambda { Taobao.api_request({}) }
32
+ .should raise_error Taobao::ApiError, 'Invalid arguments:cid'
33
+ end
34
+ end
26
35
  end
data/spec/spec_helper.rb CHANGED
@@ -9,6 +9,10 @@ end
9
9
  require 'taobaorb'
10
10
 
11
11
  class String
12
+ def str_fixture
13
+ open("spec/fixtures/#{self}").read
14
+ end
15
+
12
16
  def json_fixture
13
17
  contents = open("spec/fixtures/#{self}").read
14
18
  JSON.parse contents, {symbolize_names: true}
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: taobaorb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.2
4
+ version: 0.8.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - m16a1
9
+ - yesmeck
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2012-06-02 00:00:00.000000000 Z
13
+ date: 2012-07-15 00:00:00.000000000 Z
13
14
  dependencies: []
14
15
  description: Ruby wrapper for the Taobao API
15
16
  email: a741su@gmail.com
@@ -19,18 +20,21 @@ extra_rdoc_files: []
19
20
  files:
20
21
  - lib/taobao/base.rb
21
22
  - lib/taobao/category.rb
22
- - lib/taobao/exceptions.rb
23
+ - lib/taobao/exceptions/api_error.rb
24
+ - lib/taobao/exceptions/incorrect_category_id.rb
23
25
  - lib/taobao/product.rb
24
26
  - lib/taobao/product_list.rb
25
27
  - lib/taobao/search.rb
26
28
  - lib/taobaorb.rb
27
29
  - spec/fixtures/category.json
28
30
  - spec/fixtures/category_properties.json
31
+ - spec/fixtures/error.json
29
32
  - spec/fixtures/incorrect_category.json
30
33
  - spec/fixtures/items.json
31
34
  - spec/fixtures/items_page15.json
32
35
  - spec/fixtures/no_items.json
33
36
  - spec/fixtures/product.json
37
+ - spec/fixtures/product_wo_property_alias.json
34
38
  - spec/fixtures/search.json
35
39
  - spec/fixtures/subcategories.json
36
40
  - spec/fixtures/top_category_properties.json
@@ -60,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
60
64
  version: '0'
61
65
  requirements: []
62
66
  rubyforge_project:
63
- rubygems_version: 1.8.23
67
+ rubygems_version: 1.8.24
64
68
  signing_key:
65
69
  specification_version: 3
66
70
  summary: Ruby wrapper for the Taobao API
@@ -1,2 +0,0 @@
1
- class Taobao::ApiError < StandardError
2
- end