weibo2s 0.1.0
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 +18 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.md +93 -0
- data/Rakefile +2 -0
- data/example/.sass-cache/80b2331c862c6e430e0af18caf62d12d982610f0/screen.sassc +0 -0
- data/example/.sass-cache/faf9751221db0b5ce76d45351b9591c3bfc59441/screen.sassc +0 -0
- data/example/Gemfile +7 -0
- data/example/config/weibo.yml +9 -0
- data/example/config/weibo_api.yml +35 -0
- data/example/config.ru +2 -0
- data/example/example.rb +92 -0
- data/example/views/index.haml +42 -0
- data/example/views/layout.haml +12 -0
- data/example/views/screen.sass +13 -0
- data/lib/weibo2s/access_token.rb +20 -0
- data/lib/weibo2s/api/v2/base.rb +120 -0
- data/lib/weibo2s/base.rb +6 -0
- data/lib/weibo2s/client.rb +74 -0
- data/lib/weibo2s/config.rb +38 -0
- data/lib/weibo2s/oauth.rb +6 -0
- data/lib/weibo2s/strategy/auth_code.rb +12 -0
- data/lib/weibo2s/version.rb +19 -0
- data/lib/weibo2s.rb +26 -0
- data/spec/client_spec.rb +44 -0
- data/weibo.yml.example +9 -0
- data/weibo2s.gemspec +24 -0
- data/weibo_api.yml.example +35 -0
- metadata +154 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2012 simsicon
|
|
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.
|
data/README.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
|
|
2
|
+
谢谢 simsicon 的 https://github.com/simsicon/weibo_2
|
|
3
|
+
|
|
4
|
+
这个sdk请求weibo的api的方法是根据weibo_api.yml动态生成的。当微博的api接口有所变动时,可以更改weibo_api.yml来进行更新
|
|
5
|
+
|
|
6
|
+
# WeiboOAuth2
|
|
7
|
+
|
|
8
|
+
Ruby gem weibo's v2 SDK [API](http://open.weibo.com/wiki/API%E6%96%87%E6%A1%A3_V2)
|
|
9
|
+
|
|
10
|
+
## 安装
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
$ get clone https://github.com/cloudorz/weibo_2.git
|
|
14
|
+
$ rake install
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 使用
|
|
18
|
+
具体是用看 example, 请修改congig/weibo.yml中的api_key和api_secret
|
|
19
|
+
|
|
20
|
+
配置 api_key 和 api_secret
|
|
21
|
+
|
|
22
|
+
1.
|
|
23
|
+
|
|
24
|
+
可以将weibo.yml放在你项目目录的config/weibo.yml
|
|
25
|
+
详见 weibo.yml.example
|
|
26
|
+
|
|
27
|
+
2.
|
|
28
|
+
```ruby
|
|
29
|
+
WeiboOAuth2::Config.api_key = YOUR_KEY
|
|
30
|
+
WeiboOAuth2::Config.api_secret = YOUR_SECRET
|
|
31
|
+
WeiboOAuth2::Config.redirect_uri = YOUR_CALLBACK_URL
|
|
32
|
+
```
|
|
33
|
+
配置微博api接口的yml
|
|
34
|
+
详见weibo_api.yml.example
|
|
35
|
+
config/weibo_api.yml
|
|
36
|
+
|
|
37
|
+
1. 如何获取token
|
|
38
|
+
|
|
39
|
+
设置 YOUR_CALLBACK_URL as 'http://127.0.0.1/callback'
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
```ruby
|
|
43
|
+
client = WeiboOAuth2::Client.new
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
生成重定向URL
|
|
47
|
+
|
|
48
|
+
```ruby
|
|
49
|
+
client.authorize_url
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
在回调方法中添加下面这样代码
|
|
53
|
+
|
|
54
|
+
```ruby
|
|
55
|
+
client.auth_code.get_token(params[:code])
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
这样就获得到token
|
|
59
|
+
|
|
60
|
+
2. 使用api发送微博
|
|
61
|
+
|
|
62
|
+
发送普通微博
|
|
63
|
+
|
|
64
|
+
```ruby
|
|
65
|
+
client.statuses.update({:status => "test"})
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
发送带图的微博
|
|
69
|
+
|
|
70
|
+
```ruby
|
|
71
|
+
tmpfile = params[:file][:tempfile]
|
|
72
|
+
pic = File.open(tmpfile.path)
|
|
73
|
+
client.statuses.upload({:status => "分享图片", :pic => pic})
|
|
74
|
+
```
|
|
75
|
+
## 设置SSL
|
|
76
|
+
|
|
77
|
+
### Ubuntu
|
|
78
|
+
|
|
79
|
+
`openssl version -a`.中OPENSSLDIR的路径追加 `/certs` 例如: `/usr/lib/ssl/certs`.
|
|
80
|
+
|
|
81
|
+
```ruby
|
|
82
|
+
client = WeiboOAuth2::Client.new(YOUR_KEY, YOUR_SECRET, :ssl => {:ca_path => "/usr/lib/ssl/certs"})
|
|
83
|
+
# 下面是你在WeiboOAuth2::Config中设置过api_key, api_secret
|
|
84
|
+
# client = WeiboOAuth2::Client.new('', '', :ssl => {:ca_path => "/usr/lib/ssl/certs"})
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### 在 Heroku, Fedora, CentOS
|
|
88
|
+
|
|
89
|
+
```ruby
|
|
90
|
+
client = WeiboOAuth2::Client.new(YOUR_KEY, YOUR_SECRET, :ssl => {:ca_file => '/usr/lib/ssl/certs/ca-certificates.crt'})
|
|
91
|
+
# 下面是你在WeiboOAuth2::Config中设置过api_key, api_secret
|
|
92
|
+
# client = WeiboOAuth2::Client.new('', '', :ssl => {:ca_file => '/usr/lib/ssl/certs/ca-certificates.crt'})
|
|
93
|
+
```
|
data/Rakefile
ADDED
data/example/Gemfile
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
statuses:
|
|
2
|
+
public_timeline:
|
|
3
|
+
url: statuses/public_timeline.json
|
|
4
|
+
friends_timeline:
|
|
5
|
+
url: statuses/friends_timeline.json
|
|
6
|
+
home_timeline:
|
|
7
|
+
url: statuses/home_timeline.json
|
|
8
|
+
destroy:
|
|
9
|
+
url: statuses/destory.json
|
|
10
|
+
method: POST
|
|
11
|
+
update:
|
|
12
|
+
url: statuses/update.json
|
|
13
|
+
method: POST
|
|
14
|
+
upload:
|
|
15
|
+
url: statuses/upload.json
|
|
16
|
+
method: POST
|
|
17
|
+
attachment: true
|
|
18
|
+
upload_url_text:
|
|
19
|
+
url: statuses/upload_url_text.json
|
|
20
|
+
method: POST
|
|
21
|
+
emotions:
|
|
22
|
+
url: emotions.json
|
|
23
|
+
users:
|
|
24
|
+
show:
|
|
25
|
+
url: users/show.json
|
|
26
|
+
domain_show:
|
|
27
|
+
url: user/domain_show.json
|
|
28
|
+
counts:
|
|
29
|
+
url: users/counts.json
|
|
30
|
+
remind:
|
|
31
|
+
unread_count:
|
|
32
|
+
url: https://rm.api.weibo.com/2/remind/unread_count.json
|
|
33
|
+
set_count:
|
|
34
|
+
url: https://rm.api.weibo.com/2/remind/set_count.json
|
|
35
|
+
method: POST
|
data/example/config.ru
ADDED
data/example/example.rb
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'weibo2s'
|
|
4
|
+
require 'time-ago-in-words'
|
|
5
|
+
|
|
6
|
+
%w(rubygems bundler).each { |dependency| require dependency }
|
|
7
|
+
Bundler.setup
|
|
8
|
+
%w(sinatra haml sass).each { |dependency| require dependency }
|
|
9
|
+
enable :sessions
|
|
10
|
+
|
|
11
|
+
#WeiboOAuth2::Config.api_key = ENV['KEY']
|
|
12
|
+
#WeiboOAuth2::Config.api_secret = ENV['SECRET']
|
|
13
|
+
WeiboOAuth2::Config.redirect_uri = "http://codewoow.com:4567/callback"
|
|
14
|
+
|
|
15
|
+
get '/' do
|
|
16
|
+
client = WeiboOAuth2::Client.new
|
|
17
|
+
if session[:access_token] && !client.authorized?
|
|
18
|
+
token = client.get_token_from_hash({:access_token => session[:access_token], :expires_at => session[:expires_at]})
|
|
19
|
+
p "*" * 80 + "validated"
|
|
20
|
+
p token.inspect
|
|
21
|
+
p token.validated?
|
|
22
|
+
|
|
23
|
+
unless token.validated?
|
|
24
|
+
reset_session
|
|
25
|
+
redirect '/connect'
|
|
26
|
+
return
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
puts "ok 1" if client.respond_to? :statuses
|
|
31
|
+
puts "ok 2" if client.statuses.respond_to? :update
|
|
32
|
+
puts "ok 3" if client.respond_to? :atuses_nono
|
|
33
|
+
puts "ok 4" if client.statuses.respond_to? :atuse
|
|
34
|
+
|
|
35
|
+
if session[:uid]
|
|
36
|
+
@user = client.users.show({:uid => session[:uid].to_i})
|
|
37
|
+
@statuses = client.statuses
|
|
38
|
+
end
|
|
39
|
+
haml :index
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
get '/connect' do
|
|
43
|
+
client = WeiboOAuth2::Client.new
|
|
44
|
+
redirect client.authorize_url
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
get '/callback' do
|
|
48
|
+
client = WeiboOAuth2::Client.new
|
|
49
|
+
access_token = client.auth_code.get_token(params[:code].to_s)
|
|
50
|
+
session[:uid] = access_token.params["uid"]
|
|
51
|
+
session[:access_token] = access_token.token
|
|
52
|
+
session[:expires_at] = access_token.expires_at
|
|
53
|
+
p "*" * 80 + "callback"
|
|
54
|
+
p access_token.inspect
|
|
55
|
+
#@user = client.users.show_by_uid(session[:uid].to_i)
|
|
56
|
+
@user = client.users.show({:uid => session[:uid].to_i})
|
|
57
|
+
redirect '/'
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
get '/logout' do
|
|
61
|
+
reset_session
|
|
62
|
+
redirect '/'
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
get '/screen.css' do
|
|
66
|
+
content_type 'text/css'
|
|
67
|
+
sass :screen
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
post '/update' do
|
|
71
|
+
client = WeiboOAuth2::Client.new
|
|
72
|
+
client.get_token_from_hash({:access_token => session[:access_token], :expires_at => session[:expires_at]})
|
|
73
|
+
statuses = client.statuses
|
|
74
|
+
|
|
75
|
+
unless params[:file] && (tmpfile = params[:file][:tempfile]) && (name = params[:file][:filename])
|
|
76
|
+
statuses.update({:status => params[:status]})
|
|
77
|
+
else
|
|
78
|
+
status = params[:status] || '图片'
|
|
79
|
+
pic = File.open(tmpfile.path)
|
|
80
|
+
statuses.upload({:status => params[:status], :pic => pic})
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
redirect '/'
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
helpers do
|
|
87
|
+
def reset_session
|
|
88
|
+
session[:uid] = nil
|
|
89
|
+
session[:access_token] = nil
|
|
90
|
+
session[:expires_at] = nil
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
-if @user
|
|
2
|
+
%p
|
|
3
|
+
%h5
|
|
4
|
+
hello! you are
|
|
5
|
+
=@user.screen_name
|
|
6
|
+
|
|
7
|
+
%h3
|
|
8
|
+
make a weibo!
|
|
9
|
+
%form{:action => "/update", :method => "POST", :enctype => "multipart/form-data"}
|
|
10
|
+
%textarea{:id => 'status', :name => "status", :cols => "62", :rows => "5"}
|
|
11
|
+
%br
|
|
12
|
+
%input{:id => 'file', :name => 'file', :type => 'file'}
|
|
13
|
+
%br
|
|
14
|
+
%input{:type => "submit", :value => "Send"}
|
|
15
|
+
|
|
16
|
+
%br
|
|
17
|
+
%br
|
|
18
|
+
%br
|
|
19
|
+
%h3
|
|
20
|
+
home timeline
|
|
21
|
+
.statuses
|
|
22
|
+
-@statuses.friends_timeline.statuses.each do |status|
|
|
23
|
+
.status
|
|
24
|
+
%p.text
|
|
25
|
+
=status.text
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
%br
|
|
29
|
+
-if status.bmiddle_pic
|
|
30
|
+
%img{:src => status.bmiddle_pic, :alt => "", :class => 'pic'}
|
|
31
|
+
%br
|
|
32
|
+
.time_and_by
|
|
33
|
+
=Time.parse(status.created_at).ago_in_words
|
|
34
|
+
by
|
|
35
|
+
=status.user.screen_name
|
|
36
|
+
from
|
|
37
|
+
=status.source
|
|
38
|
+
%br
|
|
39
|
+
%br
|
|
40
|
+
%br
|
|
41
|
+
%br
|
|
42
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
!!!
|
|
2
|
+
%html(xml:lang='en' lang='en' xmlns='http://www.w3.org/1999/xhtml')
|
|
3
|
+
%head
|
|
4
|
+
%meta(content='text/html;charset=UTF-8' http-equiv='content-type')
|
|
5
|
+
%title="weibo oauth2 api example"
|
|
6
|
+
%link{:href => "/screen.css", :rel =>"stylesheet", :type => "text/css", :media => "screen" }
|
|
7
|
+
%body
|
|
8
|
+
%h2="weibo oauth2 api example"
|
|
9
|
+
%a{:href => (session[:uid] ? "/logout" : "/connect")}=(session[:uid] ? "logout" : "connect")
|
|
10
|
+
= yield
|
|
11
|
+
%footer
|
|
12
|
+
%h6="http://github.com/simsicon/weibo_2"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module WeiboOAuth2
|
|
2
|
+
class AccessToken < OAuth2::AccessToken
|
|
3
|
+
|
|
4
|
+
def validated?
|
|
5
|
+
!!@expires_at && !expired?
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def expired?
|
|
9
|
+
expires? && (expires_at < time_convertion(Time.now, '+08:00').to_i)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
#Convert Time from a time zone to another time zone
|
|
14
|
+
#'+08:00' or '-08:00'
|
|
15
|
+
#return Time
|
|
16
|
+
def time_convertion(time, time_zone)
|
|
17
|
+
time.getutc.getlocal(time_zone)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
require 'hashie'
|
|
2
|
+
require 'json'
|
|
3
|
+
require 'rest_client'
|
|
4
|
+
require 'net/http/post/multipart'
|
|
5
|
+
|
|
6
|
+
module WeiboOAuth2
|
|
7
|
+
module Api
|
|
8
|
+
module V2
|
|
9
|
+
class Base
|
|
10
|
+
extend Forwardable
|
|
11
|
+
|
|
12
|
+
def_delegators :@access_token, :get, :post, :put, :delete
|
|
13
|
+
|
|
14
|
+
@@API_VERSION = 2
|
|
15
|
+
|
|
16
|
+
def initialize(access_token, apis)
|
|
17
|
+
@access_token = access_token
|
|
18
|
+
@apis = apis
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def hashie(response)
|
|
22
|
+
json_body = JSON.parse(response.body)
|
|
23
|
+
if json_body.is_a? Array
|
|
24
|
+
Array.new(json_body.count){|i| Hashie::Mash.new(json_body[i])}
|
|
25
|
+
else
|
|
26
|
+
Hashie::Mash.new json_body
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def method_missing(name, *args)
|
|
31
|
+
name_str = name.to_s
|
|
32
|
+
api_info = @apis[name_str]
|
|
33
|
+
super unless api_info
|
|
34
|
+
|
|
35
|
+
method = api_info['method'] || 'get'
|
|
36
|
+
method = method.downcase
|
|
37
|
+
if api_info['attachment']
|
|
38
|
+
self.class.class_eval do
|
|
39
|
+
define_method(name) do |params={}|
|
|
40
|
+
multipart = self.class.build_multipart_bodies(params)
|
|
41
|
+
hashie send(method, api_info['url'], :headers => multipart[:headers], :body => multipart[:body])
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
else
|
|
45
|
+
if api_info['url'].start_with?('https://') or api_info['url'].start_with?('http://')
|
|
46
|
+
self.class.class_eval do
|
|
47
|
+
if ['post', 'put'].include? method
|
|
48
|
+
define_method(name) do
|
|
49
|
+
hashie RestClient.send(method, api_info['url'], :access_token => @access_token.token)
|
|
50
|
+
end
|
|
51
|
+
else
|
|
52
|
+
define_method(name) do
|
|
53
|
+
hashie RestClient.send(method, "#{api_info['url']}?access_token=#{@access_token.token}")
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
else
|
|
58
|
+
self.class.class_eval do
|
|
59
|
+
define_method(name) do |params={}|
|
|
60
|
+
hashie send(method, api_info['url'], :params => params)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
if args.length > 0
|
|
67
|
+
send(name, args[0])
|
|
68
|
+
else
|
|
69
|
+
send(name)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# respond_to
|
|
74
|
+
def respond_to?(name)
|
|
75
|
+
unless methods.include? name
|
|
76
|
+
name_str = name.to_s
|
|
77
|
+
unless @apis.include? name_str
|
|
78
|
+
return super
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
true
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
protected
|
|
86
|
+
def self.mime_type(file)
|
|
87
|
+
case
|
|
88
|
+
when file =~ /\.jpg/ then 'image/jpg'
|
|
89
|
+
when file =~ /\.gif$/ then 'image/gif'
|
|
90
|
+
when file =~ /\.png$/ then 'image/png'
|
|
91
|
+
else 'application/octet-stream'
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
CRLF = "\r\n"
|
|
96
|
+
def self.build_multipart_bodies(parts)
|
|
97
|
+
boundary = Time.now.to_i.to_s(16)
|
|
98
|
+
body = ""
|
|
99
|
+
parts.each do |key, value|
|
|
100
|
+
esc_key = CGI.escape(key.to_s)
|
|
101
|
+
body << "--#{boundary}#{CRLF}"
|
|
102
|
+
if value.respond_to?(:read)
|
|
103
|
+
body << "Content-Disposition: form-data; name=\"#{esc_key}\"; filename=\"#{File.basename(value.path)}\"#{CRLF}"
|
|
104
|
+
body << "Content-Type: #{mime_type(value.path)}#{CRLF*2}"
|
|
105
|
+
body << value.read
|
|
106
|
+
else
|
|
107
|
+
body << "Content-Disposition: form-data; name=\"#{esc_key}\"#{CRLF*2}#{value}"
|
|
108
|
+
end
|
|
109
|
+
body << CRLF
|
|
110
|
+
end
|
|
111
|
+
body << "--#{boundary}--#{CRLF*2}"
|
|
112
|
+
{
|
|
113
|
+
:body => body,
|
|
114
|
+
:headers => {"Content-Type" => "multipart/form-data; boundary=#{boundary}"}
|
|
115
|
+
}
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
data/lib/weibo2s/base.rb
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
require 'oauth2'
|
|
2
|
+
|
|
3
|
+
module WeiboOAuth2
|
|
4
|
+
class Client < OAuth2::Client
|
|
5
|
+
|
|
6
|
+
def initialize(client_id='', client_secret='', opts={}, &block)
|
|
7
|
+
client_id = WeiboOAuth2::Config.api_key if client_id.empty?
|
|
8
|
+
client_secret = WeiboOAuth2::Config.api_secret if client_secret.empty?
|
|
9
|
+
super
|
|
10
|
+
@site = "https://api.weibo.com/2/"
|
|
11
|
+
@options[:authorize_url] = '/oauth2/authorize'
|
|
12
|
+
@options[:token_url] = '/oauth2/access_token'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def authorize_url(params={})
|
|
16
|
+
params[:client_id] = @id unless params[:client_id]
|
|
17
|
+
params[:response_type] = 'code' unless params[:response_type]
|
|
18
|
+
params[:redirect_uri] = WeiboOAuth2::Config.redirect_uri unless params[:redirect_uri]
|
|
19
|
+
super
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def get_token(params, access_token_opts={})
|
|
23
|
+
params = params.merge({:parse => :json})
|
|
24
|
+
access_token_opts = access_token_opts.merge({:header_format => "OAuth2 %s", :param_name => "access_token"})
|
|
25
|
+
super
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def get_and_restore_token(params, access_token_opts={})
|
|
29
|
+
@access_token = get_token(params, access_token_opts={})
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def get_token_from_hash(hash)
|
|
33
|
+
access_token = hash.delete(:access_token) || hash.delete('access_token')
|
|
34
|
+
opts = {:expires_at => (hash.delete(:expires_at) || hash.delete('expires_at')),
|
|
35
|
+
:header_format => "OAuth2 %s",
|
|
36
|
+
:param_name => "access_token"}
|
|
37
|
+
|
|
38
|
+
@access_token = WeiboOAuth2::AccessToken.new(self, access_token, opts)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def authorized?
|
|
42
|
+
!!@access_token
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def method_missing(name, *args)
|
|
46
|
+
name_str = name.to_s
|
|
47
|
+
super unless WeiboOAuth2::Config.apis.include? name_str
|
|
48
|
+
apis = WeiboOAuth2::Config.apis[name_str]
|
|
49
|
+
|
|
50
|
+
self.class.class_eval do
|
|
51
|
+
define_method(name) do
|
|
52
|
+
p = "@#{name.to_s}"
|
|
53
|
+
instance_variable_set(p, WeiboOAuth2::Api::V2::Base.new(@access_token, apis)) unless instance_variable_get(p) if @access_token
|
|
54
|
+
instance_variable_get(p)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
send(name)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# respond_to
|
|
62
|
+
def respond_to?(name)
|
|
63
|
+
unless methods.include? name
|
|
64
|
+
name_str = name.to_s
|
|
65
|
+
unless WeiboOAuth2::Config.apis.include? name_str
|
|
66
|
+
return super
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
true
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module WeiboOAuth2
|
|
2
|
+
module Config
|
|
3
|
+
|
|
4
|
+
def self.api_key=(val)
|
|
5
|
+
@@api_key = val
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def self.api_key
|
|
9
|
+
@@api_key
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.api_secret=(val)
|
|
13
|
+
@@api_secret = val
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.api_secret
|
|
17
|
+
@@api_secret
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.redirect_uri=(val)
|
|
21
|
+
@@redirect_uri = val
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.redirect_uri
|
|
25
|
+
@@redirect_uri
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
## plus by cloud
|
|
29
|
+
def self.apis=(val)
|
|
30
|
+
@@apis = val
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.apis
|
|
34
|
+
@@apis
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module WeiboOAuth2
|
|
2
|
+
module Strategy
|
|
3
|
+
class AuthCode < OAuth2::Strategy::AuthCode
|
|
4
|
+
def get_token(code, params={}, opts={})
|
|
5
|
+
params = {'grant_type' => 'authorization_code',
|
|
6
|
+
'code' => code,
|
|
7
|
+
'redirect_uri' => WeiboOAuth2::Config.redirect_uri.to_s}.merge(client_params).merge(params)
|
|
8
|
+
@client.get_and_restore_token(params, opts)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module WeiboOAuth2
|
|
2
|
+
|
|
3
|
+
class Version
|
|
4
|
+
MAJOR = 0 unless defined? MAJOR
|
|
5
|
+
MINOR = 1 unless defined? MINOR
|
|
6
|
+
PATCH = 0 unless defined? PATCH
|
|
7
|
+
PRE = nil unless defined? PRE
|
|
8
|
+
|
|
9
|
+
class << self
|
|
10
|
+
|
|
11
|
+
# @return [String]
|
|
12
|
+
def to_s
|
|
13
|
+
[MAJOR, MINOR, PATCH, PRE].compact.join('.')
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/weibo2s.rb
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require "yaml"
|
|
2
|
+
|
|
3
|
+
require "weibo2s/version"
|
|
4
|
+
require "weibo2s/config"
|
|
5
|
+
require "weibo2s/base"
|
|
6
|
+
require "weibo2s/client"
|
|
7
|
+
require "weibo2s/access_token"
|
|
8
|
+
require "weibo2s/api/v2/base"
|
|
9
|
+
require "weibo2s/strategy/auth_code"
|
|
10
|
+
|
|
11
|
+
if File.exists?('config/weibo.yml')
|
|
12
|
+
weibo_oauth = YAML.load_file('config/weibo.yml')[ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"]
|
|
13
|
+
WeiboOAuth2::Config.api_key = weibo_oauth["api_key"]
|
|
14
|
+
WeiboOAuth2::Config.api_secret = weibo_oauth["api_secret"]
|
|
15
|
+
else
|
|
16
|
+
puts "\n\n=========================================================\n\n" +
|
|
17
|
+
" You haven't made a config/weibo.yml file.\n\n You should. \n\n The weibo gem will work much better if you do\n\n" +
|
|
18
|
+
" Please set Weibo::Config.api_key and \n Weibo::Config.api_secret\n somewhere in your initialization process\n\n" +
|
|
19
|
+
"=========================================================\n\n"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
if File.exists?('config/weibo_api.yml')
|
|
23
|
+
WeiboOAuth2::Config.apis = YAML.load_file('config/weibo_api.yml')
|
|
24
|
+
else
|
|
25
|
+
puts "No apis YAML file can't work."
|
|
26
|
+
end
|
data/spec/client_spec.rb
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'weibo2s'
|
|
2
|
+
|
|
3
|
+
WeiboOAuth2::Config.api_key = 'abc'
|
|
4
|
+
WeiboOAuth2::Config.api_secret = 'def'
|
|
5
|
+
WeiboOAuth2::Config.redirect_uri = 'https://example.com/callback'
|
|
6
|
+
|
|
7
|
+
describe WeiboOAuth2::Client do
|
|
8
|
+
it 'should assign id and secret from config' do
|
|
9
|
+
subject.id.should == 'abc'
|
|
10
|
+
subject.secret.should == 'def'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'should assign site from default' do
|
|
14
|
+
subject.site.should == 'https://api.weibo.com/2/'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'should get authorize_url' do
|
|
18
|
+
authorize_url = 'https://api.weibo.com/oauth2/authorize?client_id=abc&response_type=code&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback'
|
|
19
|
+
subject.authorize_url.should == authorize_url
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'should leave Faraday::Connection#ssl unset' do
|
|
23
|
+
subject.connection.ssl.should == {}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "defaults raise_errors to true" do
|
|
27
|
+
subject.options[:raise_errors].should be_true
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "allows true/false for raise_errors option" do
|
|
31
|
+
client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :raise_errors => false)
|
|
32
|
+
client.options[:raise_errors].should be_false
|
|
33
|
+
client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :raise_errors => true)
|
|
34
|
+
client.options[:raise_errors].should be_true
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "allows get/post for access_token_method option" do
|
|
38
|
+
client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :access_token_method => :get)
|
|
39
|
+
client.options[:access_token_method].should == :get
|
|
40
|
+
client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :access_token_method => :post)
|
|
41
|
+
client.options[:access_token_method].should == :post
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
data/weibo.yml.example
ADDED
data/weibo2s.gemspec
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
require File.expand_path('../lib/weibo2s/version', __FILE__)
|
|
3
|
+
|
|
4
|
+
Gem::Specification.new do |gem|
|
|
5
|
+
gem.authors = ["cloud"]
|
|
6
|
+
gem.email = ["cloud@gmail.com"]
|
|
7
|
+
gem.description = "A oauth2 gem for weibo"
|
|
8
|
+
gem.summary = "A oauth2 gem for weibo"
|
|
9
|
+
gem.homepage = "https://github.com/cloudorz/weibo_2"
|
|
10
|
+
|
|
11
|
+
gem.files = `git ls-files`.split($\)
|
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
14
|
+
gem.name = "weibo2s"
|
|
15
|
+
gem.require_paths = ["lib"]
|
|
16
|
+
gem.version = WeiboOAuth2::Version
|
|
17
|
+
|
|
18
|
+
gem.add_development_dependency "rspec", "~> 2.6"
|
|
19
|
+
|
|
20
|
+
gem.add_runtime_dependency 'oauth2', "~> 0.8.0"
|
|
21
|
+
gem.add_runtime_dependency 'hashie', "~> 1.2.0"
|
|
22
|
+
gem.add_runtime_dependency 'json' , "~> 1.7.3"
|
|
23
|
+
gem.add_runtime_dependency 'rest-client', "~> 1.6.7"
|
|
24
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
statuses:
|
|
2
|
+
public_timeline:
|
|
3
|
+
url: statuses/public_timeline.json
|
|
4
|
+
friends_timeline:
|
|
5
|
+
url: statuses/friends_timeline.json
|
|
6
|
+
home_timeline:
|
|
7
|
+
url: statuses/home_timeline.json
|
|
8
|
+
destroy:
|
|
9
|
+
url: statuses/destory.json
|
|
10
|
+
method: POST
|
|
11
|
+
update:
|
|
12
|
+
url: statuses/update.json
|
|
13
|
+
method: POST
|
|
14
|
+
upload:
|
|
15
|
+
url: statuses/upload.json
|
|
16
|
+
method: POST
|
|
17
|
+
attachment: true
|
|
18
|
+
upload_url_text:
|
|
19
|
+
url: statuses/upload_url_text.json
|
|
20
|
+
method: POST
|
|
21
|
+
emotions:
|
|
22
|
+
url: emotions.json
|
|
23
|
+
users:
|
|
24
|
+
show:
|
|
25
|
+
url: users/show.json
|
|
26
|
+
domain_show:
|
|
27
|
+
url: user/domain_show.json
|
|
28
|
+
counts:
|
|
29
|
+
url: users/counts.json
|
|
30
|
+
remind:
|
|
31
|
+
unread_count:
|
|
32
|
+
url: https://rm.api.weibo.com/2/remind/unread_count.json
|
|
33
|
+
set_count:
|
|
34
|
+
url: https://rm.api.weibo.com/2/remind/set_count.json
|
|
35
|
+
method: POST
|
metadata
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: weibo2s
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- cloud
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2012-08-22 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: rspec
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
18
|
+
requirements:
|
|
19
|
+
- - ~>
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '2.6'
|
|
22
|
+
type: :development
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ~>
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '2.6'
|
|
30
|
+
- !ruby/object:Gem::Dependency
|
|
31
|
+
name: oauth2
|
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
|
33
|
+
none: false
|
|
34
|
+
requirements:
|
|
35
|
+
- - ~>
|
|
36
|
+
- !ruby/object:Gem::Version
|
|
37
|
+
version: 0.8.0
|
|
38
|
+
type: :runtime
|
|
39
|
+
prerelease: false
|
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
42
|
+
requirements:
|
|
43
|
+
- - ~>
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: 0.8.0
|
|
46
|
+
- !ruby/object:Gem::Dependency
|
|
47
|
+
name: hashie
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
49
|
+
none: false
|
|
50
|
+
requirements:
|
|
51
|
+
- - ~>
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: 1.2.0
|
|
54
|
+
type: :runtime
|
|
55
|
+
prerelease: false
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
none: false
|
|
58
|
+
requirements:
|
|
59
|
+
- - ~>
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: 1.2.0
|
|
62
|
+
- !ruby/object:Gem::Dependency
|
|
63
|
+
name: json
|
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
|
65
|
+
none: false
|
|
66
|
+
requirements:
|
|
67
|
+
- - ~>
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: 1.7.3
|
|
70
|
+
type: :runtime
|
|
71
|
+
prerelease: false
|
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
+
none: false
|
|
74
|
+
requirements:
|
|
75
|
+
- - ~>
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: 1.7.3
|
|
78
|
+
- !ruby/object:Gem::Dependency
|
|
79
|
+
name: rest-client
|
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
|
81
|
+
none: false
|
|
82
|
+
requirements:
|
|
83
|
+
- - ~>
|
|
84
|
+
- !ruby/object:Gem::Version
|
|
85
|
+
version: 1.6.7
|
|
86
|
+
type: :runtime
|
|
87
|
+
prerelease: false
|
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
89
|
+
none: false
|
|
90
|
+
requirements:
|
|
91
|
+
- - ~>
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: 1.6.7
|
|
94
|
+
description: A oauth2 gem for weibo
|
|
95
|
+
email:
|
|
96
|
+
- cloud@gmail.com
|
|
97
|
+
executables: []
|
|
98
|
+
extensions: []
|
|
99
|
+
extra_rdoc_files: []
|
|
100
|
+
files:
|
|
101
|
+
- .gitignore
|
|
102
|
+
- Gemfile
|
|
103
|
+
- LICENSE
|
|
104
|
+
- README.md
|
|
105
|
+
- Rakefile
|
|
106
|
+
- example/.sass-cache/80b2331c862c6e430e0af18caf62d12d982610f0/screen.sassc
|
|
107
|
+
- example/.sass-cache/faf9751221db0b5ce76d45351b9591c3bfc59441/screen.sassc
|
|
108
|
+
- example/Gemfile
|
|
109
|
+
- example/config.ru
|
|
110
|
+
- example/config/weibo.yml
|
|
111
|
+
- example/config/weibo_api.yml
|
|
112
|
+
- example/example.rb
|
|
113
|
+
- example/views/index.haml
|
|
114
|
+
- example/views/layout.haml
|
|
115
|
+
- example/views/screen.sass
|
|
116
|
+
- lib/weibo2s.rb
|
|
117
|
+
- lib/weibo2s/access_token.rb
|
|
118
|
+
- lib/weibo2s/api/v2/base.rb
|
|
119
|
+
- lib/weibo2s/base.rb
|
|
120
|
+
- lib/weibo2s/client.rb
|
|
121
|
+
- lib/weibo2s/config.rb
|
|
122
|
+
- lib/weibo2s/oauth.rb
|
|
123
|
+
- lib/weibo2s/strategy/auth_code.rb
|
|
124
|
+
- lib/weibo2s/version.rb
|
|
125
|
+
- spec/client_spec.rb
|
|
126
|
+
- weibo.yml.example
|
|
127
|
+
- weibo2s.gemspec
|
|
128
|
+
- weibo_api.yml.example
|
|
129
|
+
homepage: https://github.com/cloudorz/weibo_2
|
|
130
|
+
licenses: []
|
|
131
|
+
post_install_message:
|
|
132
|
+
rdoc_options: []
|
|
133
|
+
require_paths:
|
|
134
|
+
- lib
|
|
135
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
136
|
+
none: false
|
|
137
|
+
requirements:
|
|
138
|
+
- - ! '>='
|
|
139
|
+
- !ruby/object:Gem::Version
|
|
140
|
+
version: '0'
|
|
141
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
142
|
+
none: false
|
|
143
|
+
requirements:
|
|
144
|
+
- - ! '>='
|
|
145
|
+
- !ruby/object:Gem::Version
|
|
146
|
+
version: '0'
|
|
147
|
+
requirements: []
|
|
148
|
+
rubyforge_project:
|
|
149
|
+
rubygems_version: 1.8.24
|
|
150
|
+
signing_key:
|
|
151
|
+
specification_version: 3
|
|
152
|
+
summary: A oauth2 gem for weibo
|
|
153
|
+
test_files:
|
|
154
|
+
- spec/client_spec.rb
|