taobao_api 0.2.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/COPYING +1 -0
- data/LICENSE +1 -0
- data/README +5 -0
- data/Rakefile +61 -0
- data/lib/taobao_api.rb +7 -0
- data/lib/taobao_api/base_api.rb +69 -0
- data/lib/taobao_api/deal.rb +95 -0
- data/lib/taobao_api/evaluate.rb +14 -0
- data/lib/taobao_api/evaluate_list.rb +40 -0
- data/lib/taobao_api/init.rb +6 -0
- data/lib/taobao_api/shop.rb +57 -0
- data/lib/taobao_api/user.rb +59 -0
- data/lib/taobao_api/util/hash.rb +37 -0
- data/resources/defaults.yaml +2 -0
- metadata +95 -0
data/COPYING
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
No copying restrictions/license given.
|
data/LICENSE
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
No license given.
|
data/README
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
require 'rake/rdoctask'
|
6
|
+
require 'fileutils'
|
7
|
+
include FileUtils
|
8
|
+
|
9
|
+
version="0.2.1"
|
10
|
+
name="taobao_api"
|
11
|
+
|
12
|
+
spec = Gem::Specification.new do |s|
|
13
|
+
s.name = name
|
14
|
+
s.version = version
|
15
|
+
s.description = s.summary = "The taobao_api GemPlugin"
|
16
|
+
s.author = "tumayun"
|
17
|
+
s.add_dependency('gem_plugin', '>= 0.2.3')
|
18
|
+
|
19
|
+
s.platform = Gem::Platform::RUBY
|
20
|
+
s.has_rdoc = true
|
21
|
+
s.extra_rdoc_files = ["README"]
|
22
|
+
|
23
|
+
s.files = %w(COPYING LICENSE README Rakefile) +
|
24
|
+
Dir.glob("{bin,doc/rdoc,test,lib}/**/*") +
|
25
|
+
Dir.glob("ext/**/*.{h,c,rb}") +
|
26
|
+
Dir.glob("examples/**/*.rb") +
|
27
|
+
Dir.glob("tools/*.rb") +
|
28
|
+
Dir.glob("resources/**/*")
|
29
|
+
|
30
|
+
s.require_path = "lib"
|
31
|
+
s.bindir = "bin"
|
32
|
+
end
|
33
|
+
|
34
|
+
Rake::GemPackageTask.new(spec) do |p|
|
35
|
+
p.need_tar = true if RUBY_PLATFORM !~ /mswin/
|
36
|
+
end
|
37
|
+
|
38
|
+
task :install => [:test, :package] do
|
39
|
+
sh %{sudo gem install pkg/#{name}-#{version}.gem}
|
40
|
+
end
|
41
|
+
|
42
|
+
task :uninstall => [:clean] do
|
43
|
+
sh %{sudo gem uninstall #{name}}
|
44
|
+
end
|
45
|
+
|
46
|
+
Rake::TestTask.new do |t|
|
47
|
+
t.libs << "test"
|
48
|
+
t.test_files = FileList['test/test*.rb']
|
49
|
+
t.verbose = true
|
50
|
+
end
|
51
|
+
|
52
|
+
Rake::RDocTask.new do |rdoc|
|
53
|
+
rdoc.rdoc_dir = 'doc/rdoc'
|
54
|
+
rdoc.options << '--line-numbers'
|
55
|
+
rdoc.rdoc_files.add ['README', 'LICENSE', 'COPYING', 'lib/**/*.rb', 'doc/**/*.rdoc']
|
56
|
+
end
|
57
|
+
|
58
|
+
task :default => [:test, :package]
|
59
|
+
|
60
|
+
CLEAN.include ['build/*', '**/*.o', '**/*.so', '**/*.a', 'lib/*-*', '**/*.log', 'pkg', 'lib/*.bundle', '*.gem', '.config']
|
61
|
+
|
data/lib/taobao_api.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
require 'md5'
|
4
|
+
require 'timeout'
|
5
|
+
module TaobaoApi
|
6
|
+
|
7
|
+
module BaseApi
|
8
|
+
class ConfigKeysError < StandardError; end
|
9
|
+
class ConfigValuesError < StandardError; end
|
10
|
+
|
11
|
+
mattr_reader :config
|
12
|
+
|
13
|
+
def self.included(receiver)
|
14
|
+
receiver.extend ClassMethods
|
15
|
+
receiver.send :include, InstanceMethods
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.init_config
|
19
|
+
@@config = YAML::load_file("#{RAILS_ROOT}/config/taobao_api.yml")['taobao_api'].symbolize_keys
|
20
|
+
valid_config
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.valid_config
|
24
|
+
@@config.assert_valid_keys :api_url, :secret_code, :pid, :api_key, :timeout, :outer_code rescue raise ConfigKeysError.new
|
25
|
+
@@config.values.map { |v| raise ConfigValuesError.new if v.blank? }
|
26
|
+
end
|
27
|
+
|
28
|
+
init_config
|
29
|
+
|
30
|
+
module ClassMethods
|
31
|
+
|
32
|
+
#获得淘宝API返回的json数据
|
33
|
+
#返回结果是Hash
|
34
|
+
def taobao_api_get(options = {})
|
35
|
+
Timeout::timeout(BaseApi.config[:timeout].to_f) do
|
36
|
+
return ActiveResource::Formats::JsonFormat.decode(Net::HTTP.post_form(URI::parse(BaseApi.config[:api_url]), get_taobao_options(options)).body)
|
37
|
+
end
|
38
|
+
rescue Exception => e
|
39
|
+
ActiveRecord::Base.logger.error("#{e}\n#{e.backtrace.join('\n')}")
|
40
|
+
return {}
|
41
|
+
end
|
42
|
+
|
43
|
+
protected
|
44
|
+
#get taobao request options
|
45
|
+
def get_taobao_options(options = {})
|
46
|
+
taobao_options = taobao_config_options.merge(options)
|
47
|
+
taobao_options[:sign] = encrypt(taobao_options.stringify_keys.sort.flatten.join).upcase
|
48
|
+
taobao_options
|
49
|
+
end
|
50
|
+
|
51
|
+
def taobao_config_options
|
52
|
+
{
|
53
|
+
:api_key => BaseApi.config[:api_key],
|
54
|
+
:format => 'json',
|
55
|
+
:v => '2.0',
|
56
|
+
:sign_method => 'md5'
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def encrypt(str)
|
61
|
+
MD5.hexdigest(BaseApi.config[:secret_code] + str + BaseApi.config[:secret_code])
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
module InstanceMethods
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require "util/hash"
|
2
|
+
module TaobaoApi
|
3
|
+
|
4
|
+
class Deal
|
5
|
+
include BaseApi
|
6
|
+
|
7
|
+
cattr_reader :configurable_attrs
|
8
|
+
@@configurable_attrs = [:click_url, :wap_detail_url, :nick, :desc, :num_iid, :props_name, :wap_click_url]
|
9
|
+
attr_reader *@@configurable_attrs
|
10
|
+
|
11
|
+
def @@configurable_attrs.<<(item)
|
12
|
+
return self if item.blank?
|
13
|
+
super(item.to_sym).uniq!
|
14
|
+
TaobaoApi::Deal.send :attr_reader, item.to_sym
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.get_taobao_deal(num_iid)
|
19
|
+
options = get_result(num_iid)
|
20
|
+
return nil if options.blank?
|
21
|
+
|
22
|
+
new options
|
23
|
+
end
|
24
|
+
|
25
|
+
#获取指定id的淘宝商品推广url
|
26
|
+
def self.get_taobao_cps_url(num_iid)
|
27
|
+
options = {
|
28
|
+
:method => 'taobao.taobaoke.items.detail.get',
|
29
|
+
:timestamp => Time.now.to_s(:db),
|
30
|
+
:num_iids => num_iid,
|
31
|
+
:pid => BaseApi.config[:pid],
|
32
|
+
:outer_code => BaseApi.config[:outer_code],
|
33
|
+
:fields => 'click_url'
|
34
|
+
}
|
35
|
+
|
36
|
+
taobao_api_get(options).search('click_url')
|
37
|
+
end
|
38
|
+
|
39
|
+
#获取指定id的淘宝商品wap推广url
|
40
|
+
def self.get_taobao_wap_cps_url(num_iid)
|
41
|
+
options = {
|
42
|
+
:method => 'taobao.taobaoke.items.convert',
|
43
|
+
:timestamp => Time.now.to_s(:db),
|
44
|
+
:num_iids => num_iid,
|
45
|
+
:pid => BaseApi.config[:pid],
|
46
|
+
:outer_code => BaseApi.config[:outer_code],
|
47
|
+
:fields => 'click_url',
|
48
|
+
:is_mobile => true
|
49
|
+
}
|
50
|
+
|
51
|
+
glue_taobaoke_wap_cps_url(num_iid, taobao_api_get(options).search('click_url'))
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
def initialize(options)
|
56
|
+
@@configurable_attrs.each do |attr_name|
|
57
|
+
instance_variable_set("@#{attr_name}", options.search(attr_name.to_s))
|
58
|
+
end
|
59
|
+
@click_url = get_taobao_cps_url
|
60
|
+
@wap_click_url = get_taobao_wap_cps_url
|
61
|
+
end
|
62
|
+
|
63
|
+
def get_taobao_cps_url
|
64
|
+
self.class.get_taobao_cps_url(@num_iid)
|
65
|
+
end
|
66
|
+
|
67
|
+
def get_taobao_wap_cps_url
|
68
|
+
self.class.get_taobao_wap_cps_url(@num_iid)
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.get_tks(wap_taobao_cps_url)
|
72
|
+
wap_taobao_cps_url.scan(/tks=([^& $]+)/).flatten.first
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.glue_taobaoke_wap_cps_url(num_iid, click_url)
|
76
|
+
"http://a.m.taobao.com/i#{num_iid}.htm?tks=#{get_tks(click_url)}&ttid=#{generate_ttid}" if click_url.present?
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.generate_ttid
|
80
|
+
"400000_#{BaseApi.config[:api_key]}@t800wx_Tao800Wap_0.0.0"
|
81
|
+
end
|
82
|
+
|
83
|
+
#获取deal详情 Hash
|
84
|
+
def self.get_result(num_iid)
|
85
|
+
options = {
|
86
|
+
:method => 'taobao.item.get',
|
87
|
+
:timestamp => Time.now.to_s(:db),
|
88
|
+
:num_iid => num_iid,
|
89
|
+
:fields => @@configurable_attrs.join(',')
|
90
|
+
}
|
91
|
+
|
92
|
+
taobao_api_get(options).search('item') || {}
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module TaobaoApi
|
2
|
+
|
3
|
+
class Evaluate
|
4
|
+
|
5
|
+
ATTRIBUTE_NAMES = [:reply, :created, :nick, :content, :oid, :result, :tid, :role, :level]
|
6
|
+
attr_reader *ATTRIBUTE_NAMES
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
ATTRIBUTE_NAMES.each do |attr_name|
|
10
|
+
instance_variable_set("@#{attr_name}", options[attr_name.to_s])
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module TaobaoApi
|
2
|
+
|
3
|
+
class EvaluateList
|
4
|
+
include BaseApi
|
5
|
+
|
6
|
+
attr_reader :evaluate_size, :evaluates
|
7
|
+
|
8
|
+
def initialize(num_iid, seller_nick)
|
9
|
+
options = self.class.get_result(num_iid, seller_nick)
|
10
|
+
@evaluate_size = options.search('total_results').to_i
|
11
|
+
init_evaluates(options.search('trade_rate'))
|
12
|
+
end
|
13
|
+
|
14
|
+
protected
|
15
|
+
#获取指定tao_deal的评价列表 Hash
|
16
|
+
def self.get_result(num_iid, seller_nick)
|
17
|
+
options = {
|
18
|
+
:method => 'taobao.traderates.search',
|
19
|
+
:timestamp => Time.now.to_s(:db),
|
20
|
+
:num_iid => num_iid,
|
21
|
+
:seller_nick => seller_nick,
|
22
|
+
:page_no => 1,
|
23
|
+
:page_size => 10
|
24
|
+
}
|
25
|
+
|
26
|
+
taobao_api_get(options) || {}
|
27
|
+
end
|
28
|
+
|
29
|
+
def init_evaluates(options = {})
|
30
|
+
@evaluates = []
|
31
|
+
return if @evaluate_size == 0
|
32
|
+
level_hash_of_users = TaobaoApi::User.get_buyer_users_level(options.collect{ |t| t['nick'] })
|
33
|
+
|
34
|
+
options.each do |evaluate_options|
|
35
|
+
evaluate_options['level'] = level_hash_of_users[evaluate_options['nick']].to_i
|
36
|
+
@evaluates << TaobaoApi::Evaluate.new(evaluate_options)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'util/hash'
|
2
|
+
module TaobaoApi
|
3
|
+
|
4
|
+
class Shop
|
5
|
+
include BaseApi
|
6
|
+
|
7
|
+
cattr_reader :configurable_attrs
|
8
|
+
@@configurable_attrs = [:nick, :level, :title, :created, :address, :item_score, :service_score, :delivery_score, :praise_rate, :type, :shop_score]
|
9
|
+
attr_reader *@@configurable_attrs
|
10
|
+
|
11
|
+
def @@configurable_attrs.<<(item)
|
12
|
+
return self if item.blank?
|
13
|
+
super(item.to_sym).uniq!
|
14
|
+
TaobaoApi::Shop.send :attr_reader, item.to_sym
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.get_taobao_shop(nick)
|
19
|
+
options = get_result(nick)
|
20
|
+
return nil if options.blank?
|
21
|
+
|
22
|
+
new options
|
23
|
+
end
|
24
|
+
|
25
|
+
def is_tmall?
|
26
|
+
@type == 'B'
|
27
|
+
end
|
28
|
+
|
29
|
+
def is_taobao?
|
30
|
+
@type == 'C'
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
def initialize(options)
|
35
|
+
@@configurable_attrs.each do |attr_name|
|
36
|
+
instance_variable_set("@#{attr_name}", options.search(attr_name.to_s))
|
37
|
+
end
|
38
|
+
|
39
|
+
taobao_user = TaobaoApi::User.new(@nick)
|
40
|
+
@praise_rate = taobao_user.praise_rate
|
41
|
+
@address = taobao_user.address
|
42
|
+
@level = taobao_user.level
|
43
|
+
@type = taobao_user.type
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.get_result(nick)
|
47
|
+
options = {
|
48
|
+
:method => 'taobao.shop.get',
|
49
|
+
:timestamp => Time.now.to_s(:db),
|
50
|
+
:nick => nick,
|
51
|
+
:fields => @@configurable_attrs.join(',')
|
52
|
+
}
|
53
|
+
|
54
|
+
taobao_api_get(options).search('shop') || {}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'util/hash'
|
2
|
+
module TaobaoApi
|
3
|
+
|
4
|
+
class User
|
5
|
+
include BaseApi
|
6
|
+
|
7
|
+
cattr_reader :configurable_attrs
|
8
|
+
@@configurable_attrs = [:address, :level, :praise_rate, :type, :seller_credit, :nick, :location]
|
9
|
+
attr_reader *@@configurable_attrs
|
10
|
+
|
11
|
+
def @@configurable_attrs.<<(item)
|
12
|
+
return self if item.blank?
|
13
|
+
super(item.to_sym).uniq!
|
14
|
+
TaobaoApi::User.send :attr_reader, item.to_sym
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(nick)
|
19
|
+
return if (options = self.class.get_result(nick)).blank?
|
20
|
+
|
21
|
+
@@configurable_attrs.each do |attr_name|
|
22
|
+
instance_variable_set("@#{attr_name}", options.search(attr_name.to_s))
|
23
|
+
end
|
24
|
+
|
25
|
+
@level = @level.to_i
|
26
|
+
@praise_rate = count_praise_rate(options)
|
27
|
+
@address = get_address(options)
|
28
|
+
end
|
29
|
+
|
30
|
+
#获得买家用户等级
|
31
|
+
#返回Hash { 'tumayun' => 10, 'jcw' => 12 }
|
32
|
+
#get_buyer_users_level('tumayun', 'jcw')
|
33
|
+
def self.get_buyer_users_level(*nicks)
|
34
|
+
options = { :method => 'taobao.users.get', :timestamp => Time.now.to_s(:db), :fields => 'nick, buyer_credit', :nicks => nicks.join(',') }
|
35
|
+
users = taobao_api_get(options).search('user') || []
|
36
|
+
users.inject({}){ |h, user| h[user['nick']] = user['buyer_credit'].try(:[], 'level'); h }
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
#获得淘宝API请求结果 Hash
|
41
|
+
def self.get_result(nick)
|
42
|
+
options = { :method => 'taobao.user.get', :timestamp => Time.now.to_s(:db), :fields => @@configurable_attrs.join(','), :nick => nick }
|
43
|
+
|
44
|
+
taobao_api_get(options).search('user') || {}
|
45
|
+
end
|
46
|
+
|
47
|
+
#计算的好评率
|
48
|
+
def count_praise_rate(options = {})
|
49
|
+
total_num = options.search('total_num').to_i
|
50
|
+
return 0 if total_num == 0
|
51
|
+
good_num = options.search('good_num').to_f
|
52
|
+
"%.2f" % (good_num * 100 / total_num)
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_address(options = {})
|
56
|
+
[options.search('state'), options.search('city')].compact.join(',')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class Hash
|
2
|
+
|
3
|
+
#def try_get(*args)
|
4
|
+
#args.each do |arg|
|
5
|
+
#return nil unless options.is_a? ::Hash || options.has_key?(arg)
|
6
|
+
#options = options[arg]
|
7
|
+
#end
|
8
|
+
#options
|
9
|
+
#end
|
10
|
+
|
11
|
+
#case_sym 表示是否区分string和symbol
|
12
|
+
def search(key, case_sym = false)
|
13
|
+
h = self.clone
|
14
|
+
h.symbolize_keys! and key = key.to_sym if case_sym
|
15
|
+
|
16
|
+
h.nested_find(key)
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
def nested_find(key)
|
21
|
+
h = self
|
22
|
+
return h[key] if h.has_key?(key)
|
23
|
+
|
24
|
+
value = nil
|
25
|
+
keys.each do |k|
|
26
|
+
tmp = h[k]
|
27
|
+
if tmp.is_a? Array
|
28
|
+
tmp.flatten!
|
29
|
+
tmp.each do |item|
|
30
|
+
return value if item.respond_to?(:nested_find) && (value = item.nested_find(key)).present?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
return value if tmp.respond_to?(:nested_find) && (value = tmp.nested_find(key)).present?
|
34
|
+
end
|
35
|
+
value
|
36
|
+
end
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: taobao_api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 21
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
- 1
|
10
|
+
version: 0.2.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- tumayun
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-04-26 00:00:00 +08:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: gem_plugin
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 17
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 2
|
33
|
+
- 3
|
34
|
+
version: 0.2.3
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
description: The taobao_api GemPlugin
|
38
|
+
email:
|
39
|
+
executables: []
|
40
|
+
|
41
|
+
extensions: []
|
42
|
+
|
43
|
+
extra_rdoc_files:
|
44
|
+
- README
|
45
|
+
files:
|
46
|
+
- COPYING
|
47
|
+
- LICENSE
|
48
|
+
- README
|
49
|
+
- Rakefile
|
50
|
+
- lib/taobao_api.rb
|
51
|
+
- lib/taobao_api/shop.rb
|
52
|
+
- lib/taobao_api/user.rb
|
53
|
+
- lib/taobao_api/evaluate_list.rb
|
54
|
+
- lib/taobao_api/deal.rb
|
55
|
+
- lib/taobao_api/evaluate.rb
|
56
|
+
- lib/taobao_api/init.rb
|
57
|
+
- lib/taobao_api/base_api.rb
|
58
|
+
- lib/taobao_api/util/hash.rb
|
59
|
+
- resources/defaults.yaml
|
60
|
+
has_rdoc: true
|
61
|
+
homepage:
|
62
|
+
licenses: []
|
63
|
+
|
64
|
+
post_install_message:
|
65
|
+
rdoc_options: []
|
66
|
+
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
hash: 3
|
75
|
+
segments:
|
76
|
+
- 0
|
77
|
+
version: "0"
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
hash: 3
|
84
|
+
segments:
|
85
|
+
- 0
|
86
|
+
version: "0"
|
87
|
+
requirements: []
|
88
|
+
|
89
|
+
rubyforge_project:
|
90
|
+
rubygems_version: 1.3.7
|
91
|
+
signing_key:
|
92
|
+
specification_version: 3
|
93
|
+
summary: The taobao_api GemPlugin
|
94
|
+
test_files: []
|
95
|
+
|