taobao_api 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|