webco-tuiter 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +7 -0
- data/README.rdoc +37 -0
- data/examples/basic_example.rb +22 -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/lib/tuiter.rb +7 -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/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/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/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: webco-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 -07: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:
|