taobao-top 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.3@taobao-top --create
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'http://ruby.taobao.org'
2
+
3
+ # Specify your gem's dependencies in taobao-top.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 xixilive
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,145 @@
1
+ # Taobao::Top
2
+
3
+ A simple ruby implementation of Taobao TOP API [淘宝开放平台](http://open.taobao.com)
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'taobao-top'
10
+
11
+ And then execute:
12
+
13
+ $ bundle install
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install taobao-top
18
+
19
+ ## Usage
20
+ ### Configuration
21
+
22
+ For Rails, add following lines in 'config/initializers/taobao_top.rb':
23
+
24
+ ```ruby
25
+ Taobao::TOP.sandbox = !Rails.env.production?
26
+ OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE if Taobao::TOP.sandbox?
27
+ ```
28
+
29
+ ### Invoke a API method:
30
+ ```ruby
31
+ require 'taobao/top'
32
+ ```
33
+
34
+ Init a service instance by following lines:
35
+
36
+ ```ruby
37
+ service = Taobao::TOP::Service.new(APP_KEY, APP_SECRET, :session => "SESSION")
38
+ ```
39
+
40
+ Or
41
+
42
+ ```ruby
43
+ service = Taobao::TOP::Service.new(APP_KEY, APP_SECRET) do |options|
44
+ options.session = "SESSION"
45
+ options.format = "json"
46
+ options.sign_method = "md5"
47
+ end
48
+ ```
49
+
50
+ then invoke a API method:
51
+
52
+ ```ruby
53
+ response = service.get("taobao.users.get", :nick => "test")
54
+ unless response.error?
55
+ user = response.body.user
56
+ p user.nick # => test
57
+ else
58
+ p response.error.code
59
+ p response.error.msg
60
+ p response.error.sub_code
61
+ p response.error.sub_msg
62
+ end
63
+ ```
64
+
65
+ ### Multipart content
66
+ ```ruby
67
+ service = Taobao::TOP::Service.new(APP_KEY, APP_SECRET, :session => "SESSION")
68
+ response = service.post("taobao.item.img.upload", :num_iid=>'1489161932', :image => File.open('example.jpg'))
69
+ ```
70
+
71
+ ### Integrate with OmniAuth
72
+ ```ruby
73
+ require 'taobao/top-oauth' # includes TOP API and Oauth
74
+ ```
75
+
76
+ and Rails initializer at config/initializers/omniauth.rb
77
+
78
+ ```ruby
79
+ Rails.application.config.middleware.use OmniAuth::Builder do
80
+ provider :taobao, TAOBAO_API_KEY, TAOBAO_API_SECRET
81
+ end
82
+ ```
83
+
84
+ and Append a line in routes.rb
85
+
86
+ ```ruby
87
+ get '/auth/:provider/callback', to: 'sessions#create'
88
+ ```
89
+
90
+ and Add following lines in your sessions_controller.rb to initialize a user's session
91
+
92
+ ```ruby
93
+ def create
94
+ @user = User.find_or_create_from_auth_hash(request.env['omniauth.auth'])
95
+ session[:current_user] = @user
96
+ redirect_to '/'
97
+ end
98
+ ```
99
+
100
+ #### How to fetch a user's information from TOP API after 'token callback'
101
+
102
+ By default, the 'taobao_user_role' option is nil in OmniAuth::Strategies::Taobao class, in this case, your will get a simple raw-info hash like this:
103
+
104
+ ```ruby
105
+ {
106
+ "user_id": TAOBAO_USER_ID,
107
+ "nick": TAOBAO_USER_NICKNAME
108
+ }
109
+ ```
110
+
111
+ and you can get a user's information through a TOP API method named 'taobao.user.get' like this:
112
+
113
+ ```ruby
114
+ OmniAuth::Strategies::Taobao.option :taobao_user_role, 'user'
115
+ ```
116
+
117
+ and to use 'taobao.user.buyer.get' like this:
118
+
119
+ ```ruby
120
+ OmniAuth::Strategies::Taobao.option :taobao_user_role, 'buyer'
121
+ ```
122
+
123
+ and to use 'taobao.user.seller.get' like this:
124
+
125
+ ```ruby
126
+ OmniAuth::Strategies::Taobao.option :taobao_user_role, 'seller'
127
+ ```
128
+
129
+ NOTE: you should have avaliable TOP API permissions for above settings. visit [Taobao User API](http://open.taobao.com/doc/api_cat_detail.htm?spm=0.0.0.0.mfYwn5&cat_id=1&category_id=102) for more details.
130
+
131
+ ### SSL verify in Taobao sandbox environment:
132
+
133
+ when you are using Oauth in the 'tbsandbox' env, you should skip verify SSL certification as following:
134
+
135
+ ```ruby
136
+ OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
137
+ ```
138
+
139
+ ## Contributing
140
+
141
+ 1. Fork it
142
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
143
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
144
+ 4. Push to the branch (`git push origin my-new-feature`)
145
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,59 @@
1
+ require 'omniauth'
2
+ require 'omniauth-oauth2'
3
+ require 'taobao/top'
4
+
5
+ module OmniAuth::Strategies
6
+ class Taobao < OmniAuth::Strategies::OAuth2
7
+ option :client_options, ::Taobao::TOP.gateways
8
+ option :taobao_user_role, nil
9
+
10
+ def request_phase
11
+ options[:state] ||= '1'
12
+ super
13
+ end
14
+
15
+ uid { raw_info['user_id'] }
16
+
17
+ info do
18
+ {
19
+ 'name' => raw_info['nick'],
20
+ 'image' => raw_info['avatar']
21
+ }
22
+ end
23
+
24
+ extra do
25
+ { :raw_info => raw_info }
26
+ end
27
+
28
+ def raw_info
29
+ @rawinfo ||= (!!options.taobao_user_role ? fetch_raw_info : fetch_raw_info_from_params)
30
+ end
31
+
32
+ private
33
+ def raw_info_method
34
+ ["taobao", "user", "#{options.taobao_user_role}", "get"].uniq.join(".")
35
+ end
36
+
37
+ def raw_info_fields
38
+ {
39
+ "buyer" => "user_id,nick,sex,avatar,buyer_credit,has_shop,vip_info",
40
+ "seller" => "user_id,nick,sex,avatar,seller_credit,type,has_shop,is_golden_seller,vip_info",
41
+ "user" => "user_id,nick,sex,avatar,email,buyer_credit,seller_credit,location,type,has_shop,vip_info"
42
+ }[options.taobao_user_role.to_s]
43
+ end
44
+
45
+ def fetch_raw_info
46
+ service = ::Taobao::TOP::Service.new(options.client_id, options.client_secret, :session => @access_token.token)
47
+ res = service.get(raw_info_method, :fields => raw_info_fields)
48
+ res.error? ? {} : res.body.user
49
+ end
50
+
51
+ def fetch_raw_info_from_params
52
+ attrs = [["user_id", "taobao_user_id"],["nick", "taobao_user_nick"]]
53
+ Hash[attrs.collect{|arr| [arr[0], @access_token[arr[1]]]}].select{|k,v| v != nil}
54
+ end
55
+
56
+ end
57
+ end
58
+
59
+ ::OmniAuth.config.add_camelization 'taobao', 'Taobao'
@@ -0,0 +1,17 @@
1
+ module Taobao
2
+ module Rails
3
+ class Engine < ::Rails::Engine
4
+
5
+ initializer "taobao.top" do |app|
6
+
7
+ ::Taobao::TOP.sandbox = !::Rails.env.production?
8
+ ::OpenSSL::SSL::VERIFY_PEER = ::OpenSSL::SSL::VERIFY_NONE if ::Taobao::TOP.sandbox?
9
+
10
+ if defined?(::OmniAuth::Strategies::Taobao)
11
+ ::OmniAuth::Strategies::Taobao.option :client_options, ::Taobao::TOP.gateways
12
+ end
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,2 @@
1
+ require 'taobao/top'
2
+ require 'omniauth/strategies/taobao'
@@ -0,0 +1,33 @@
1
+ lib = File.expand_path('../../../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ require "taobao/top/version"
5
+ require 'hashie'
6
+ require 'active_support/core_ext'
7
+
8
+ module Taobao
9
+ module TOP
10
+ mattr_accessor :sandbox
11
+ @@sandbox = false
12
+
13
+ def self.gateways
14
+ domain = self.sandbox? ? "tbsandbox" : "taobao"
15
+ {
16
+ :site => "http://gw.api.#{domain}.com/router/rest",
17
+ :authorize_url => "https://oauth.#{domain}.com/authorize",
18
+ :token_url => "https://oauth.#{domain}.com/token"
19
+ }
20
+ end
21
+
22
+ def self.sandbox?
23
+ !!self.sandbox
24
+ end
25
+
26
+ autoload :Options, 'taobao/top/service.rb'
27
+ autoload :Params, 'taobao/top/service.rb'
28
+ autoload :Service, 'taobao/top/service.rb'
29
+ autoload :Response, 'taobao/top/service.rb'
30
+ end
31
+ end
32
+
33
+ require 'taobao/rails/engine' if defined?(::Rails) && ::Rails::VERSION::MAJOR >= 3
@@ -0,0 +1,106 @@
1
+ require 'digest/md5'
2
+ require 'digest/hmac'
3
+ require 'rest_client'
4
+
5
+ module Taobao
6
+ module TOP
7
+ class Options < ::Hashie::Mash;
8
+ def self.default
9
+ self.new v: '2.0', sign_method: 'md5', format: 'json'
10
+ end
11
+ end
12
+
13
+ class Params < ::Hashie::Mash
14
+
15
+ attr_reader :signature
16
+
17
+ def sign! secret
18
+ str = self.select{|k,v| !multipart?(v) }.sort_by{|k,v| k.to_s }.collect{|i| i.join }.join
19
+ @signature = case self.sign_method.to_s.downcase
20
+ when 'md5' then Digest::MD5.hexdigest("#{secret}#{str}#{secret}").upcase
21
+ when 'hmac' then Digest::HMAC.hexdigest(str, secret, Digest::MD5).upcase
22
+ else ""
23
+ end
24
+ self.sign = @signature
25
+ end
26
+
27
+ private
28
+ def multipart? obj
29
+ obj.respond_to?(:path) && obj.respond_to?(:read)
30
+ end
31
+ end
32
+
33
+ class Response < ::Hashie::Mash
34
+ def self.from_json data
35
+ self.new ActiveSupport::JSON.decode(data)
36
+ end
37
+
38
+ def self.from_xml data
39
+ self.new Hash.from_xml(data)
40
+ end
41
+
42
+ def body
43
+ unless error?
44
+ self[self.keys.first]
45
+ end
46
+ end
47
+
48
+ def error?
49
+ self.error_response
50
+ end
51
+
52
+ def error
53
+ self.error_response if error?
54
+ end
55
+ end
56
+
57
+ class Service
58
+
59
+ attr_reader :options, :params, :response
60
+
61
+ def initialize *args, &block
62
+ @options = TOP::Options.default.dup.merge(args.extract_options!)
63
+ @app_key, @app_secret = args.slice!(0,2)
64
+ raise ArgumentError.new "app_key or app_secret missing!" unless @app_key && @app_secret
65
+ yield @options if block_given?
66
+ end
67
+
68
+ def get method, *args
69
+ invoke method, :get, *args
70
+ end
71
+
72
+ def post method, *args
73
+ invoke method, :post, *args
74
+ end
75
+
76
+ private
77
+ def prepare_params params
78
+ @params = TOP::Params.new params
79
+ @params.app_key = @app_key
80
+ @params.timestamp = Time.now.strftime('%Y-%m-%d %H:%M:%S')
81
+ @params.sign! @app_secret
82
+ end
83
+
84
+ def invoke method, http_method, *args
85
+ prepare_params @options.merge(args.extract_options!).merge(method: method)
86
+ begin
87
+ raw_response = case http_method
88
+ when :get then RestClient.get [TOP.gateways[:site], @params.to_query].join("?")
89
+ when :post then RestClient.post TOP.gateways[:site], @params
90
+ end
91
+ @response = case @params.format.to_s.downcase
92
+ when 'json'
93
+ TOP::Response.from_json(raw_response)
94
+ when 'xml'
95
+ TOP::Response.from_xml(raw_response)
96
+ else
97
+ raw_response
98
+ end
99
+ rescue Exception => e
100
+ RestClient.create_log("stderr") << e
101
+ end
102
+ end
103
+ end
104
+
105
+ end
106
+ end
@@ -0,0 +1,5 @@
1
+ module Taobao
2
+ module Top
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'taobao/top/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "taobao-top"
8
+ spec.version = Taobao::Top::VERSION
9
+ spec.authors = ["xixilive"]
10
+ spec.email = ["xixilive@gmail.com"]
11
+ spec.description = %q{a simple ruby implementation of TOP API}
12
+ spec.summary = %q{a simple ruby implementation of TOP API}
13
+ spec.homepage = "https://github.com/xixilive/taobao-top"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "hashie", '~> 2.0'
22
+ spec.add_dependency "activesupport", ['>= 3.2','< 4']
23
+ spec.add_dependency "rest-client", "~> 1.6.0"
24
+ spec.add_dependency "omniauth", '~> 1.1'
25
+ spec.add_dependency "omniauth-oauth2", '~> 1.1'
26
+
27
+ spec.add_development_dependency "bundler", "~> 1.3"
28
+ spec.add_development_dependency "rake"
29
+ end
metadata ADDED
@@ -0,0 +1,177 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: taobao-top
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - xixilive
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-07-16 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: hashie
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '2.0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activesupport
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '3.2'
38
+ - - <
39
+ - !ruby/object:Gem::Version
40
+ version: '4'
41
+ type: :runtime
42
+ prerelease: false
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '3.2'
49
+ - - <
50
+ - !ruby/object:Gem::Version
51
+ version: '4'
52
+ - !ruby/object:Gem::Dependency
53
+ name: rest-client
54
+ requirement: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ~>
58
+ - !ruby/object:Gem::Version
59
+ version: 1.6.0
60
+ type: :runtime
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ~>
66
+ - !ruby/object:Gem::Version
67
+ version: 1.6.0
68
+ - !ruby/object:Gem::Dependency
69
+ name: omniauth
70
+ requirement: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '1.1'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ~>
82
+ - !ruby/object:Gem::Version
83
+ version: '1.1'
84
+ - !ruby/object:Gem::Dependency
85
+ name: omniauth-oauth2
86
+ requirement: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ~>
90
+ - !ruby/object:Gem::Version
91
+ version: '1.1'
92
+ type: :runtime
93
+ prerelease: false
94
+ version_requirements: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ~>
98
+ - !ruby/object:Gem::Version
99
+ version: '1.1'
100
+ - !ruby/object:Gem::Dependency
101
+ name: bundler
102
+ requirement: !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ~>
106
+ - !ruby/object:Gem::Version
107
+ version: '1.3'
108
+ type: :development
109
+ prerelease: false
110
+ version_requirements: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ~>
114
+ - !ruby/object:Gem::Version
115
+ version: '1.3'
116
+ - !ruby/object:Gem::Dependency
117
+ name: rake
118
+ requirement: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ! '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ description: a simple ruby implementation of TOP API
133
+ email:
134
+ - xixilive@gmail.com
135
+ executables: []
136
+ extensions: []
137
+ extra_rdoc_files: []
138
+ files:
139
+ - .gitignore
140
+ - .rvmrc
141
+ - Gemfile
142
+ - LICENSE.txt
143
+ - README.md
144
+ - Rakefile
145
+ - lib/omniauth/strategies/taobao.rb
146
+ - lib/taobao/rails/engine.rb
147
+ - lib/taobao/top-oauth.rb
148
+ - lib/taobao/top.rb
149
+ - lib/taobao/top/service.rb
150
+ - lib/taobao/top/version.rb
151
+ - taobao-top.gemspec
152
+ homepage: https://github.com/xixilive/taobao-top
153
+ licenses:
154
+ - MIT
155
+ post_install_message:
156
+ rdoc_options: []
157
+ require_paths:
158
+ - lib
159
+ required_ruby_version: !ruby/object:Gem::Requirement
160
+ none: false
161
+ requirements:
162
+ - - ! '>='
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ required_rubygems_version: !ruby/object:Gem::Requirement
166
+ none: false
167
+ requirements:
168
+ - - ! '>='
169
+ - !ruby/object:Gem::Version
170
+ version: '0'
171
+ requirements: []
172
+ rubyforge_project:
173
+ rubygems_version: 1.8.25
174
+ signing_key:
175
+ specification_version: 3
176
+ summary: a simple ruby implementation of TOP API
177
+ test_files: []