tuiter 0.0.5 → 0.0.6
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/CHANGELOG +7 -0
- data/README.rdoc +37 -0
- data/examples/basic_example.rb +22 -1
- data/lib/tuiter.rb +7 -1
- data/lib/tuiter/client.rb +20 -50
- data/lib/tuiter/methods/account.rb +2 -2
- data/lib/tuiter/methods/direct_message.rb +6 -10
- data/lib/tuiter/methods/friendship.rb +4 -11
- data/lib/tuiter/methods/social_graph.rb +1 -1
- data/lib/tuiter/methods/status.rb +4 -8
- data/lib/tuiter/methods/user.rb +3 -3
- data/lib/tuiter/utils.rb +150 -0
- data/lib/tuiter/version.rb +1 -1
- data/test/unit/client_test.rb +5 -19
- data/test/unit/utils_test.rb +69 -0
- metadata +14 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
== v0.0.6
|
2
|
+
* Added OAuth support
|
3
|
+
* Http Basic Authentication is still supported and old users won't need to change any code base
|
4
|
+
* gem refactoring, now the HTTP Requests handling is centralized in one object
|
5
|
+
* tests for utils and client
|
6
|
+
* documentation upgrade for OAuth
|
7
|
+
|
1
8
|
== v0.0.5
|
2
9
|
* Version bump and gemspec update
|
3
10
|
* Improvements on parse_options
|
data/README.rdoc
CHANGED
@@ -37,6 +37,43 @@ source part out.
|
|
37
37
|
There are (or at least we want to add :-) another examples in the examples/
|
38
38
|
folder.
|
39
39
|
|
40
|
+
== Using OAuth
|
41
|
+
|
42
|
+
require 'tuiter'
|
43
|
+
client = Tuiter::Client.new(:authentication => :oauth, :consumer_key => 'YOUR_KEY', :consumer_secret => 'YOUR_SECRET')
|
44
|
+
|
45
|
+
# request token from Twitter
|
46
|
+
rtoken = client.request_token
|
47
|
+
# waits for token
|
48
|
+
# stores token and secret
|
49
|
+
token, secret = rtoken.token, rtoken.secret # you could store this on session, db, etc
|
50
|
+
|
51
|
+
# redirect to authorize url
|
52
|
+
rtoken.authorize_url
|
53
|
+
# user authenticate in twitter domains
|
54
|
+
|
55
|
+
# the code below goes in the callback accessed by Twitter
|
56
|
+
access_token = client.authorize(token,secret)
|
57
|
+
# checks if everything's ok
|
58
|
+
if client.authorized?
|
59
|
+
# have fun
|
60
|
+
15.times do
|
61
|
+
client.update('All work and no play makes Jack a dull boy')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
If you already have the token and secret of the user (from database, for example), you just have to do the following to authenticate them:
|
66
|
+
|
67
|
+
client = Tuiter::Client.new(:authentication => :oauth, :consumer_key => 'YOUR_KEY', :consumer_secret => 'YOUR_SECRET', :token => token, :secret => secret)
|
68
|
+
if client.authorized?
|
69
|
+
# have fun
|
70
|
+
15.times do
|
71
|
+
client.update('All work and no play makes Jack a dull boy')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
Register your Twitter client at http://twitter.com/oauth_clients
|
76
|
+
|
40
77
|
== Roadmap and TO-DO list
|
41
78
|
|
42
79
|
Check out the library roadmap and to-do list
|
data/examples/basic_example.rb
CHANGED
@@ -1,8 +1,29 @@
|
|
1
1
|
require 'tuiter'
|
2
2
|
|
3
|
-
|
3
|
+
# HTTP Basic Auth example
|
4
|
+
client = Tuiter::Client.new(:authentication => :basic, :username => 'screen_name', :password => 'password')
|
4
5
|
|
5
6
|
15.times do
|
6
7
|
client.update('All work and no play makes Jack a dull boy')
|
7
8
|
end
|
8
9
|
|
10
|
+
|
11
|
+
# OAuth example
|
12
|
+
client = Tuiter::Client.new(:authentication => :oauth, :consumer_key => 'YOUR_KEY', :consumer_secret => 'YOUR_SECRET')
|
13
|
+
|
14
|
+
rtoken = client.request_token
|
15
|
+
# waits for token
|
16
|
+
# stores token and secret
|
17
|
+
token, secret = rtoken.token, rtoken.secret
|
18
|
+
# redirect to authorize url
|
19
|
+
rtoken.authorize_url
|
20
|
+
# user authenticate in twitter domains
|
21
|
+
# and then Twitter access the callback url with the access token
|
22
|
+
access_token = client.authorize(token,secret)
|
23
|
+
# checks if everything's ok
|
24
|
+
if client.authorized?
|
25
|
+
# and have fun
|
26
|
+
15.times do
|
27
|
+
client.update('All work and no play makes Jack a dull boy')
|
28
|
+
end
|
29
|
+
end
|
data/lib/tuiter.rb
CHANGED
@@ -2,12 +2,19 @@ require 'open-uri'
|
|
2
2
|
require 'uri'
|
3
3
|
require 'net/http'
|
4
4
|
require 'logger'
|
5
|
+
require 'oauth'
|
5
6
|
|
6
7
|
require 'json'
|
7
8
|
|
8
9
|
libdir = File.dirname(__FILE__)
|
9
10
|
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
10
11
|
|
12
|
+
# some constants
|
13
|
+
TWITTER_API_BASE_URL = "http://twitter.com"
|
14
|
+
|
15
|
+
# Utils
|
16
|
+
require 'tuiter/utils'
|
17
|
+
|
11
18
|
# Tuiter API methods modules
|
12
19
|
require 'tuiter/methods/status'
|
13
20
|
require 'tuiter/methods/user'
|
@@ -24,4 +31,3 @@ require 'tuiter/data/direct_message'
|
|
24
31
|
|
25
32
|
# Tuiter client and end points
|
26
33
|
require 'tuiter/client'
|
27
|
-
|
data/lib/tuiter/client.rb
CHANGED
@@ -7,42 +7,34 @@ module Tuiter
|
|
7
7
|
include Tuiter::FriendshipMethods
|
8
8
|
include Tuiter::SocialGraphMethods
|
9
9
|
include Tuiter::AccountMethods
|
10
|
-
|
11
|
-
attr_accessor :username, :password
|
12
10
|
|
13
11
|
def initialize(options = {})
|
14
12
|
@pid = Process.pid
|
15
13
|
@logger = options[:logger] || Logger.new('tuiter.log')
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
begin
|
15
|
+
authentication_type = options.delete(:authentication)
|
16
|
+
authentication_type = :basic if authentication_type.nil?
|
17
|
+
@request_handler = Tuiter::Request.new(authentication_type, options)
|
18
|
+
rescue
|
19
|
+
return nil
|
20
|
+
end
|
19
21
|
log("initialize()")
|
20
22
|
end
|
23
|
+
|
24
|
+
def request_token
|
25
|
+
@request_handler.request_token
|
26
|
+
end
|
27
|
+
|
28
|
+
def authorize(token, secret)
|
29
|
+
@request_handler.authorize(token, secret)
|
30
|
+
end
|
21
31
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
status = Timeout::timeout(10) do
|
26
|
-
log("request() query: #{url}")
|
27
|
-
http = open(url, :http_basic_authentication => [@username, @password])
|
28
|
-
log("request() debug: http status is #{http.status.join(' ')}")
|
29
|
-
if http.status == ["200", "OK"]
|
30
|
-
res = http.read
|
31
|
-
return res
|
32
|
-
end
|
33
|
-
return nil
|
34
|
-
end
|
35
|
-
rescue Timeout::Error
|
36
|
-
log("request() error: timeout error")
|
37
|
-
return nil
|
38
|
-
rescue OpenURI::HTTPError => e
|
39
|
-
log("request() http error: #{e.message} in #{e.backtrace.first.to_s}")
|
40
|
-
return nil
|
41
|
-
rescue Exception => e
|
42
|
-
log("request() error: #{e.message} in #{e.backtrace.first.to_s}")
|
43
|
-
return nil
|
32
|
+
def authorized?
|
33
|
+
oauth_response = @request_handler.get('/account/verify_credentials.json')
|
34
|
+
return oauth_response.class == Net::HTTPOK
|
44
35
|
end
|
45
|
-
|
36
|
+
|
37
|
+
private
|
46
38
|
def parse_options(options)
|
47
39
|
params = ""
|
48
40
|
|
@@ -56,29 +48,7 @@ module Tuiter
|
|
56
48
|
|
57
49
|
return params
|
58
50
|
end
|
59
|
-
|
60
|
-
def setup_a_proxy?
|
61
|
-
http_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY'] || nil
|
62
|
-
|
63
|
-
if http_proxy
|
64
|
-
proxy = URI.parse(http_proxy)
|
65
|
-
|
66
|
-
@proxy_host = proxy.host
|
67
|
-
@proxy_port = proxy.port
|
68
|
-
@proxy_user, @proxy_pass = proxy.userinfo.split(/:/) if proxy.userinfo
|
69
|
-
end
|
70
51
|
|
71
|
-
http_proxy != nil
|
72
|
-
end
|
73
|
-
|
74
|
-
def new_http_for(url)
|
75
|
-
if @use_proxy
|
76
|
-
http = Net::HTTP.new(url.host, url.port, @proxy_host, @proxy_port, @proxy_user, @proxy_pass)
|
77
|
-
else
|
78
|
-
http = Net::HTTP.new(url.host, url.port)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
52
|
def log(message)
|
83
53
|
@logger.info "[Tuiter:#{@pid}] #{Time.now.to_s} : #{message}"
|
84
54
|
end
|
@@ -14,7 +14,7 @@ module Tuiter
|
|
14
14
|
module AccountMethods
|
15
15
|
|
16
16
|
def account_verify_credentials?
|
17
|
-
if res =
|
17
|
+
if res = @request_handler.get("/account/verify_credentials.json").body
|
18
18
|
return Tuiter::UserExtended.new(JSON.parse(res))
|
19
19
|
else
|
20
20
|
return nil
|
@@ -22,7 +22,7 @@ module Tuiter
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def account_rate_limit_status
|
25
|
-
if res =
|
25
|
+
if res = @request_handler.get("/account/rate_limit_status.json").body
|
26
26
|
return Tuiter::RateLimit.new(JSON.parse(res))
|
27
27
|
else
|
28
28
|
return nil
|
@@ -9,10 +9,10 @@ module Tuiter
|
|
9
9
|
module DirectMessageMethods
|
10
10
|
|
11
11
|
def direct_messages(options = {})
|
12
|
-
url = '
|
12
|
+
url = '/direct_messages.json'
|
13
13
|
params = parse_options(options) || ""
|
14
14
|
|
15
|
-
if res =
|
15
|
+
if res = @request_handler.get(url+params).body
|
16
16
|
data = JSON.parse(res)
|
17
17
|
return data.map { |d| Tuiter::DirectMessage.new(d) }
|
18
18
|
else
|
@@ -21,10 +21,10 @@ module Tuiter
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def direct_messages_sent(options = {})
|
24
|
-
url = '
|
24
|
+
url = '/direct_messages/sent.json'
|
25
25
|
params = parse_options(options) || ""
|
26
26
|
|
27
|
-
if res =
|
27
|
+
if res = @request_handler.get(url+params).body
|
28
28
|
data = JSON.parse(res)
|
29
29
|
return data.map { |d| Tuiter::DirectMessage.new(d) }
|
30
30
|
else
|
@@ -33,12 +33,8 @@ module Tuiter
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def direct_messages_new(user, text)
|
36
|
-
log("direct_new() sending: #{text} to #{user}")
|
37
|
-
|
38
|
-
req = Net::HTTP::Post.new(url.path)
|
39
|
-
req.basic_auth @username, @password
|
40
|
-
req.set_form_data({'user'=>user, 'text'=>text })
|
41
|
-
res = new_http_for(url).start {|http| http.request(req) }
|
36
|
+
log("direct_new() sending: #{text} to #{user}")
|
37
|
+
res = @request_handler.post('/direct_messages/new.json', {'user'=>user, 'text'=>text })
|
42
38
|
case res
|
43
39
|
when Net::HTTPSuccess, Net::HTTPRedirection
|
44
40
|
log("direct_new() success: OK")
|
@@ -9,11 +9,7 @@ module Tuiter
|
|
9
9
|
|
10
10
|
def friendships_create(user, follow = nil)
|
11
11
|
log("friendship_new() following: #{user}")
|
12
|
-
|
13
|
-
req = Net::HTTP::Post.new(url.path)
|
14
|
-
req.basic_auth @username, @password
|
15
|
-
req.set_form_data({'follow'=>"true"}) if follow
|
16
|
-
res = new_http_for(url).start {|http| http.request(req) }
|
12
|
+
res = @request_handler.post("/friendships/create/#{user}.json", (follow ? {'follow'=>"true"} : "" ))
|
17
13
|
case res
|
18
14
|
when Net::HTTPSuccess, Net::HTTPRedirection
|
19
15
|
log("friendship_new() success: OK")
|
@@ -24,12 +20,9 @@ module Tuiter
|
|
24
20
|
end
|
25
21
|
end
|
26
22
|
|
27
|
-
def friendships_destroy(user
|
23
|
+
def friendships_destroy(user)
|
28
24
|
log("friendship_new() following: #{user}")
|
29
|
-
|
30
|
-
req = Net::HTTP::Post.new(url.path)
|
31
|
-
req.basic_auth @username, @password
|
32
|
-
res = new_http_for(url).start {|http| http.request(req) }
|
25
|
+
res = @request_handler.post("/friendships/destroy/#{user}.json")
|
33
26
|
case res
|
34
27
|
when Net::HTTPSuccess, Net::HTTPRedirection
|
35
28
|
log("remove_friendship() success: OK")
|
@@ -41,7 +34,7 @@ module Tuiter
|
|
41
34
|
end
|
42
35
|
|
43
36
|
def friendships_exists?(id)
|
44
|
-
if res =
|
37
|
+
if res = @request_handler.get("http://twitter.com/friendships/exists.json?user_a=#{id}&user_b=#{@username}").body
|
45
38
|
return true if res == "true"
|
46
39
|
return false
|
47
40
|
else
|
@@ -7,7 +7,7 @@ module Tuiter
|
|
7
7
|
module SocialGraphMethods
|
8
8
|
|
9
9
|
def followers_ids
|
10
|
-
if res =
|
10
|
+
if res = @request_handler.get("http://twitter.com/followers/ids/#{username}.json").body
|
11
11
|
return JSON.parse(res)
|
12
12
|
else
|
13
13
|
return nil
|
@@ -12,7 +12,7 @@ module Tuiter
|
|
12
12
|
module StatusMethods
|
13
13
|
|
14
14
|
def statuses_show(id)
|
15
|
-
if res =
|
15
|
+
if res = @request_handler.get("/statuses/show/#{id}.json").body
|
16
16
|
return Tuiter::Status.new(JSON.parse(res))
|
17
17
|
else
|
18
18
|
return nil
|
@@ -21,11 +21,7 @@ module Tuiter
|
|
21
21
|
|
22
22
|
def statuses_update(status, in_reply_to_status_id = nil)
|
23
23
|
log("update() sending: #{status}")
|
24
|
-
|
25
|
-
req = Net::HTTP::Post.new(url.path)
|
26
|
-
req.basic_auth @username, @password
|
27
|
-
req.set_form_data({'status'=>status, 'in_reply_to_status_id'=>in_reply_to_status_id })
|
28
|
-
res = new_http_for(url).start {|http| http.request(req) }
|
24
|
+
res = @request_handler.post('/statuses/update.json', {'status' => status, 'in_reply_to_status_id' => in_reply_to_status_id })
|
29
25
|
case res
|
30
26
|
when Net::HTTPSuccess, Net::HTTPRedirection
|
31
27
|
log("update() success: OK")
|
@@ -37,7 +33,7 @@ module Tuiter
|
|
37
33
|
end
|
38
34
|
|
39
35
|
def statuses_mentions(options = {})
|
40
|
-
query = "
|
36
|
+
query = "/statuses/mentions.json"
|
41
37
|
if options[:since]
|
42
38
|
params = "?since=#{options[:since]}"
|
43
39
|
elsif options[:since_id]
|
@@ -52,7 +48,7 @@ module Tuiter
|
|
52
48
|
params = params + "&" + "page=#{options[:page]}"
|
53
49
|
end
|
54
50
|
end
|
55
|
-
if res =
|
51
|
+
if res = @request_handler.get(query+params).body
|
56
52
|
data = JSON.parse(res)
|
57
53
|
return data.map { |d| Tuiter::Status.new(d) }
|
58
54
|
else
|
data/lib/tuiter/methods/user.rb
CHANGED
@@ -18,7 +18,7 @@ module Tuiter
|
|
18
18
|
else
|
19
19
|
params = ""
|
20
20
|
end
|
21
|
-
if res =
|
21
|
+
if res = @request_handler.get(query+params).body
|
22
22
|
data = JSON.parse(res)
|
23
23
|
return data.map { |d| Tuiter::User.new(d) }
|
24
24
|
else
|
@@ -37,7 +37,7 @@ module Tuiter
|
|
37
37
|
else
|
38
38
|
params = ""
|
39
39
|
end
|
40
|
-
if res =
|
40
|
+
if res = @request_handler.get(query+params).body
|
41
41
|
data = JSON.parse(res)
|
42
42
|
return data.map { |d| Tuiter::User.new(d) }
|
43
43
|
else
|
@@ -46,7 +46,7 @@ module Tuiter
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def users_show(id)
|
49
|
-
if res =
|
49
|
+
if res = @request_handler.get("http://twitter.com/users/show/#{id}.json").body
|
50
50
|
return Tuiter::UserExtended.new(JSON.parse(res))
|
51
51
|
else
|
52
52
|
return nil
|
data/lib/tuiter/utils.rb
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
module Tuiter
|
2
|
+
|
3
|
+
class Request
|
4
|
+
|
5
|
+
# if :basic => options = {:username, :password}
|
6
|
+
# if :oauth => options = {consumer_key, consumer_secret, token, secret}
|
7
|
+
def initialize(authentication_type, options)
|
8
|
+
if [:basic, :oauth].include?(authentication_type)
|
9
|
+
@authentication_type = authentication_type
|
10
|
+
else
|
11
|
+
raise StandardError, "Type of Authentication not informed (must be :basic or :oauth)."
|
12
|
+
end
|
13
|
+
@config = options
|
14
|
+
end
|
15
|
+
|
16
|
+
def request_token
|
17
|
+
oauth_consumer.get_request_token if @authentication_type == :oauth
|
18
|
+
end
|
19
|
+
|
20
|
+
def authorize(token, secret)
|
21
|
+
if @authentication_type == :oauth
|
22
|
+
request_token = OAuth::RequestToken.new(oauth_consumer, token, secret)
|
23
|
+
@access_token = request_token.get_access_token
|
24
|
+
@config[:token] = @access_token.token
|
25
|
+
@config[:secret] = @access_token.secret
|
26
|
+
@access_token
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def request(http_method, path, *arguments)
|
31
|
+
send(("#{@authentication_type.to_s}_request").to_sym, http_method, path, *arguments)
|
32
|
+
end
|
33
|
+
|
34
|
+
def get(path, headers = {})
|
35
|
+
request(:get, path, headers)
|
36
|
+
end
|
37
|
+
|
38
|
+
def post(path, body = '', headers = {})
|
39
|
+
request(:post, path, body, headers)
|
40
|
+
end
|
41
|
+
|
42
|
+
def put(path, body = '', headers = {})
|
43
|
+
request(:post, path, body, headers)
|
44
|
+
end
|
45
|
+
|
46
|
+
def delete(path, headers = {})
|
47
|
+
request(:delete, path, headers)
|
48
|
+
end
|
49
|
+
|
50
|
+
def is_basic?
|
51
|
+
return (@authentication_type == :basic)
|
52
|
+
end
|
53
|
+
|
54
|
+
def is_oauth?
|
55
|
+
return (@authentication_type == :oauth)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
def http
|
60
|
+
@http ||= create_http
|
61
|
+
end
|
62
|
+
|
63
|
+
def basic_request(http_method, path, *arguments)
|
64
|
+
if path !~ /^\//
|
65
|
+
_uri = URI.parse(path)
|
66
|
+
_uri.path = "/" if _uri.path == ""
|
67
|
+
path = "#{_uri.path}#{_uri.query ? "?#{_uri.query}" : ""}"
|
68
|
+
end
|
69
|
+
|
70
|
+
response = http.request(create_http_request(http_method, path, *arguments))
|
71
|
+
return response
|
72
|
+
end
|
73
|
+
|
74
|
+
#Instantiates the http object
|
75
|
+
def create_http
|
76
|
+
tuiter_uri = URI.parse(TWITTER_API_BASE_URL)
|
77
|
+
|
78
|
+
http_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY'] || nil
|
79
|
+
if (http_proxy)
|
80
|
+
proxy = URI.parse(http_proxy)
|
81
|
+
if proxy.userinfo
|
82
|
+
proxy_user, proxy_pass = proxy.userinfo.split(/:/)
|
83
|
+
http_object = Net::HTTP.new(tuiter_uri.host, tuiter_uri.port, proxy.host, proxy.port, proxy_user, proxy_pass)
|
84
|
+
else
|
85
|
+
http_object = Net::HTTP.new(tuiter_uri.host, tuiter_uri.port, proxy.host, proxy.port)
|
86
|
+
end
|
87
|
+
else
|
88
|
+
http_object = Net::HTTP.new(tuiter_uri.host, tuiter_uri.port)
|
89
|
+
end
|
90
|
+
|
91
|
+
http_object
|
92
|
+
end
|
93
|
+
|
94
|
+
#snippet based on oauth gem
|
95
|
+
def create_http_request(http_method, path, *arguments)
|
96
|
+
http_method = http_method.to_sym
|
97
|
+
|
98
|
+
if [:post, :put].include?(http_method)
|
99
|
+
data = arguments.shift
|
100
|
+
end
|
101
|
+
|
102
|
+
headers = arguments.first.is_a?(Hash) ? arguments.shift : {}
|
103
|
+
|
104
|
+
case http_method
|
105
|
+
when :post
|
106
|
+
request = Net::HTTP::Post.new(path,headers)
|
107
|
+
request["Content-Length"] = 0 # Default to 0
|
108
|
+
when :put
|
109
|
+
request = Net::HTTP::Put.new(path,headers)
|
110
|
+
request["Content-Length"] = 0 # Default to 0
|
111
|
+
when :get
|
112
|
+
request = Net::HTTP::Get.new(path,headers)
|
113
|
+
when :delete
|
114
|
+
request = Net::HTTP::Delete.new(path,headers)
|
115
|
+
else
|
116
|
+
raise ArgumentError, "Don't know how to handle http_method: :#{http_method.to_s}"
|
117
|
+
end
|
118
|
+
|
119
|
+
# handling basic http auth
|
120
|
+
request.basic_auth @config[:username], @config[:password]
|
121
|
+
|
122
|
+
if data.is_a?(Hash)
|
123
|
+
request.set_form_data(data)
|
124
|
+
elsif data
|
125
|
+
request.body = data.to_s
|
126
|
+
request["Content-Length"] = request.body.length
|
127
|
+
end
|
128
|
+
|
129
|
+
request
|
130
|
+
end
|
131
|
+
|
132
|
+
def oauth_request(http_method, path, *arguments)
|
133
|
+
oauth_response = oauth_access_token.request(http_method, path, *arguments)
|
134
|
+
return oauth_response
|
135
|
+
end
|
136
|
+
|
137
|
+
def oauth_consumer
|
138
|
+
@consumer ||= OAuth::Consumer.new(
|
139
|
+
@config[:consumer_key],
|
140
|
+
@config[:consumer_secret],
|
141
|
+
{ :site => TWITTER_API_BASE_URL }
|
142
|
+
)
|
143
|
+
end
|
144
|
+
|
145
|
+
def oauth_access_token
|
146
|
+
@access_token ||= OAuth::AccessToken.new(oauth_consumer, @config[:token], @config[:secret])
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
data/lib/tuiter/version.rb
CHANGED
data/test/unit/client_test.rb
CHANGED
@@ -11,7 +11,7 @@ class ClientTest < Test::Unit::TestCase
|
|
11
11
|
setup do
|
12
12
|
@username = "username"
|
13
13
|
@password = "password"
|
14
|
-
@client = Tuiter::Client.new(:username => @username, :password => @password)
|
14
|
+
@client = Tuiter::Client.new(:authentication => :basic, :username => @username, :password => @password)
|
15
15
|
end
|
16
16
|
|
17
17
|
context "on POST to statuses/update" do
|
@@ -21,25 +21,17 @@ class ClientTest < Test::Unit::TestCase
|
|
21
21
|
|
22
22
|
context "with successfully response" do
|
23
23
|
setup do
|
24
|
-
fake_web_on_post("http
|
24
|
+
fake_web_on_post("http://#{@username}:#{@password}@twitter.com/statuses/update.json", :string => @update_message, :status => "200")
|
25
25
|
end
|
26
26
|
|
27
27
|
should "allow the user to post an update to Twitter" do
|
28
|
-
# basic authentication and form data
|
29
|
-
Net::HTTP::Post.any_instance.expects(:basic_auth).with(@username, @password)
|
30
|
-
Net::HTTP::Post.any_instance.expects(:set_form_data).with('status' => @update_message, 'in_reply_to_status_id' => nil)
|
31
|
-
|
32
28
|
assert_nothing_raised do
|
33
29
|
@response = @client.statuses_update(@update_message)
|
34
30
|
end
|
35
31
|
assert_instance_of Net::HTTPOK, @response
|
36
32
|
end
|
37
33
|
|
38
|
-
should "allow the user to post a reply to Twitter" do
|
39
|
-
# basic authentication and form data
|
40
|
-
Net::HTTP::Post.any_instance.expects(:basic_auth).with(@username, @password)
|
41
|
-
Net::HTTP::Post.any_instance.expects(:set_form_data).with('status' => @update_message, 'in_reply_to_status_id' => "1234567890")
|
42
|
-
|
34
|
+
should "allow the user to post a reply to Twitter" do
|
43
35
|
assert_nothing_raised do
|
44
36
|
@response = @client.statuses_update(@update_message, "1234567890")
|
45
37
|
end
|
@@ -51,13 +43,10 @@ class ClientTest < Test::Unit::TestCase
|
|
51
43
|
context "with error response" do
|
52
44
|
setup do
|
53
45
|
response_status = ["503", "Service unavailable"]
|
54
|
-
fake_web_on_post("http
|
46
|
+
fake_web_on_post("http://#{@username}:#{@password}@twitter.com/statuses/update.json", :string => response_status.join(" "), :status => response_status)
|
55
47
|
end
|
56
48
|
|
57
49
|
should "raise for http response status on 503" do
|
58
|
-
Net::HTTP::Post.any_instance.expects(:basic_auth).with(@username, @password)
|
59
|
-
Net::HTTP::Post.any_instance.expects(:set_form_data).with('status' => @update_message, 'in_reply_to_status_id' => nil)
|
60
|
-
|
61
50
|
assert_raises Net::HTTPFatalError do
|
62
51
|
@client.statuses_update(@update_message)
|
63
52
|
end
|
@@ -70,15 +59,12 @@ class ClientTest < Test::Unit::TestCase
|
|
70
59
|
|
71
60
|
context "on POST to direct_messages/new" do
|
72
61
|
setup do
|
73
|
-
fake_web_on_post("http
|
62
|
+
fake_web_on_post("http://#{@username}:#{@password}@twitter.com/direct_messages/new.json")
|
74
63
|
@anoter_user = "1234567890"
|
75
64
|
@text = "Hello World!"
|
76
65
|
end
|
77
66
|
|
78
67
|
should "allow the user to post a direct message to another Twitter's user" do
|
79
|
-
Net::HTTP::Post.any_instance.expects(:basic_auth).with(@username, @password)
|
80
|
-
Net::HTTP::Post.any_instance.expects(:set_form_data).with('user'=>@another_user, 'text'=>@text )
|
81
|
-
|
82
68
|
assert_nothing_raised do
|
83
69
|
@response = @client.direct_messages_new(@another_user, @text)
|
84
70
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../test_helper"
|
2
|
+
|
3
|
+
class UtilsTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "Tuiter::Request" do
|
6
|
+
setup do
|
7
|
+
FakeWeb.allow_net_connect = false
|
8
|
+
end
|
9
|
+
|
10
|
+
should "raise exception if user uses wrong authentication type" do
|
11
|
+
assert_raise StandardError do
|
12
|
+
Tuiter::Request.new(:wrong, {})
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "basic authentication" do
|
17
|
+
setup do
|
18
|
+
@tuiter_request = Tuiter::Request.new(:basic, :username => "foo", :password => "bar")
|
19
|
+
FakeWeb.register_uri("http://foo:bar@twitter.com/secret", :string => "Unauthorized", :status => ["401", "Unauthorized"])
|
20
|
+
FakeWeb.register_uri(:get, 'http://foo:bar@twitter.com', :string => "response")
|
21
|
+
FakeWeb.register_uri(:post, 'http://foo:bar@twitter.com/create', :string => "created")
|
22
|
+
end
|
23
|
+
|
24
|
+
should "verify the authentication type correctly" do
|
25
|
+
assert_equal true, @tuiter_request.is_basic?
|
26
|
+
assert_equal false, @tuiter_request.is_oauth?
|
27
|
+
end
|
28
|
+
|
29
|
+
should "do a request correctly" do
|
30
|
+
assert_equal "response", @tuiter_request.request(:get, 'http://twitter.com').body
|
31
|
+
end
|
32
|
+
|
33
|
+
should "return 401 when user is not authenticated" do
|
34
|
+
assert_equal "401", @tuiter_request.request(:get, 'http://twitter.com/secret').code
|
35
|
+
end
|
36
|
+
|
37
|
+
should "do a get" do
|
38
|
+
assert_equal "response", @tuiter_request.get('/').body
|
39
|
+
end
|
40
|
+
|
41
|
+
should "do a post" do
|
42
|
+
FakeWeb.register_uri(:post, 'http://foo:bar@twitter.com/create', :string => "created")
|
43
|
+
assert_equal "created", @tuiter_request.post('/create', "status=some_status").body
|
44
|
+
end
|
45
|
+
|
46
|
+
should "do a put" do
|
47
|
+
FakeWeb.register_uri(:any, 'http://foo:bar@twitter.com/change', :string => "changed")
|
48
|
+
assert_equal "changed", @tuiter_request.put('/change', :status => "some_status").body
|
49
|
+
end
|
50
|
+
|
51
|
+
should "do a delete" do
|
52
|
+
FakeWeb.register_uri(:delete, 'http://foo:bar@twitter.com/delete', :string => "deleted")
|
53
|
+
assert_equal "deleted", @tuiter_request.delete('/delete').body
|
54
|
+
end
|
55
|
+
|
56
|
+
should "handle error if the method is wrong" do
|
57
|
+
assert_raise ArgumentError do
|
58
|
+
@tuiter_request.request(:head, '/check').body
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
end
|
69
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tuiter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Manoel Lemos
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-
|
13
|
+
date: 2009-05-03 00:00:00 -03:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -23,6 +23,16 @@ dependencies:
|
|
23
23
|
- !ruby/object:Gem::Version
|
24
24
|
version: "1.1"
|
25
25
|
version:
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: oauth
|
28
|
+
type: :runtime
|
29
|
+
version_requirement:
|
30
|
+
version_requirements: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 0.3.1
|
35
|
+
version:
|
26
36
|
description: Yet another Twitter API wrapper library in Ruby
|
27
37
|
email: opensource@webcointernet.com
|
28
38
|
executables: []
|
@@ -51,6 +61,7 @@ files:
|
|
51
61
|
- lib/tuiter/methods/social_graph.rb
|
52
62
|
- lib/tuiter/methods/status.rb
|
53
63
|
- lib/tuiter/methods/user.rb
|
64
|
+
- lib/tuiter/utils.rb
|
54
65
|
- lib/tuiter/version.rb
|
55
66
|
- lib/tuiter.rb
|
56
67
|
- examples/basic_example.rb
|
@@ -68,6 +79,7 @@ files:
|
|
68
79
|
- test/unit/rate_limit_test.rb
|
69
80
|
- test/unit/status_test.rb
|
70
81
|
- test/unit/user_test.rb
|
82
|
+
- test/unit/utils_test.rb
|
71
83
|
has_rdoc: false
|
72
84
|
homepage: http://github.com/webco/tuiter
|
73
85
|
post_install_message:
|