dschn-twitter 0.3.7.1
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/History.txt +106 -0
- data/License.txt +19 -0
- data/Manifest.txt +71 -0
- data/README.txt +84 -0
- data/Rakefile +4 -0
- data/bin/twitter +15 -0
- data/config/hoe.rb +74 -0
- data/config/requirements.rb +17 -0
- data/examples/blocks.rb +15 -0
- data/examples/direct_messages.rb +28 -0
- data/examples/favorites.rb +20 -0
- data/examples/friends_followers.rb +25 -0
- data/examples/friendships.rb +13 -0
- data/examples/identica_timeline.rb +7 -0
- data/examples/location.rb +8 -0
- data/examples/posting.rb +9 -0
- data/examples/replies.rb +26 -0
- data/examples/search.rb +17 -0
- data/examples/sent_messages.rb +26 -0
- data/examples/timeline.rb +33 -0
- data/examples/twitter.rb +27 -0
- data/examples/verify_credentials.rb +13 -0
- data/lib/twitter.rb +21 -0
- data/lib/twitter/base.rb +260 -0
- data/lib/twitter/cli.rb +328 -0
- data/lib/twitter/cli/config.rb +9 -0
- data/lib/twitter/cli/helpers.rb +97 -0
- data/lib/twitter/cli/migrations/20080722194500_create_accounts.rb +13 -0
- data/lib/twitter/cli/migrations/20080722194508_create_tweets.rb +16 -0
- data/lib/twitter/cli/migrations/20080722214605_add_account_id_to_tweets.rb +9 -0
- data/lib/twitter/cli/migrations/20080722214606_create_configurations.rb +13 -0
- data/lib/twitter/cli/models/account.rb +33 -0
- data/lib/twitter/cli/models/configuration.rb +13 -0
- data/lib/twitter/cli/models/tweet.rb +20 -0
- data/lib/twitter/direct_message.rb +22 -0
- data/lib/twitter/easy_class_maker.rb +43 -0
- data/lib/twitter/rate_limit_status.rb +19 -0
- data/lib/twitter/search.rb +94 -0
- data/lib/twitter/status.rb +22 -0
- data/lib/twitter/user.rb +37 -0
- data/lib/twitter/version.rb +9 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +74 -0
- data/setup.rb +1585 -0
- data/spec/base_spec.rb +109 -0
- data/spec/cli/helper_spec.rb +35 -0
- data/spec/direct_message_spec.rb +35 -0
- data/spec/fixtures/followers.xml +706 -0
- data/spec/fixtures/friends.xml +609 -0
- data/spec/fixtures/friends_for.xml +584 -0
- data/spec/fixtures/friends_lite.xml +192 -0
- data/spec/fixtures/friends_timeline.xml +66 -0
- data/spec/fixtures/public_timeline.xml +148 -0
- data/spec/fixtures/rate_limit_status.xml +7 -0
- data/spec/fixtures/search_results.json +1 -0
- data/spec/fixtures/status.xml +25 -0
- data/spec/fixtures/user.xml +38 -0
- data/spec/fixtures/user_timeline.xml +465 -0
- data/spec/search_spec.rb +89 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/status_spec.rb +40 -0
- data/spec/user_spec.rb +42 -0
- data/tasks/deployment.rake +50 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +17 -0
- data/twitter.gemspec +49 -0
- data/website/css/common.css +47 -0
- data/website/images/terminal_output.png +0 -0
- data/website/index.html +156 -0
- metadata +180 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
|
3
|
+
config = YAML::load(open(ENV['HOME'] + '/.twitter'))
|
4
|
+
|
5
|
+
twitter = Twitter::Base.new(config['email'], config['password'])
|
6
|
+
|
7
|
+
puts 'FAVORITES'
|
8
|
+
twitter.favorites.each { |f| puts f.text }
|
9
|
+
puts
|
10
|
+
puts
|
11
|
+
|
12
|
+
puts 'CREATE'
|
13
|
+
puts twitter.create_favorite(865416114).text
|
14
|
+
puts
|
15
|
+
puts
|
16
|
+
|
17
|
+
puts 'DESTROY'
|
18
|
+
puts twitter.destroy_favorite(865416114).text
|
19
|
+
puts
|
20
|
+
puts
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
|
3
|
+
config = YAML::load(open(ENV['HOME'] + '/.twitter'))
|
4
|
+
|
5
|
+
twitter = Twitter::Base.new(config['email'], config['password'])
|
6
|
+
|
7
|
+
puts "FRIENDS"
|
8
|
+
twitter.friends.each { |f| puts f.name }
|
9
|
+
puts
|
10
|
+
puts
|
11
|
+
|
12
|
+
puts "FRIENDS FOR"
|
13
|
+
twitter.friends_for('orderedlist', :lite => true).each { |f| puts f.name }
|
14
|
+
puts
|
15
|
+
puts
|
16
|
+
|
17
|
+
puts "FOLLOWERS"
|
18
|
+
twitter.followers(:lite => true).each { |f| puts f.name }
|
19
|
+
puts
|
20
|
+
puts
|
21
|
+
|
22
|
+
puts "FOLLOWERS FOR"
|
23
|
+
twitter.followers_for('orderedlist', :lite => true).each { |f| puts f.name }
|
24
|
+
puts
|
25
|
+
puts
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
|
3
|
+
config = YAML::load(open(ENV['HOME'] + '/.twitter'))
|
4
|
+
|
5
|
+
twitter = Twitter::Base.new(config['email'], config['password'])
|
6
|
+
|
7
|
+
puts twitter.create_friendship('orderedlist').name
|
8
|
+
puts twitter.follow('orderedlist').name
|
9
|
+
puts twitter.leave('orderedlist').name
|
10
|
+
puts twitter.destroy_friendship('orderedlist').name
|
11
|
+
|
12
|
+
puts twitter.friendship_exists?('jnunemaker', 'orderedlist').inspect
|
13
|
+
puts twitter.friendship_exists?('jnunemaker', 'ze').inspect
|
@@ -0,0 +1,7 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
|
3
|
+
config = YAML::load(open(ENV['HOME'] + '/.twitter'))
|
4
|
+
|
5
|
+
identica = Twitter::Base.new(config['email'], config['password'], :api_host => 'identi.ca/api')
|
6
|
+
|
7
|
+
identica.timeline(:public).each { |s| puts s.text, s.user.name, '' }
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
|
3
|
+
config = YAML::load(open(ENV['HOME'] + '/.twitter'))
|
4
|
+
|
5
|
+
twitter = Twitter::Base.new(config['email'], config['password'])
|
6
|
+
|
7
|
+
puts twitter.update_location('Hollywood, CA').location
|
8
|
+
puts twitter.update_delivery_device('none')
|
data/examples/posting.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
|
3
|
+
config = YAML::load(open(ENV['HOME'] + '/.twitter'))
|
4
|
+
|
5
|
+
twitter = Twitter::Base.new(config['email'], config['password'])
|
6
|
+
puts twitter.post("This is a test from the example file").inspect
|
7
|
+
|
8
|
+
# sending a direct message
|
9
|
+
# puts twitter.d('jnunemaker', 'this is a test').inspect
|
data/examples/replies.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
|
3
|
+
config = YAML::load(open(ENV['HOME'] + '/.twitter'))
|
4
|
+
|
5
|
+
twitter = Twitter::Base.new(config['email'], config['password'])
|
6
|
+
|
7
|
+
puts 'SINCE'
|
8
|
+
twitter.replies(:since => Time.now - 5.day).each do |s|
|
9
|
+
puts "- #{s.text}"
|
10
|
+
end
|
11
|
+
puts
|
12
|
+
puts
|
13
|
+
|
14
|
+
puts 'SINCE_ID'
|
15
|
+
twitter.replies(:since_id => 863081345).each do |s|
|
16
|
+
puts "- #{s.text}"
|
17
|
+
end
|
18
|
+
puts
|
19
|
+
puts
|
20
|
+
|
21
|
+
puts 'PAGE'
|
22
|
+
twitter.replies(:page => 1).each do |s|
|
23
|
+
puts "- #{s.text}"
|
24
|
+
end
|
25
|
+
puts
|
26
|
+
puts
|
data/examples/search.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
|
3
|
+
|
4
|
+
Twitter::Search.new('httparty').each { |r| puts r.inspect,'' }
|
5
|
+
|
6
|
+
# search = Twitter::Search.new
|
7
|
+
# search.from('jnunemaker').to('oaknd1').each { |r| puts r.inspect, '' }
|
8
|
+
# pp search.result
|
9
|
+
# search.clear
|
10
|
+
|
11
|
+
# search.from('jnunemaker').to('oaknd1').since(814529437).containing('milk').each { |r| puts r.inspect, '' }
|
12
|
+
# search.clear
|
13
|
+
#
|
14
|
+
# search.geocode('40.757929', '-73.985506', '50mi').containing('holland').each { |r| puts r.inspect, '' }
|
15
|
+
# search.clear
|
16
|
+
|
17
|
+
# pp search.from('jnunemaker').fetch()
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
|
3
|
+
config = YAML::load(open(ENV['HOME'] + '/.twitter'))
|
4
|
+
|
5
|
+
twitter = Twitter::Base.new(config['email'], config['password'])
|
6
|
+
|
7
|
+
puts 'SINCE'
|
8
|
+
twitter.sent_messages(:since => Time.now - 5.day).each do |s|
|
9
|
+
puts "- #{s.text}"
|
10
|
+
end
|
11
|
+
puts
|
12
|
+
puts
|
13
|
+
|
14
|
+
puts 'SINCE_ID'
|
15
|
+
twitter.sent_messages(:since_id => 33505386).each do |s|
|
16
|
+
puts "- #{s.text}"
|
17
|
+
end
|
18
|
+
puts
|
19
|
+
puts
|
20
|
+
|
21
|
+
puts 'PAGE'
|
22
|
+
twitter.sent_messages(:page => 1).each do |s|
|
23
|
+
puts "- #{s.text}"
|
24
|
+
end
|
25
|
+
puts
|
26
|
+
puts
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
|
3
|
+
config = YAML::load(open(ENV['HOME'] + '/.twitter'))
|
4
|
+
|
5
|
+
twitter = Twitter::Base.new(config['email'], config['password'])
|
6
|
+
|
7
|
+
puts 'SINCE'
|
8
|
+
twitter.timeline(:user, :since => Time.now - 1.day).each do |s|
|
9
|
+
puts "- #{s.text}"
|
10
|
+
end
|
11
|
+
puts
|
12
|
+
puts
|
13
|
+
|
14
|
+
puts 'SINCE_ID'
|
15
|
+
twitter.timeline(:user, :since_id => 865547074).each do |s|
|
16
|
+
puts "- #{s.text}"
|
17
|
+
end
|
18
|
+
puts
|
19
|
+
puts
|
20
|
+
|
21
|
+
puts 'COUNT'
|
22
|
+
twitter.timeline(:user, :count => 1).each do |s|
|
23
|
+
puts "- #{s.text}"
|
24
|
+
end
|
25
|
+
puts
|
26
|
+
puts
|
27
|
+
|
28
|
+
puts 'PAGE'
|
29
|
+
twitter.timeline(:user, :page => 1).each do |s|
|
30
|
+
puts "- #{s.text}"
|
31
|
+
end
|
32
|
+
puts
|
33
|
+
puts
|
data/examples/twitter.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
|
3
|
+
config = YAML::load(open(ENV['HOME'] + '/.twitter'))
|
4
|
+
|
5
|
+
puts "Public Timeline", "=" * 50
|
6
|
+
Twitter::Base.new(config['email'], config['password']).timeline(:public).each do |s|
|
7
|
+
puts s.text, s.user.name
|
8
|
+
puts
|
9
|
+
end
|
10
|
+
|
11
|
+
puts '', "Friends Timeline", "=" * 50
|
12
|
+
Twitter::Base.new(config['email'], config['password']).timeline.each do |s|
|
13
|
+
puts s.text, s.user.name
|
14
|
+
puts
|
15
|
+
end
|
16
|
+
|
17
|
+
puts '', "Friends", "=" * 50
|
18
|
+
Twitter::Base.new(config['email'], config['password']).friends.each do |u|
|
19
|
+
puts u.name, u.status.text
|
20
|
+
puts
|
21
|
+
end
|
22
|
+
|
23
|
+
puts '', "Followers", "=" * 50
|
24
|
+
Twitter::Base.new(config['email'], config['password']).followers.each do |u|
|
25
|
+
puts u.name, u.status.text
|
26
|
+
puts
|
27
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
|
3
|
+
config = YAML::load(open(ENV['HOME'] + '/.twitter'))
|
4
|
+
|
5
|
+
twitter = Twitter::Base.new(config['email'], config['password'])
|
6
|
+
|
7
|
+
puts twitter.verify_credentials
|
8
|
+
|
9
|
+
begin
|
10
|
+
Twitter::Base.new('asdf', 'foobar').verify_credentials
|
11
|
+
rescue => error
|
12
|
+
puts error.message
|
13
|
+
end
|
data/lib/twitter.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
%w(uri cgi net/http yaml rubygems hpricot active_support).each { |f| require f }
|
2
|
+
|
3
|
+
$:.unshift(File.join(File.dirname(__FILE__)))
|
4
|
+
require 'twitter/version'
|
5
|
+
require 'twitter/easy_class_maker'
|
6
|
+
require 'twitter/base'
|
7
|
+
require 'twitter/user'
|
8
|
+
require 'twitter/search'
|
9
|
+
require 'twitter/status'
|
10
|
+
require 'twitter/direct_message'
|
11
|
+
require 'twitter/rate_limit_status'
|
12
|
+
|
13
|
+
module Twitter
|
14
|
+
class Unavailable < StandardError; end
|
15
|
+
class CantConnect < StandardError; end
|
16
|
+
class BadResponse < StandardError; end
|
17
|
+
class UnknownTimeline < ArgumentError; end
|
18
|
+
class RateExceeded < StandardError; end
|
19
|
+
|
20
|
+
SourceName = 'twittergem'
|
21
|
+
end
|
data/lib/twitter/base.rb
ADDED
@@ -0,0 +1,260 @@
|
|
1
|
+
# This is the base class for the twitter library. It makes all the requests
|
2
|
+
# to twitter, parses the xml (using hpricot) and returns ruby objects to play with.
|
3
|
+
#
|
4
|
+
# For complete documentation on the options, check out the twitter api docs.
|
5
|
+
# http://groups.google.com/group/twitter-development-talk/web/api-documentation
|
6
|
+
module Twitter
|
7
|
+
class Base
|
8
|
+
# Initializes the configuration for making requests to twitter
|
9
|
+
# Twitter example:
|
10
|
+
# Twitter.new('email/username', 'password')
|
11
|
+
#
|
12
|
+
# Identi.ca example:
|
13
|
+
# Twitter.new('email/username', 'password', :api_host => 'identi.ca/api')
|
14
|
+
def initialize(email, password, options={})
|
15
|
+
@config, @config[:email], @config[:password] = {}, email, password
|
16
|
+
@api_host = options.delete(:api_host) || 'twitter.com'
|
17
|
+
end
|
18
|
+
|
19
|
+
def timeout=(time)
|
20
|
+
@config[:timeout] = time
|
21
|
+
end
|
22
|
+
|
23
|
+
def timeout
|
24
|
+
@config[:timeout]
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns an array of statuses for a timeline; Defaults to your friends timeline.
|
28
|
+
def timeline(which=:friends, options={})
|
29
|
+
raise UnknownTimeline unless [:friends, :public, :user].include?(which)
|
30
|
+
auth = which.to_s.include?('public') ? false : true
|
31
|
+
statuses(call("#{which}_timeline", :auth => auth, :since => options[:since], :args => parse_options(options)))
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns an array of users who are in your friends list
|
35
|
+
def friends(options={})
|
36
|
+
users(call(:friends, {:args => parse_options(options)}))
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns an array of users who are friends for the id or username passed in
|
40
|
+
def friends_for(id, options={})
|
41
|
+
friends(options.merge({:id => id}))
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns an array of users who are following you
|
45
|
+
def followers(options={})
|
46
|
+
users(call(:followers, {:args => parse_options(options)}))
|
47
|
+
end
|
48
|
+
|
49
|
+
def followers_for(id, options={})
|
50
|
+
followers(options.merge({:id => id}))
|
51
|
+
end
|
52
|
+
|
53
|
+
# Returns a single status for a given id
|
54
|
+
def status(id)
|
55
|
+
statuses(call("show/#{id}")).first
|
56
|
+
end
|
57
|
+
|
58
|
+
# returns all the profile information and the last status for a user
|
59
|
+
def user(id_or_screenname)
|
60
|
+
users(request("users/show/#{id_or_screenname}.xml", :auth => true)).first
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns an array of statuses that are replies
|
64
|
+
def replies(options={})
|
65
|
+
statuses(call(:replies, :since => options[:since], :args => parse_options(options)))
|
66
|
+
end
|
67
|
+
|
68
|
+
# Destroys a status by id
|
69
|
+
def destroy(id)
|
70
|
+
call("destroy/#{id}")
|
71
|
+
end
|
72
|
+
|
73
|
+
def rate_limit_status
|
74
|
+
RateLimitStatus.new_from_xml request("account/rate_limit_status.xml", :auth => true)
|
75
|
+
end
|
76
|
+
|
77
|
+
# waiting for twitter to correctly implement this in the api as it is documented
|
78
|
+
def featured
|
79
|
+
users(call(:featured))
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns an array of all the direct messages for the authenticated user
|
83
|
+
def direct_messages(options={})
|
84
|
+
doc = request(build_path('direct_messages.xml', parse_options(options)), {:auth => true, :since => options[:since]})
|
85
|
+
(doc/:direct_message).inject([]) { |dms, dm| dms << DirectMessage.new_from_xml(dm); dms }
|
86
|
+
end
|
87
|
+
alias :received_messages :direct_messages
|
88
|
+
|
89
|
+
# Returns direct messages sent by auth user
|
90
|
+
def sent_messages(options={})
|
91
|
+
doc = request(build_path('direct_messages/sent.xml', parse_options(options)), {:auth => true, :since => options[:since]})
|
92
|
+
(doc/:direct_message).inject([]) { |dms, dm| dms << DirectMessage.new_from_xml(dm); dms }
|
93
|
+
end
|
94
|
+
|
95
|
+
# destroys a give direct message by id if the auth user is a recipient
|
96
|
+
def destroy_direct_message(id)
|
97
|
+
DirectMessage.new_from_xml(request("direct_messages/destroy/#{id}.xml", :auth => true, :method => :post))
|
98
|
+
end
|
99
|
+
|
100
|
+
# Sends a direct message <code>text</code> to <code>user</code>
|
101
|
+
def d(user, text)
|
102
|
+
DirectMessage.new_from_xml(request('direct_messages/new.xml', :auth => true, :method => :post, :form_data => {'text' => text, 'user' => user}))
|
103
|
+
end
|
104
|
+
|
105
|
+
# Befriends id_or_screenname for the auth user
|
106
|
+
def create_friendship(id_or_screenname)
|
107
|
+
users(request("friendships/create/#{id_or_screenname}.xml", :auth => true, :method => :post)).first
|
108
|
+
end
|
109
|
+
|
110
|
+
# Defriends id_or_screenname for the auth user
|
111
|
+
def destroy_friendship(id_or_screenname)
|
112
|
+
users(request("friendships/destroy/#{id_or_screenname}.xml", :auth => true, :method => :post)).first
|
113
|
+
end
|
114
|
+
|
115
|
+
# Returns true if friendship exists, false if it doesn't.
|
116
|
+
def friendship_exists?(user_a, user_b)
|
117
|
+
doc = request(build_path("friendships/exists.xml", {:user_a => user_a, :user_b => user_b}), :auth => true)
|
118
|
+
doc.at('friends').innerHTML == 'true' ? true : false
|
119
|
+
end
|
120
|
+
|
121
|
+
# Updates your location and returns Twitter::User object
|
122
|
+
def update_location(location)
|
123
|
+
users(request(build_path('account/update_location.xml', {'location' => location}), :auth => true, :method => :post)).first
|
124
|
+
end
|
125
|
+
|
126
|
+
# Updates your deliver device and returns Twitter::User object
|
127
|
+
def update_delivery_device(device)
|
128
|
+
users(request(build_path('account/update_delivery_device.xml', {'device' => device}), :auth => true, :method => :post)).first
|
129
|
+
end
|
130
|
+
|
131
|
+
# Turns notifications by id_or_screenname on for auth user.
|
132
|
+
def follow(id_or_screenname)
|
133
|
+
users(request("notifications/follow/#{id_or_screenname}.xml", :auth => true, :method => :post)).first
|
134
|
+
end
|
135
|
+
|
136
|
+
# Turns notifications by id_or_screenname off for auth user.
|
137
|
+
def leave(id_or_screenname)
|
138
|
+
users(request("notifications/leave/#{id_or_screenname}.xml", :auth => true, :method => :post)).first
|
139
|
+
end
|
140
|
+
|
141
|
+
# Returns the most recent favorite statuses for the autenticating user
|
142
|
+
def favorites(options={})
|
143
|
+
statuses(request(build_path('favorites.xml', parse_options(options)), :auth => true))
|
144
|
+
end
|
145
|
+
|
146
|
+
# Favorites the status specified by id for the auth user
|
147
|
+
def create_favorite(id)
|
148
|
+
statuses(request("favorites/create/#{id}.xml", :auth => true, :method => :post)).first
|
149
|
+
end
|
150
|
+
|
151
|
+
# Un-favorites the status specified by id for the auth user
|
152
|
+
def destroy_favorite(id)
|
153
|
+
statuses(request("favorites/destroy/#{id}.xml", :auth => true, :method => :post)).first
|
154
|
+
end
|
155
|
+
|
156
|
+
# Blocks the user specified by id for the auth user
|
157
|
+
def block(id)
|
158
|
+
users(request("blocks/create/#{id}.xml", :auth => true, :method => :post)).first
|
159
|
+
end
|
160
|
+
|
161
|
+
# Unblocks the user specified by id for the auth user
|
162
|
+
def unblock(id)
|
163
|
+
users(request("blocks/destroy/#{id}.xml", :auth => true, :method => :post)).first
|
164
|
+
end
|
165
|
+
|
166
|
+
# Posts a new update to twitter for auth user.
|
167
|
+
def post(status, options={})
|
168
|
+
form_data = {'status' => status}
|
169
|
+
form_data.merge!({'source' => options[:source]}) if options[:source]
|
170
|
+
Status.new_from_xml(request('statuses/update.xml', :auth => true, :method => :post, :form_data => form_data))
|
171
|
+
end
|
172
|
+
alias :update :post
|
173
|
+
|
174
|
+
# Verifies the credentials for the auth user.
|
175
|
+
# raises Twitter::CantConnect on failure.
|
176
|
+
def verify_credentials
|
177
|
+
request('account/verify_credentials', :auth => true)
|
178
|
+
end
|
179
|
+
|
180
|
+
private
|
181
|
+
# Converts an hpricot doc to an array of statuses
|
182
|
+
def statuses(doc)
|
183
|
+
(doc/:status).inject([]) { |statuses, status| statuses << Status.new_from_xml(status); statuses }
|
184
|
+
end
|
185
|
+
|
186
|
+
# Converts an hpricot doc to an array of users
|
187
|
+
def users(doc)
|
188
|
+
(doc/:user).inject([]) { |users, user| users << User.new_from_xml(user); users }
|
189
|
+
end
|
190
|
+
|
191
|
+
# Calls whatever api method requested that deals with statuses
|
192
|
+
#
|
193
|
+
# ie: call(:public_timeline, :auth => false)
|
194
|
+
def call(method, options={})
|
195
|
+
options.reverse_merge!({ :auth => true, :args => {} })
|
196
|
+
# Following line needed as lite=false doesn't work in the API: http://tinyurl.com/yo3h5d
|
197
|
+
options[:args].delete(:lite) unless options[:args][:lite]
|
198
|
+
args = options.delete(:args)
|
199
|
+
request(build_path("statuses/#{method.to_s}.xml", args), options)
|
200
|
+
end
|
201
|
+
|
202
|
+
# Makes a request to twitter.
|
203
|
+
def request(path, options={})
|
204
|
+
options.reverse_merge!({
|
205
|
+
:headers => { "User-Agent" => @config[:email] },
|
206
|
+
:method => :get
|
207
|
+
})
|
208
|
+
unless options[:since].blank?
|
209
|
+
since = options[:since].kind_of?(Date) ? options[:since].strftime('%a, %d-%b-%y %T GMT') : options[:since].to_s
|
210
|
+
options[:headers]["If-Modified-Since"] = since
|
211
|
+
end
|
212
|
+
|
213
|
+
uri = URI.parse("http://#{@api_host}")
|
214
|
+
|
215
|
+
begin
|
216
|
+
response = Net::HTTP.start(uri.host, 80) do |http|
|
217
|
+
klass = Net::HTTP.const_get options[:method].to_s.downcase.capitalize
|
218
|
+
req = klass.new("#{uri.path}/#{path}", options[:headers])
|
219
|
+
req.basic_auth(@config[:email], @config[:password]) if options[:auth]
|
220
|
+
if options[:method].to_s == 'post' && options[:form_data]
|
221
|
+
req.set_form_data(options[:form_data])
|
222
|
+
end
|
223
|
+
http.read_timeout = @config[:timeout] if @config[:timeout]
|
224
|
+
http.request(req)
|
225
|
+
end
|
226
|
+
rescue => error
|
227
|
+
raise CantConnect, error.message
|
228
|
+
end
|
229
|
+
|
230
|
+
if %w[200 304].include?(response.code)
|
231
|
+
response = parse(response.body)
|
232
|
+
raise RateExceeded if (response/:hash/:error).text =~ /Rate limit exceeded/
|
233
|
+
response
|
234
|
+
elsif response.code == '503'
|
235
|
+
raise Unavailable, response.message
|
236
|
+
elsif response.code == '401'
|
237
|
+
raise CantConnect, 'Authentication failed. Check your username and password'
|
238
|
+
else
|
239
|
+
raise CantConnect, "Twitter is returning a #{response.code}: #{response.message}"
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
# Given a path and a hash, build a full path with the hash turned into a query string
|
244
|
+
def build_path(path, options)
|
245
|
+
path += "?#{options.to_query}" unless options.blank?
|
246
|
+
path
|
247
|
+
end
|
248
|
+
|
249
|
+
# Tries to get all the options in the correct format before making the request
|
250
|
+
def parse_options(options)
|
251
|
+
options[:since] = options[:since].kind_of?(Date) ? options[:since].strftime('%a, %d-%b-%y %T GMT') : options[:since].to_s if options[:since]
|
252
|
+
options
|
253
|
+
end
|
254
|
+
|
255
|
+
# Converts a string response into an Hpricot xml element.
|
256
|
+
def parse(response)
|
257
|
+
Hpricot.XML(response || '')
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|