sml-twitter 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/History +226 -0
  2. data/License +20 -0
  3. data/Notes +33 -0
  4. data/README.rdoc +19 -0
  5. data/Rakefile +40 -0
  6. data/VERSION.yml +5 -0
  7. data/examples/connect.rb +30 -0
  8. data/examples/friendship_existance.rb +13 -0
  9. data/examples/helpers/config_store.rb +38 -0
  10. data/examples/httpauth.rb +11 -0
  11. data/examples/ids.rb +13 -0
  12. data/examples/lists.rb +11 -0
  13. data/examples/oauth.rb +27 -0
  14. data/examples/search.rb +15 -0
  15. data/examples/timeline.rb +19 -0
  16. data/examples/unauthorized.rb +16 -0
  17. data/examples/update.rb +11 -0
  18. data/examples/user.rb +5 -0
  19. data/lib/twitter.rb +63 -0
  20. data/lib/twitter/base.rb +249 -0
  21. data/lib/twitter/httpauth.rb +35 -0
  22. data/lib/twitter/oauth.rb +56 -0
  23. data/lib/twitter/request.rb +118 -0
  24. data/lib/twitter/search.rb +111 -0
  25. data/lib/twitter/trends.rb +29 -0
  26. data/test/fixtures/firehose.json +1 -0
  27. data/test/fixtures/follower_ids.json +1 -0
  28. data/test/fixtures/friend_ids.json +1 -0
  29. data/test/fixtures/friends_timeline.json +1 -0
  30. data/test/fixtures/friendship.json +1 -0
  31. data/test/fixtures/list.json +1 -0
  32. data/test/fixtures/list_statuses.json +1 -0
  33. data/test/fixtures/list_subscriptions.json +1 -0
  34. data/test/fixtures/list_users.json +1 -0
  35. data/test/fixtures/lists.json +1 -0
  36. data/test/fixtures/memberships.json +1 -0
  37. data/test/fixtures/mentions.json +1 -0
  38. data/test/fixtures/rate_limit_exceeded.json +1 -0
  39. data/test/fixtures/search.json +1 -0
  40. data/test/fixtures/search_from_jnunemaker.json +1 -0
  41. data/test/fixtures/status.json +1 -0
  42. data/test/fixtures/status_show.json +1 -0
  43. data/test/fixtures/trends_current.json +1 -0
  44. data/test/fixtures/trends_current_exclude.json +1 -0
  45. data/test/fixtures/trends_daily.json +1 -0
  46. data/test/fixtures/trends_daily_date.json +1 -0
  47. data/test/fixtures/trends_daily_exclude.json +1 -0
  48. data/test/fixtures/trends_weekly.json +1 -0
  49. data/test/fixtures/trends_weekly_date.json +1 -0
  50. data/test/fixtures/trends_weekly_exclude.json +1 -0
  51. data/test/fixtures/user.json +1 -0
  52. data/test/fixtures/user_timeline.json +1 -0
  53. data/test/test_helper.rb +51 -0
  54. data/test/twitter/base_test.rb +214 -0
  55. data/test/twitter/httpauth_test.rb +76 -0
  56. data/test/twitter/oauth_test.rb +108 -0
  57. data/test/twitter/request_test.rb +217 -0
  58. data/test/twitter/search_test.rb +159 -0
  59. data/test/twitter/trends_test.rb +95 -0
  60. data/test/twitter_test.rb +38 -0
  61. metadata +203 -0
data/examples/ids.rb ADDED
@@ -0,0 +1,13 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
2
+ require File.join(File.dirname(__FILE__), 'helpers', 'config_store')
3
+ require 'pp'
4
+
5
+ config = ConfigStore.new("#{ENV['HOME']}/.twitter")
6
+
7
+ oauth = Twitter::OAuth.new(config['token'], config['secret'])
8
+ oauth.authorize_from_access(config['atoken'], config['asecret'])
9
+
10
+ client = Twitter::Base.new(oauth)
11
+
12
+ puts client.friend_ids
13
+ puts client.follower_ids
data/examples/lists.rb ADDED
@@ -0,0 +1,11 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
2
+ require File.join(File.dirname(__FILE__), 'helpers', 'config_store')
3
+ require 'pp'
4
+
5
+ config = ConfigStore.new("#{ENV['HOME']}/.twitter")
6
+
7
+ httpauth = Twitter::HTTPAuth.new(config['email'], config['password'])
8
+ base = Twitter::Base.new(httpauth)
9
+
10
+ pp base.lists('pengwynn')
11
+ pp base.list_members('pengwynn', 'rubyists')
data/examples/oauth.rb ADDED
@@ -0,0 +1,27 @@
1
+ require 'pp'
2
+ require 'pathname'
3
+ dir = Pathname(__FILE__).dirname.expand_path
4
+ require (dir + '..' + 'lib' + 'twitter').expand_path
5
+ require dir + 'helpers' + 'config_store'
6
+
7
+ config = ConfigStore.new("#{ENV['HOME']}/.twitter")
8
+ oauth = Twitter::OAuth.new(config['token'], config['secret'])
9
+ rtoken = oauth.request_token.token
10
+ rsecret = oauth.request_token.secret
11
+
12
+ puts "> redirecting you to twitter to authorize..."
13
+ %x(open #{oauth.request_token.authorize_url})
14
+
15
+ print "> what was the PIN twitter provided you with? "
16
+ pin = gets.chomp
17
+
18
+ begin
19
+ oauth.authorize_from_request(rtoken, rsecret, pin)
20
+
21
+ twitter = Twitter::Base.new(oauth)
22
+ twitter.user_timeline.each do |tweet|
23
+ puts "#{tweet.user.screen_name}: #{tweet.text}"
24
+ end
25
+ rescue OAuth::Unauthorized
26
+ puts "> FAIL!"
27
+ end
@@ -0,0 +1,15 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
2
+ require 'pp'
3
+
4
+ search = Twitter::Search.new.from('jnunemaker')
5
+
6
+ puts '*'*50, 'First Run', '*'*50
7
+ search.each { |result| pp result }
8
+
9
+ puts '*'*50, 'Second Run', '*'*50
10
+ search.each { |result| pp result }
11
+
12
+ puts '*'*50, 'Parameter Check', '*'*50
13
+ pp Twitter::Search.new('#austineats').fetch().results.first
14
+ pp Twitter::Search.new('#austineats').page(2).fetch().results.first
15
+ pp Twitter::Search.new('#austineats').since(1412737343).fetch().results.first
@@ -0,0 +1,19 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
2
+ require File.join(File.dirname(__FILE__), 'helpers', 'config_store')
3
+ require 'pp'
4
+
5
+ config = ConfigStore.new("#{ENV['HOME']}/.twitter")
6
+
7
+ oauth = Twitter::OAuth.new(config['token'], config['secret'])
8
+ oauth.authorize_from_access(config['atoken'], config['asecret'])
9
+
10
+ client = Twitter::Base.new(oauth)
11
+
12
+ pp client.friends_timeline
13
+ puts '*'*50
14
+
15
+ pp client.user_timeline
16
+ puts '*'*50
17
+
18
+ pp client.replies
19
+ puts '*'*50
@@ -0,0 +1,16 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
2
+ require 'pp'
3
+
4
+ puts 'User', '*'*50
5
+ pp Twitter.user('jnunemaker')
6
+ pp Twitter.user('snitch_test')
7
+
8
+ puts 'Status', '*'*50
9
+ pp Twitter.status(1533815199)
10
+
11
+ puts 'Friend Ids', '*'*50
12
+ pp Twitter.friend_ids('jnunemaker')
13
+
14
+ puts 'Follower Ids', '*'*50
15
+ pp Twitter.follower_ids('jnunemaker')
16
+
@@ -0,0 +1,11 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
2
+ require File.join(File.dirname(__FILE__), 'helpers', 'config_store')
3
+ require 'pp'
4
+
5
+ config = ConfigStore.new("#{ENV['HOME']}/.twitter")
6
+
7
+ oauth = Twitter::OAuth.new(config['token'], config['secret'])
8
+ oauth.authorize_from_access(config['atoken'], config['asecret'])
9
+
10
+ client = Twitter::Base.new(oauth)
11
+ pp client.update('This is an update from the twitter gem')
data/examples/user.rb ADDED
@@ -0,0 +1,5 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'twitter')
2
+ require 'pp'
3
+
4
+ pp Twitter.user('jnunemaker')
5
+ pp Twitter.user('snitch_test')
data/lib/twitter.rb ADDED
@@ -0,0 +1,63 @@
1
+ require 'forwardable'
2
+ require 'rubygems'
3
+
4
+ gem 'oauth', '~> 0.3.5'
5
+ require 'oauth'
6
+
7
+ gem 'mash', '~> 0.1.1'
8
+ require 'mash'
9
+
10
+ gem 'httparty', '~> 0.4.3'
11
+ require 'httparty'
12
+
13
+ module Twitter
14
+ class TwitterError < StandardError
15
+ attr_reader :data
16
+
17
+ def initialize(data)
18
+ @data = data
19
+ super
20
+ end
21
+ end
22
+
23
+ class RateLimitExceeded < TwitterError; end
24
+ class Unauthorized < TwitterError; end
25
+ class General < TwitterError; end
26
+
27
+ class Unavailable < StandardError; end
28
+ class InformTwitter < StandardError; end
29
+ class NotFound < StandardError; end
30
+
31
+
32
+ def self.firehose
33
+ response = HTTParty.get('http://twitter.com/statuses/public_timeline.json', :format => :json)
34
+ response.map { |tweet| Mash.new(tweet) }
35
+ end
36
+
37
+ def self.user(id)
38
+ response = HTTParty.get("http://twitter.com/users/show/#{id}.json", :format => :json)
39
+ Mash.new(response)
40
+ end
41
+
42
+ def self.status(id)
43
+ response = HTTParty.get("http://twitter.com/statuses/show/#{id}.json", :format => :json)
44
+ Mash.new(response)
45
+ end
46
+
47
+ def self.friend_ids(id)
48
+ HTTParty.get("http://twitter.com/friends/ids/#{id}.json", :format => :json)
49
+ end
50
+
51
+ def self.follower_ids(id)
52
+ HTTParty.get("http://twitter.com/followers/ids/#{id}.json", :format => :json)
53
+ end
54
+ end
55
+
56
+ directory = File.expand_path(File.dirname(__FILE__))
57
+
58
+ require File.join(directory, 'twitter', 'oauth')
59
+ require File.join(directory, 'twitter', 'httpauth')
60
+ require File.join(directory, 'twitter', 'request')
61
+ require File.join(directory, 'twitter', 'base')
62
+ require File.join(directory, 'twitter', 'search')
63
+ require File.join(directory, 'twitter', 'trends')
@@ -0,0 +1,249 @@
1
+ module Twitter
2
+ class Base
3
+ extend Forwardable
4
+
5
+ def_delegators :client, :get, :post, :put, :delete
6
+
7
+ attr_reader :client
8
+
9
+ def initialize(client)
10
+ @client = client
11
+ end
12
+
13
+ # Options: since_id, max_id, count, page, since
14
+ def friends_timeline(query={})
15
+ perform_get('/statuses/friends_timeline.json', :query => query)
16
+ end
17
+
18
+ # Options: id, user_id, screen_name, since_id, max_id, page, since, count
19
+
20
+ def user_timeline(query={})
21
+ perform_get('/statuses/user_timeline.json', :query => query)
22
+ end
23
+
24
+ def status(id)
25
+ perform_get("/statuses/show/#{id}.json")
26
+ end
27
+
28
+ # Options: in_reply_to_status_id
29
+ def update(status, query={})
30
+ perform_post("/statuses/update.json", :body => {:status => status}.merge(query))
31
+ end
32
+
33
+ # DEPRECATED: Use #mentions instead
34
+ #
35
+ # Options: since_id, max_id, since, page
36
+ def replies(query={})
37
+ warn("DEPRECATED: #replies is deprecated by Twitter; use #mentions instead")
38
+ perform_get('/statuses/replies.json', :query => query)
39
+ end
40
+
41
+ # Options: since_id, max_id, count, page
42
+ def mentions(query={})
43
+ perform_get('/statuses/mentions.json', :query => query)
44
+ end
45
+
46
+ def status_destroy(id)
47
+ perform_post("/statuses/destroy/#{id}.json")
48
+ end
49
+
50
+ # Options: id, user_id, screen_name, page
51
+ def friends(query={})
52
+ perform_get('/statuses/friends.json', :query => query)
53
+ end
54
+
55
+ # Options: id, user_id, screen_name, page
56
+ def followers(query={})
57
+ perform_get('/statuses/followers.json', :query => query)
58
+ end
59
+
60
+ def user(id, query={})
61
+ perform_get("/users/show/#{id}.json", :query => query)
62
+ end
63
+
64
+ # Options: since, since_id, page
65
+ def direct_messages(query={})
66
+ perform_get("/direct_messages.json", :query => query)
67
+ end
68
+
69
+ # Options: since, since_id, page
70
+ def direct_messages_sent(query={})
71
+ perform_get("/direct_messages/sent.json", :query => query)
72
+ end
73
+
74
+ def direct_message_create(user, text)
75
+ perform_post("/direct_messages/new.json", :body => {:user => user, :text => text})
76
+ end
77
+
78
+ def direct_message_destroy(id)
79
+ perform_post("/direct_messages/destroy/#{id}.json")
80
+ end
81
+
82
+ def friendship_create(id, follow=false)
83
+ body = {}
84
+ body.merge!(:follow => follow) if follow
85
+ perform_post("/friendships/create/#{id}.json", :body => body)
86
+ end
87
+
88
+ def friendship_destroy(id)
89
+ perform_post("/friendships/destroy/#{id}.json")
90
+ end
91
+
92
+ def friendship_exists?(a, b)
93
+ perform_get("/friendships/exists.json", :query => {:user_a => a, :user_b => b})
94
+ end
95
+
96
+ def friendship_show(query)
97
+ perform_get("/friendships/show.json", :query => query)
98
+ end
99
+
100
+ # Options: id, user_id, screen_name
101
+ def friend_ids(query={})
102
+ perform_get("/friends/ids.json", :query => query, :mash => false)
103
+ end
104
+
105
+ # Options: id, user_id, screen_name
106
+ def follower_ids(query={})
107
+ perform_get("/followers/ids.json", :query => query, :mash => false)
108
+ end
109
+
110
+ def verify_credentials
111
+ perform_get("/account/verify_credentials.json")
112
+ end
113
+
114
+ # Device must be sms, im or none
115
+ def update_delivery_device(device)
116
+ perform_post('/account/update_delivery_device.json', :body => {:device => device})
117
+ end
118
+
119
+ # One or more of the following must be present:
120
+ # profile_background_color, profile_text_color, profile_link_color,
121
+ # profile_sidebar_fill_color, profile_sidebar_border_color
122
+ def update_profile_colors(colors={})
123
+ perform_post('/account/update_profile_colors.json', :body => colors)
124
+ end
125
+
126
+ def rate_limit_status
127
+ perform_get('/account/rate_limit_status.json')
128
+ end
129
+
130
+ # One or more of the following must be present:
131
+ # name, email, url, location, description
132
+ def update_profile(body={})
133
+ perform_post('/account/update_profile.json', :body => body)
134
+ end
135
+
136
+ # Options: id, page
137
+ def favorites(query={})
138
+ perform_get('/favorites.json', :query => query)
139
+ end
140
+
141
+ def favorite_create(id)
142
+ perform_post("/favorites/create/#{id}.json")
143
+ end
144
+
145
+ def favorite_destroy(id)
146
+ perform_post("/favorites/destroy/#{id}.json")
147
+ end
148
+
149
+ def enable_notifications(id)
150
+ perform_post("/notifications/follow/#{id}.json")
151
+ end
152
+
153
+ def disable_notifications(id)
154
+ perform_post("/notifications/leave/#{id}.json")
155
+ end
156
+
157
+ def block(id)
158
+ perform_post("/blocks/create/#{id}.json")
159
+ end
160
+
161
+ def unblock(id)
162
+ perform_post("/blocks/destroy/#{id}.json")
163
+ end
164
+
165
+ def help
166
+ perform_get('/help/test.json')
167
+ end
168
+
169
+ def list_create(list_owner_username, options)
170
+ perform_post("/#{list_owner_username}/lists.json", :body => {:user => list_owner_username}.merge(options))
171
+ end
172
+
173
+ def list_update(list_owner_username, slug, options)
174
+ perform_put("/#{list_owner_username}/lists/#{slug}.json", :body => options)
175
+ end
176
+
177
+ def list_delete(list_owner_username, slug)
178
+ perform_delete("/#{list_owner_username}/lists/#{slug}.json")
179
+ end
180
+
181
+ def lists(list_owner_username=nil)
182
+ path = "http://api.twitter.com/1"
183
+ path += "/#{list_owner_username}" if list_owner_username
184
+ path += "/lists.json"
185
+ perform_get(path)
186
+ end
187
+
188
+ def list(list_owner_username, slug)
189
+ perform_get("/#{list_owner_username}/lists/#{slug}.json")
190
+ end
191
+
192
+ def list_timeline(list_owner_username, slug)
193
+ perform_get("/#{list_owner_username}/lists/#{slug}/statuses.json")
194
+ end
195
+
196
+ def memberships(list_owner_username)
197
+ perform_get("/#{list_owner_username}/lists/memberships.json")
198
+ end
199
+
200
+ def list_members(list_owner_username, slug)
201
+ perform_get("/#{list_owner_username}/#{slug}/members.json")
202
+ end
203
+
204
+ def list_add_member(list_owner_username, slug, new_id)
205
+ perform_post("/#{list_owner_username}/#{slug}/members.json", :body => {:id => new_id})
206
+ end
207
+
208
+ def list_remove_member(list_owner_username, slug, id)
209
+ perform_delete("/#{list_owner_username}/#{slug}/members.json", :body => {:id => id})
210
+ end
211
+
212
+ def is_list_member?(list_owner_username, slug, id)
213
+ perform_get("/#{list_owner_username}/#{slug}/members/#{id}.json").error.nil?
214
+ end
215
+
216
+ def list_subscribers(list_owner_username, slug)
217
+ perform_get("/#{list_owner_username}/#{slug}/subscribers.json")
218
+ end
219
+
220
+ def list_subscribe(list_owner_username, slug)
221
+ perform_post("/#{list_owner_username}/#{slug}/subscribers.json")
222
+ end
223
+
224
+ def list_unsubscribe(list_owner_username, slug)
225
+ perform_delete("/#{list_owner_username}/#{slug}/subscribers.json")
226
+ end
227
+
228
+ def list_subscriptions(list_owner_username)
229
+ perform_get("/#{list_owner_username}/lists/subscriptions.json")
230
+ end
231
+
232
+ private
233
+ def perform_get(path, options={})
234
+ Twitter::Request.get(self, path, options)
235
+ end
236
+
237
+ def perform_post(path, options={})
238
+ Twitter::Request.post(self, path, options)
239
+ end
240
+
241
+ def perform_put(path, options={})
242
+ Twitter::Request.put(self, path, options)
243
+ end
244
+
245
+ def perform_delete(path, options={})
246
+ Twitter::Request.delete(self, path, options)
247
+ end
248
+ end
249
+ end
@@ -0,0 +1,35 @@
1
+ module Twitter
2
+ class HTTPAuth
3
+ include HTTParty
4
+ format :plain
5
+
6
+ attr_reader :username, :password, :options
7
+
8
+ def initialize(username, password, options={})
9
+ @username, @password = username, password
10
+ @options = {:ssl => false}.merge(options)
11
+ self.class.base_uri "http#{'s' if options[:ssl]}://twitter.com"
12
+ end
13
+
14
+ def get(uri, headers={})
15
+ self.class.get(uri, :headers => headers, :basic_auth => basic_auth)
16
+ end
17
+
18
+ def post(uri, body={}, headers={})
19
+ self.class.post(uri, :body => body, :headers => headers, :basic_auth => basic_auth)
20
+ end
21
+
22
+ def put(uri, body={}, headers={})
23
+ self.class.put(uri, :body => body, :headers => headers, :basic_auth => basic_auth)
24
+ end
25
+
26
+ def delete(uri, body={}, headers={})
27
+ self.class.delete(uri, :body => body, :headers => headers, :basic_auth => basic_auth)
28
+ end
29
+
30
+ private
31
+ def basic_auth
32
+ @basic_auth ||= {:username => @username, :password => @password}
33
+ end
34
+ end
35
+ end