t 2.2.1 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a30a59d381d4a4e6815086c4e45d1541fb372855
4
- data.tar.gz: 300d0fedac30548d0fea628774e4b9a632716017
3
+ metadata.gz: de38f7eb78340ae96773b30fffb581a6b4e8d0c0
4
+ data.tar.gz: f1f4f6488de9009b9b2c53bee89726f8bcf2688b
5
5
  SHA512:
6
- metadata.gz: 09c862bc9a765df7f652ea0820631c8d284266df0a87af3a9840694c9a1ce75cdae8e143c8312eba5cae686194185602ffe2b90e9f7d0633c80c3c43b0c8bab7
7
- data.tar.gz: 15970f41bc2c623d6040eeb3fb7cc721ac67742b4697ec4826e6d1d8123525b4e9e039a6485299b545c625482cd77c1cde917146a6540a1217d2205def19aa71
6
+ metadata.gz: 5b29427b22863093b80888ef7b5cb71ebfb8d69c64256e7009258541c6af70d7bc7e6a4cbb54ce9e1c5557fd9b5c9f685450b3bf0e3259689d3b2c590b5e5be4
7
+ data.tar.gz: 1f1d755455a52571b9589487b4406e91451ed59d28d13e7818eb21589c75372036a363660e5479d83dff655958863dc246314573903cc33a75449d5cf66f8ac6
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
data/README.md CHANGED
@@ -6,13 +6,13 @@
6
6
  [![Build Status](https://secure.travis-ci.org/sferik/t.png?branch=master)][travis]
7
7
  [![Dependency Status](https://gemnasium.com/sferik/t.png?travis)][gemnasium]
8
8
  [![Coverage Status](https://coveralls.io/repos/sferik/t/badge.png?branch=master)][coveralls]
9
- [![Gittip](http://img.shields.io/gittip/sferik.png)][gittip]
9
+ [![Gittip](http://img.shields.io/gittip/gems.png)][gittip]
10
10
 
11
11
  [gem]: https://rubygems.org/gems/t
12
12
  [travis]: http://travis-ci.org/sferik/t
13
13
  [gemnasium]: https://gemnasium.com/sferik/t
14
14
  [coveralls]: https://coveralls.io/r/sferik/t
15
- [gittip]: https://www.gittip.com/sferik/
15
+ [gittip]: https://www.gittip.com/gems/
16
16
 
17
17
  #### A command-line power tool for Twitter.
18
18
  The CLI takes syntactic cues from the [Twitter SMS commands][sms], but it
data/bin/t CHANGED
@@ -13,7 +13,7 @@ def pute(*args)
13
13
  first = args.shift.dup
14
14
  first.insert(0, "#{$PROGRAM_NAME}: ")
15
15
  args.unshift(first)
16
- abort(*args)
16
+ abort(args.join("\n"))
17
17
  end
18
18
 
19
19
  begin
@@ -24,7 +24,7 @@ rescue OAuth::Unauthorized
24
24
  pute 'Authorization failed'
25
25
  rescue Twitter::Error::TooManyRequests => error
26
26
  pute error.message,
27
- "The rate limit for this request will reset in #{error.rate_limit.reset_in} seconds.",
27
+ "The rate limit for this request will reset in #{error.rate_limit.reset_in} #{error.rate_limit.reset_in == 1 ? 'second' : 'seconds'}.",
28
28
  'While you wait, consider making a polite request for Twitter to increase the API rate limit at https://dev.twitter.com/discussions/10644'
29
29
  rescue Twitter::Error::BadRequest => error
30
30
  pute error.message,
data/lib/t/cli.rb CHANGED
@@ -49,7 +49,7 @@ module T
49
49
  end
50
50
 
51
51
  desc 'authorize', 'Allows an application to request user authorization'
52
- method_option 'display-uri', :aliases => '-d', :type => :boolean, :default => false, :desc => 'Display the authorization URL instead of attempting to open it.'
52
+ method_option 'display-uri', :aliases => '-d', :type => :boolean, :desc => 'Display the authorization URL instead of attempting to open it.'
53
53
  def authorize
54
54
  @rcfile.path = options['profile'] if options['profile']
55
55
  if @rcfile.empty?
@@ -112,23 +112,23 @@ module T
112
112
  end
113
113
 
114
114
  desc 'block USER [USER...]', 'Block users.'
115
- method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify input as Twitter user IDs instead of screen names.'
115
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify input as Twitter user IDs instead of screen names.'
116
116
  def block(user, *users)
117
117
  blocked_users, number = fetch_users(users.unshift(user), options) do |users_to_block|
118
118
  client.block(users_to_block)
119
119
  end
120
120
  say "@#{@rcfile.active_profile[0]} blocked #{pluralize(number, 'user')}."
121
121
  say
122
- say "Run `#{File.basename($PROGRAM_NAME)} delete block #{blocked_users.map { |blocked_user| "@#{blocked_user.screen_name}" }.join(' ')}` to unblock."
122
+ say "Run `#{File.basename($PROGRAM_NAME)} delete block #{blocked_users.collect { |blocked_user| "@#{blocked_user.screen_name}" }.join(' ')}` to unblock."
123
123
  end
124
124
 
125
125
  desc 'direct_messages', "Returns the #{DEFAULT_NUM_RESULTS} most recent Direct Messages sent to you."
126
- method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
127
- method_option 'decode_uris', :aliases => '-d', :type => :boolean, :default => false, :desc => 'Decodes t.co URLs into their original form.'
128
- method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
129
- method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
126
+ method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
127
+ method_option 'decode_uris', :aliases => '-d', :type => :boolean, :desc => 'Decodes t.co URLs into their original form.'
128
+ method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
130
129
  method_option 'number', :aliases => '-n', :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => 'Limit the number of results.'
131
- method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
130
+ method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
131
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :desc => 'Reverse the order of the sort.'
132
132
  def direct_messages
133
133
  count = options['number'] || DEFAULT_NUM_RESULTS
134
134
  opts = {}
@@ -144,10 +144,10 @@ module T
144
144
  say [direct_message.id, csv_formatted_time(direct_message), direct_message.sender.screen_name, decode_full_text(direct_message, options['decode_uris'])].to_csv
145
145
  end
146
146
  elsif options['long']
147
- array = direct_messages.map do |direct_message|
147
+ array = direct_messages.collect do |direct_message|
148
148
  [direct_message.id, ls_formatted_time(direct_message), "@#{direct_message.sender.screen_name}", decode_full_text(direct_message, options['decode_uris']).gsub(/\n+/, ' ')]
149
149
  end
150
- format = options['format'] || DIRECT_MESSAGE_HEADINGS.size.times.map { '%s' }
150
+ format = options['format'] || DIRECT_MESSAGE_HEADINGS.size.times.collect { '%s' }
151
151
  print_table_with_headings(array, DIRECT_MESSAGE_HEADINGS, format)
152
152
  else
153
153
  direct_messages.each do |direct_message|
@@ -158,12 +158,12 @@ module T
158
158
  map %w[directmessages dms] => :direct_messages
159
159
 
160
160
  desc 'direct_messages_sent', "Returns the #{DEFAULT_NUM_RESULTS} most recent Direct Messages you've sent."
161
- method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
162
- method_option 'decode_uris', :aliases => '-d', :type => :boolean, :default => false, :desc => 'Decodes t.co URLs into their original form.'
163
- method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
161
+ method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
162
+ method_option 'decode_uris', :aliases => '-d', :type => :boolean, :desc => 'Decodes t.co URLs into their original form.'
163
+ method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
164
164
  method_option 'number', :aliases => '-n', :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => 'Limit the number of results.'
165
165
  method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
166
- method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
166
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :desc => 'Reverse the order of the sort.'
167
167
  def direct_messages_sent
168
168
  count = options['number'] || DEFAULT_NUM_RESULTS
169
169
  opts = {}
@@ -179,10 +179,10 @@ module T
179
179
  say [direct_message.id, csv_formatted_time(direct_message), direct_message.recipient.screen_name, decode_full_text(direct_message, options['decode_uris'])].to_csv
180
180
  end
181
181
  elsif options['long']
182
- array = direct_messages.map do |direct_message|
182
+ array = direct_messages.collect do |direct_message|
183
183
  [direct_message.id, ls_formatted_time(direct_message), "@#{direct_message.recipient.screen_name}", decode_full_text(direct_message, options['decode_uris']).gsub(/\n+/, ' ')]
184
184
  end
185
- format = options['format'] || DIRECT_MESSAGE_HEADINGS.size.times.map { '%s' }
185
+ format = options['format'] || DIRECT_MESSAGE_HEADINGS.size.times.collect { '%s' }
186
186
  print_table_with_headings(array, DIRECT_MESSAGE_HEADINGS, format)
187
187
  else
188
188
  direct_messages.each do |direct_message|
@@ -192,34 +192,8 @@ module T
192
192
  end
193
193
  map %w[directmessagessent sent_messages sentmessages sms] => :direct_messages_sent
194
194
 
195
- desc 'groupies [USER]', "Returns the list of people who follow you but you don't follow back."
196
- method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
197
- method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
198
- method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
199
- method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
200
- method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
201
- method_option 'sort', :aliases => '-s', :type => :string, :enum => %w[favorites followers friends listed screen_name since tweets tweeted], :default => 'screen_name', :desc => 'Specify the order of the results.', :banner => 'ORDER'
202
- method_option 'unsorted', :aliases => '-u', :type => :boolean, :default => false, :desc => 'Output is not sorted.'
203
- def groupies(user = nil)
204
- user = if user
205
- require 't/core_ext/string'
206
- options['id'] ? user.to_i : user.strip_ats
207
- else
208
- client.verify_credentials.screen_name
209
- end
210
- follower_ids = Thread.new { client.follower_ids(user).to_a }
211
- following_ids = Thread.new { client.friend_ids(user).to_a }
212
- disciple_ids = (follower_ids.value - following_ids.value)
213
- require 'retryable'
214
- users = retryable(:tries => 3, :on => Twitter::Error, :sleep => 0) do
215
- client.users(disciple_ids)
216
- end
217
- print_users(users)
218
- end
219
- map %w[disciples] => :groupies
220
-
221
195
  desc 'dm USER MESSAGE', 'Sends that person a Direct Message.'
222
- method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
196
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify user via ID instead of screen name.'
223
197
  def dm(user, message)
224
198
  require 't/core_ext/string'
225
199
  user = options['id'] ? user.to_i : user.strip_ats
@@ -229,7 +203,7 @@ module T
229
203
  map %w[d m] => :dm
230
204
 
231
205
  desc 'does_contain [USER/]LIST USER', 'Find out whether a list contains a user.'
232
- method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
206
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify user via ID instead of screen name.'
233
207
  def does_contain(list, user = nil)
234
208
  owner, list = extract_owner(list, options)
235
209
  if user.nil?
@@ -247,7 +221,7 @@ module T
247
221
  map %w[dc doescontain] => :does_contain
248
222
 
249
223
  desc 'does_follow USER [USER]', 'Find out whether one user follows another.'
250
- method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
224
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify user via ID instead of screen name.'
251
225
  def does_follow(user1, user2 = nil)
252
226
  require 't/core_ext/string'
253
227
  thread1 = if options['id']
@@ -276,7 +250,7 @@ module T
276
250
  desc 'favorite TWEET_ID [TWEET_ID...]', 'Marks Tweets as favorites.'
277
251
  def favorite(status_id, *status_ids)
278
252
  status_ids.unshift(status_id)
279
- status_ids.map!(&:to_i)
253
+ status_ids.collect!(&:to_i)
280
254
  require 'retryable'
281
255
  favorites = retryable(:tries => 3, :on => Twitter::Error, :sleep => 0) do
282
256
  client.favorite(status_ids)
@@ -289,14 +263,14 @@ module T
289
263
  map %w[fave favourite] => :favorite
290
264
 
291
265
  desc 'favorites [USER]', "Returns the #{DEFAULT_NUM_RESULTS} most recent Tweets you favorited."
292
- method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
293
- method_option 'decode_uris', :aliases => '-d', :type => :boolean, :default => false, :desc => 'Decodes t.co URLs into their original form.'
294
- method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
295
- method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
266
+ method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
267
+ method_option 'decode_uris', :aliases => '-d', :type => :boolean, :desc => 'Decodes t.co URLs into their original form.'
268
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify user via ID instead of screen name.'
269
+ method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
296
270
  method_option 'max_id', :aliases => '-m', :type => :numeric, :desc => 'Returns only the results with an ID less than the specified ID.'
297
271
  method_option 'number', :aliases => '-n', :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => 'Limit the number of results.'
298
272
  method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
299
- method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
273
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :desc => 'Reverse the order of the sort.'
300
274
  method_option 'since_id', :aliases => '-s', :type => :numeric, :desc => 'Returns only the results with an ID greater than the specified ID.'
301
275
  def favorites(user = nil)
302
276
  count = options['number'] || DEFAULT_NUM_RESULTS
@@ -318,24 +292,24 @@ module T
318
292
  map %w[faves favourites] => :favorites
319
293
 
320
294
  desc 'follow USER [USER...]', 'Allows you to start following users.'
321
- method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify input as Twitter user IDs instead of screen names.'
295
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify input as Twitter user IDs instead of screen names.'
322
296
  def follow(user, *users)
323
297
  followed_users, number = fetch_users(users.unshift(user), options) do |users_to_follow|
324
298
  client.follow(users_to_follow)
325
299
  end
326
300
  say "@#{@rcfile.active_profile[0]} is now following #{pluralize(number, 'more user')}."
327
301
  say
328
- say "Run `#{File.basename($PROGRAM_NAME)} unfollow #{followed_users.map { |followed_user| "@#{followed_user.screen_name}" }.join(' ')}` to stop."
302
+ say "Run `#{File.basename($PROGRAM_NAME)} unfollow #{followed_users.collect { |followed_user| "@#{followed_user.screen_name}" }.join(' ')}` to stop."
329
303
  end
330
304
 
331
305
  desc 'followings [USER]', 'Returns a list of the people you follow on Twitter.'
332
- method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
333
- method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
334
- method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
306
+ method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
307
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify user via ID instead of screen name.'
308
+ method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
335
309
  method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
336
- method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
310
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :desc => 'Reverse the order of the sort.'
337
311
  method_option 'sort', :aliases => '-s', :type => :string, :enum => %w[favorites followers friends listed screen_name since tweets tweeted], :default => 'screen_name', :desc => 'Specify the order of the results.', :banner => 'ORDER'
338
- method_option 'unsorted', :aliases => '-u', :type => :boolean, :default => false, :desc => 'Output is not sorted.'
312
+ method_option 'unsorted', :aliases => '-u', :type => :boolean, :desc => 'Output is not sorted.'
339
313
  def followings(user = nil)
340
314
  if user
341
315
  require 't/core_ext/string'
@@ -349,14 +323,41 @@ module T
349
323
  print_users(users)
350
324
  end
351
325
 
326
+ desc 'followings_following USER [USER]', 'Displays your friends who follow the specified user.'
327
+ method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
328
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify input as Twitter user IDs instead of screen names.'
329
+ method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
330
+ method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
331
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :desc => 'Reverse the order of the sort.'
332
+ method_option 'sort', :aliases => '-s', :type => :string, :enum => %w[favorites followers friends listed screen_name since tweets tweeted], :default => 'screen_name', :desc => 'Specify the order of the results.', :banner => 'ORDER'
333
+ method_option 'unsorted', :aliases => '-u', :type => :boolean, :desc => 'Output is not sorted.'
334
+ def followings_following(user1, user2 = nil)
335
+ require 't/core_ext/string'
336
+ user1 = options['id'] ? user1.to_i : user1.strip_ats
337
+ user2 = if user2.nil?
338
+ @rcfile.active_profile[0]
339
+ else
340
+ options['id'] ? user2.to_i : user2.strip_ats
341
+ end
342
+ follower_ids = Thread.new { client.follower_ids(user1).to_a }
343
+ following_ids = Thread.new { client.friend_ids(user2).to_a }
344
+ followings_following_ids = follower_ids.value & following_ids.value
345
+ require 'retryable'
346
+ users = retryable(:tries => 3, :on => Twitter::Error, :sleep => 0) do
347
+ client.users(followings_following_ids)
348
+ end
349
+ print_users(users)
350
+ end
351
+ map %w[ff followingsfollowing] => :followings_following
352
+
352
353
  desc 'followers [USER]', 'Returns a list of the people who follow you on Twitter.'
353
- method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
354
- method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
355
- method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
354
+ method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
355
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify user via ID instead of screen name.'
356
+ method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
356
357
  method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
357
- method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
358
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :desc => 'Reverse the order of the sort.'
358
359
  method_option 'sort', :aliases => '-s', :type => :string, :enum => %w[favorites followers friends listed screen_name since tweets tweeted], :default => 'screen_name', :desc => 'Specify the order of the results.', :banner => 'ORDER'
359
- method_option 'unsorted', :aliases => '-u', :type => :boolean, :default => false, :desc => 'Output is not sorted.'
360
+ method_option 'unsorted', :aliases => '-u', :type => :boolean, :desc => 'Output is not sorted.'
360
361
  def followers(user = nil)
361
362
  if user
362
363
  require 't/core_ext/string'
@@ -371,13 +372,13 @@ module T
371
372
  end
372
373
 
373
374
  desc 'friends [USER]', 'Returns the list of people who you follow and follow you back.'
374
- method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
375
- method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
376
- method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
375
+ method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
376
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify user via ID instead of screen name.'
377
+ method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
377
378
  method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
378
- method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
379
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :desc => 'Reverse the order of the sort.'
379
380
  method_option 'sort', :aliases => '-s', :type => :string, :enum => %w[favorites followers friends listed screen_name since tweets tweeted], :default => 'screen_name', :desc => 'Specify the order of the results.', :banner => 'ORDER'
380
- method_option 'unsorted', :aliases => '-u', :type => :boolean, :default => false, :desc => 'Output is not sorted.'
381
+ method_option 'unsorted', :aliases => '-u', :type => :boolean, :desc => 'Output is not sorted.'
381
382
  def friends(user = nil)
382
383
  user = if user
383
384
  require 't/core_ext/string'
@@ -387,7 +388,7 @@ module T
387
388
  end
388
389
  following_ids = Thread.new { client.friend_ids(user).to_a }
389
390
  follower_ids = Thread.new { client.follower_ids(user).to_a }
390
- friend_ids = (following_ids.value & follower_ids.value)
391
+ friend_ids = following_ids.value & follower_ids.value
391
392
  require 'retryable'
392
393
  users = retryable(:tries => 3, :on => Twitter::Error, :sleep => 0) do
393
394
  client.users(friend_ids)
@@ -395,14 +396,72 @@ module T
395
396
  print_users(users)
396
397
  end
397
398
 
399
+ desc 'groupies [USER]', "Returns the list of people who follow you but you don't follow back."
400
+ method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
401
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify user via ID instead of screen name.'
402
+ method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
403
+ method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
404
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :desc => 'Reverse the order of the sort.'
405
+ method_option 'sort', :aliases => '-s', :type => :string, :enum => %w[favorites followers friends listed screen_name since tweets tweeted], :default => 'screen_name', :desc => 'Specify the order of the results.', :banner => 'ORDER'
406
+ method_option 'unsorted', :aliases => '-u', :type => :boolean, :desc => 'Output is not sorted.'
407
+ def groupies(user = nil)
408
+ user = if user
409
+ require 't/core_ext/string'
410
+ options['id'] ? user.to_i : user.strip_ats
411
+ else
412
+ client.verify_credentials.screen_name
413
+ end
414
+ follower_ids = Thread.new { client.follower_ids(user).to_a }
415
+ following_ids = Thread.new { client.friend_ids(user).to_a }
416
+ disciple_ids = (follower_ids.value - following_ids.value)
417
+ require 'retryable'
418
+ users = retryable(:tries => 3, :on => Twitter::Error, :sleep => 0) do
419
+ client.users(disciple_ids)
420
+ end
421
+ print_users(users)
422
+ end
423
+ map %w[disciples] => :groupies
424
+
425
+ desc 'intersection USER [USER...]', 'Displays the intersection of users followed by the specified users.'
426
+ method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
427
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify input as Twitter user IDs instead of screen names.'
428
+ method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
429
+ method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
430
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :desc => 'Reverse the order of the sort.'
431
+ method_option 'sort', :aliases => '-s', :type => :string, :enum => %w[favorites followers friends listed screen_name since tweets tweeted], :default => 'screen_name', :desc => 'Specify the order of the results.', :banner => 'ORDER'
432
+ method_option 'type', :aliases => '-t', :type => :string, :enum => %w[followers followings], :default => 'followings', :desc => 'Specify the typo of intersection.'
433
+ method_option 'unsorted', :aliases => '-u', :type => :boolean, :desc => 'Output is not sorted.'
434
+ def intersection(first_user, *users)
435
+ users.push(first_user)
436
+ # If only one user is specified, compare to the authenticated user
437
+ users.push(@rcfile.active_profile[0]) if users.size == 1
438
+ require 't/core_ext/string'
439
+ options['id'] ? users.collect!(&:to_i) : users.collect!(&:strip_ats)
440
+ sets = parallel_map(users) do |user|
441
+ case options['type']
442
+ when 'followings'
443
+ client.friend_ids(user).to_a
444
+ when 'followers'
445
+ client.follower_ids(user).to_a
446
+ end
447
+ end
448
+ intersection = sets.reduce(:&)
449
+ require 'retryable'
450
+ users = retryable(:tries => 3, :on => Twitter::Error, :sleep => 0) do
451
+ client.users(intersection)
452
+ end
453
+ print_users(users)
454
+ end
455
+ map %w[overlap] => :intersection
456
+
398
457
  desc 'leaders [USER]', "Returns the list of people who you follow but don't follow you back."
399
- method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
400
- method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
401
- method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
458
+ method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
459
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify user via ID instead of screen name.'
460
+ method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
402
461
  method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
403
- method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
462
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :desc => 'Reverse the order of the sort.'
404
463
  method_option 'sort', :aliases => '-s', :type => :string, :enum => %w[favorites followers friends listed screen_name since tweets tweeted], :default => 'screen_name', :desc => 'Specify the order of the results.', :banner => 'ORDER'
405
- method_option 'unsorted', :aliases => '-u', :type => :boolean, :default => false, :desc => 'Output is not sorted.'
464
+ method_option 'unsorted', :aliases => '-u', :type => :boolean, :desc => 'Output is not sorted.'
406
465
  def leaders(user = nil)
407
466
  user = if user
408
467
  require 't/core_ext/string'
@@ -421,13 +480,13 @@ module T
421
480
  end
422
481
 
423
482
  desc 'lists [USER]', 'Returns the lists created by a user.'
424
- method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
425
- method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
426
- method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
483
+ method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
484
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify user via ID instead of screen name.'
485
+ method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
427
486
  method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
428
- method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
487
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :desc => 'Reverse the order of the sort.'
429
488
  method_option 'sort', :aliases => '-s', :type => :string, :enum => %w[members mode since slug subscribers], :default => 'slug', :desc => 'Specify the order of the results.', :banner => 'ORDER'
430
- method_option 'unsorted', :aliases => '-u', :type => :boolean, :default => false, :desc => 'Output is not sorted.'
489
+ method_option 'unsorted', :aliases => '-u', :type => :boolean, :desc => 'Output is not sorted.'
431
490
  def lists(user = nil)
432
491
  lists = if user
433
492
  require 't/core_ext/string'
@@ -443,12 +502,12 @@ module T
443
502
  def_delegator :"T::Stream.new", :matrix # rubocop:disable SymbolName
444
503
 
445
504
  desc 'mentions', "Returns the #{DEFAULT_NUM_RESULTS} most recent Tweets mentioning you."
446
- method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
447
- method_option 'decode_uris', :aliases => '-d', :type => :boolean, :default => false, :desc => 'Decodes t.co URLs into their original form.'
448
- method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
505
+ method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
506
+ method_option 'decode_uris', :aliases => '-d', :type => :boolean, :desc => 'Decodes t.co URLs into their original form.'
507
+ method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
449
508
  method_option 'number', :aliases => '-n', :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => 'Limit the number of results.'
450
509
  method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
451
- method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
510
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :desc => 'Reverse the order of the sort.'
452
511
  def mentions
453
512
  count = options['number'] || DEFAULT_NUM_RESULTS
454
513
  opts = {}
@@ -461,14 +520,14 @@ module T
461
520
  map %w[replies] => :mentions
462
521
 
463
522
  desc 'open USER', "Opens that user's profile in a web browser."
464
- method_option 'display-uri', :aliases => '-d', :type => :boolean, :default => false, :desc => 'Display the requested URL instead of attempting to open it.'
465
- method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
466
- method_option 'status', :aliases => '-s', :type => :boolean, :default => false, :desc => 'Specify input as a Twitter status ID instead of a screen name.'
523
+ method_option 'display-uri', :aliases => '-d', :type => :boolean, :desc => 'Display the requested URL instead of attempting to open it.'
524
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify user via ID instead of screen name.'
525
+ method_option 'status', :aliases => '-s', :type => :boolean, :desc => 'Specify input as a Twitter status ID instead of a screen name.'
467
526
  def open(user)
468
527
  require 'launchy'
469
528
  if options['id']
470
529
  user = client.user(user.to_i)
471
- open_or_print(user.website, :dry_run => options['display-uri'])
530
+ open_or_print(user.uri, :dry_run => options['display-uri'])
472
531
  elsif options['status']
473
532
  status = client.status(user.to_i, :include_my_retweet => false)
474
533
  open_or_print(status.uri, :dry_run => options['display-uri'])
@@ -479,7 +538,7 @@ module T
479
538
  end
480
539
 
481
540
  desc 'reply TWEET_ID MESSAGE', 'Post your Tweet as a reply directed at another person.'
482
- method_option 'all', :aliases => '-a', :type => :boolean, :default => false, :desc => 'Reply to all users mentioned in the Tweet.'
541
+ method_option 'all', :aliases => '-a', :type => :boolean, :desc => 'Reply to all users mentioned in the Tweet.'
483
542
  method_option 'location', :aliases => '-l', :type => :string, :default => nil, :desc => "Add location information. If the optional 'latitude,longitude' parameter is not supplied, looks up location by IP address."
484
543
  def reply(status_id, message)
485
544
  status = client.status(status_id.to_i, :include_my_retweet => false)
@@ -488,8 +547,9 @@ module T
488
547
  users += extract_mentioned_screen_names(status.full_text)
489
548
  users.uniq!
490
549
  end
550
+ users.delete(@rcfile.active_profile[0])
491
551
  require 't/core_ext/string'
492
- users.map!(&:prepend_at)
552
+ users.collect!(&:prepend_at)
493
553
  opts = {:in_reply_to_status_id => status.id, :trim_user => true}
494
554
  add_location!(options, opts)
495
555
  reply = client.update("#{users.join(' ')} #{message}", opts)
@@ -499,7 +559,7 @@ module T
499
559
  end
500
560
 
501
561
  desc 'report_spam USER [USER...]', 'Report users for spam.'
502
- method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify input as Twitter user IDs instead of screen names.'
562
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify input as Twitter user IDs instead of screen names.'
503
563
  def report_spam(user, *users)
504
564
  _, number = fetch_users(users.unshift(user), options) do |users_to_report|
505
565
  client.report_spam(users_to_report)
@@ -511,7 +571,7 @@ module T
511
571
  desc 'retweet TWEET_ID [TWEET_ID...]', 'Sends Tweets to your followers.'
512
572
  def retweet(status_id, *status_ids)
513
573
  status_ids.unshift(status_id)
514
- status_ids.map!(&:to_i)
574
+ status_ids.collect!(&:to_i)
515
575
  require 'retryable'
516
576
  retweets = retryable(:tries => 3, :on => Twitter::Error, :sleep => 0) do
517
577
  client.retweet(status_ids, :trim_user => true)
@@ -519,18 +579,18 @@ module T
519
579
  number = retweets.length
520
580
  say "@#{@rcfile.active_profile[0]} retweeted #{pluralize(number, 'tweet')}."
521
581
  say
522
- say "Run `#{File.basename($PROGRAM_NAME)} delete status #{retweets.map { |tweet| tweet.retweeted_status.id }.join(' ')}` to undo."
582
+ say "Run `#{File.basename($PROGRAM_NAME)} delete status #{retweets.collect { |tweet| tweet.retweeted_status.id }.join(' ')}` to undo."
523
583
  end
524
584
  map %w[rt] => :retweet
525
585
 
526
586
  desc 'retweets [USER]', "Returns the #{DEFAULT_NUM_RESULTS} most recent Retweets by a user."
527
- method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
528
- method_option 'decode_uris', :aliases => '-d', :type => :boolean, :default => false, :desc => 'Decodes t.co URLs into their original form.'
529
- method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
530
- method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
587
+ method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
588
+ method_option 'decode_uris', :aliases => '-d', :type => :boolean, :desc => 'Decodes t.co URLs into their original form.'
589
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify user via ID instead of screen name.'
590
+ method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
531
591
  method_option 'number', :aliases => '-n', :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => 'Limit the number of results.'
532
592
  method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
533
- method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
593
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :desc => 'Reverse the order of the sort.'
534
594
  def retweets(user = nil)
535
595
  count = options['number'] || DEFAULT_NUM_RESULTS
536
596
  opts = {}
@@ -550,6 +610,25 @@ module T
550
610
  end
551
611
  map %w[rts] => :retweets
552
612
 
613
+ desc 'retweets_of_me', "Returns the #{DEFAULT_NUM_RESULTS} most recent Tweets of the authenticated user that have been retweeted by others."
614
+ method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
615
+ method_option 'decode_uris', :aliases => '-d', :type => :boolean, :desc => 'Decodes t.co URLs into their original form.'
616
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify user via ID instead of screen name.'
617
+ method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
618
+ method_option 'number', :aliases => '-n', :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => 'Limit the number of results.'
619
+ method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
620
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :desc => 'Reverse the order of the sort.'
621
+ def retweets_of_me(user = nil)
622
+ count = options['number'] || DEFAULT_NUM_RESULTS
623
+ opts = {}
624
+ opts[:include_entities] = !!options['decode_uris']
625
+ tweets = collect_with_count(count) do |count_opts|
626
+ client.retweets_of_me(count_opts.merge(opts))
627
+ end
628
+ print_tweets(tweets)
629
+ end
630
+ map %w[retweetsofme] => :retweets_of_me
631
+
553
632
  desc 'ruler', 'Prints a 140-character ruler'
554
633
  method_option 'indent', :aliases => '-i', :type => :numeric, :default => 0, :desc => 'The number of space to print before the ruler.'
555
634
  def ruler
@@ -558,9 +637,9 @@ module T
558
637
  end
559
638
 
560
639
  desc 'status TWEET_ID', 'Retrieves detailed information about a Tweet.'
561
- method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
562
- method_option 'decode_uris', :aliases => '-d', :type => :boolean, :default => false, :desc => 'Decodes t.co URLs into their original form.'
563
- method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
640
+ method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
641
+ method_option 'decode_uris', :aliases => '-d', :type => :boolean, :desc => 'Decodes t.co URLs into their original form.'
642
+ method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
564
643
  method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
565
644
  def status(status_id) # rubocop:disable CyclomaticComplexity
566
645
  opts = {:include_my_retweet => false}
@@ -590,7 +669,7 @@ module T
590
669
  say [status.id, csv_formatted_time(status), status.user.screen_name, decode_full_text(status, options['decode_uris']), status.retweet_count, status.favorite_count, strip_tags(status.source), location].to_csv
591
670
  elsif options['long']
592
671
  array = [status.id, ls_formatted_time(status), "@#{status.user.screen_name}", decode_full_text(status, options['decode_uris']).gsub(/\n+/, ' '), status.retweet_count, status.favorite_count, strip_tags(status.source), location]
593
- format = options['format'] || status_headings.size.times.map { '%s' }
672
+ format = options['format'] || status_headings.size.times.collect { '%s' }
594
673
  print_table_with_headings([array], status_headings, format)
595
674
  else
596
675
  array = []
@@ -607,15 +686,15 @@ module T
607
686
  end
608
687
 
609
688
  desc 'timeline [USER]', "Returns the #{DEFAULT_NUM_RESULTS} most recent Tweets posted by a user."
610
- method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
611
- method_option 'decode_uris', :aliases => '-d', :type => :boolean, :default => false, :desc => 'Decodes t.co URLs into their original form.'
689
+ method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
690
+ method_option 'decode_uris', :aliases => '-d', :type => :boolean, :desc => 'Decodes t.co URLs into their original form.'
612
691
  method_option 'exclude', :aliases => '-e', :type => :string, :enum => %w[replies retweets], :desc => 'Exclude certain types of Tweets from the results.', :banner => 'TYPE'
613
- method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
614
- method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
692
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify user via ID instead of screen name.'
693
+ method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
615
694
  method_option 'max_id', :aliases => '-m', :type => :numeric, :desc => 'Returns only the results with an ID less than the specified ID.'
616
695
  method_option 'number', :aliases => '-n', :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => 'Limit the number of results.'
617
696
  method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
618
- method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
697
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :desc => 'Reverse the order of the sort.'
619
698
  method_option 'since_id', :aliases => '-s', :type => :numeric, :desc => 'Returns only the results with an ID greater than the specified ID.'
620
699
  def timeline(user = nil)
621
700
  count = options['number'] || DEFAULT_NUM_RESULTS
@@ -641,7 +720,7 @@ module T
641
720
  map %w[tl] => :timeline
642
721
 
643
722
  desc 'trends [WOEID]', 'Returns the top 10 trending topics.'
644
- method_option 'exclude-hashtags', :aliases => '-x', :type => :boolean, :default => false, :desc => 'Remove all hashtags from the trends list.'
723
+ method_option 'exclude-hashtags', :aliases => '-x', :type => :boolean, :desc => 'Remove all hashtags from the trends list.'
645
724
  def trends(woe_id = 1)
646
725
  opts = {}
647
726
  opts.merge!(:exclude => 'hashtags') if options['exclude-hashtags']
@@ -650,12 +729,12 @@ module T
650
729
  end
651
730
 
652
731
  desc 'trend_locations', 'Returns the locations for which Twitter has trending topic information.'
653
- method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
654
- method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
732
+ method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
733
+ method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
655
734
  method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
656
- method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
735
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :desc => 'Reverse the order of the sort.'
657
736
  method_option 'sort', :aliases => '-s', :type => :string, :enum => %w[country name parent type woeid], :default => 'name', :desc => 'Specify the order of the results.', :banner => 'ORDER'
658
- method_option 'unsorted', :aliases => '-u', :type => :boolean, :default => false, :desc => 'Output is not sorted.'
737
+ method_option 'unsorted', :aliases => '-u', :type => :boolean, :desc => 'Output is not sorted.'
659
738
  def trend_locations
660
739
  places = client.trend_locations
661
740
  places = case options['sort']
@@ -678,10 +757,10 @@ module T
678
757
  say [place.woeid, place.parent_id, place.place_type, place.name, place.country].to_csv
679
758
  end
680
759
  elsif options['long']
681
- array = places.map do |place|
760
+ array = places.collect do |place|
682
761
  [place.woeid, place.parent_id, place.place_type, place.name, place.country]
683
762
  end
684
- format = options['format'] || TREND_HEADINGS.size.times.map { '%s' }
763
+ format = options['format'] || TREND_HEADINGS.size.times.collect { '%s' }
685
764
  print_table_with_headings(array, TREND_HEADINGS, format)
686
765
  else
687
766
  print_attribute(places, :name)
@@ -690,14 +769,14 @@ module T
690
769
  map %w[locations trendlocations] => :trend_locations
691
770
 
692
771
  desc 'unfollow USER [USER...]', 'Allows you to stop following users.'
693
- method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify input as Twitter user IDs instead of screen names.'
772
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify input as Twitter user IDs instead of screen names.'
694
773
  def unfollow(user, *users)
695
774
  unfollowed_users, number = fetch_users(users.unshift(user), options) do |users_to_unfollow|
696
775
  client.unfollow(users_to_unfollow)
697
776
  end
698
777
  say "@#{@rcfile.active_profile[0]} is no longer following #{pluralize(number, 'user')}."
699
778
  say
700
- say "Run `#{File.basename($PROGRAM_NAME)} follow #{unfollowed_users.map { |unfollowed_user| "@#{unfollowed_user.screen_name}" }.join(' ')}` to follow again."
779
+ say "Run `#{File.basename($PROGRAM_NAME)} follow #{unfollowed_users.collect { |unfollowed_user| "@#{unfollowed_user.screen_name}" }.join(' ')}` to follow again."
701
780
  end
702
781
 
703
782
  desc 'update [MESSAGE]', 'Post a Tweet.'
@@ -719,18 +798,21 @@ module T
719
798
  map %w[post tweet] => :update
720
799
 
721
800
  desc 'users USER [USER...]', 'Returns a list of users you specify.'
722
- method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
723
- method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify input as Twitter user IDs instead of screen names.'
724
- method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
801
+ method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
802
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify input as Twitter user IDs instead of screen names.'
803
+ method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
725
804
  method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
726
- method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
805
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :desc => 'Reverse the order of the sort.'
727
806
  method_option 'sort', :aliases => '-s', :type => :string, :enum => %w[favorites followers friends listed screen_name since tweets tweeted], :default => 'screen_name', :desc => 'Specify the order of the results.', :banner => 'ORDER'
728
- method_option 'unsorted', :aliases => '-u', :type => :boolean, :default => false, :desc => 'Output is not sorted.'
807
+ method_option 'unsorted', :aliases => '-u', :type => :boolean, :desc => 'Output is not sorted.'
729
808
  def users(user, *users)
730
809
  users.unshift(user)
731
810
  require 't/core_ext/string'
732
- options['id'] ? users.map!(&:to_i) : users.map!(&:strip_ats)
733
- users = client.users(users)
811
+ options['id'] ? users.collect!(&:to_i) : users.collect!(&:strip_ats)
812
+ require 'retryable'
813
+ users = retryable(:tries => 3, :on => Twitter::Error, :sleep => 0) do
814
+ client.users(users)
815
+ end
734
816
  print_users(users)
735
817
  end
736
818
  map %w[stats] => :users
@@ -743,10 +825,10 @@ module T
743
825
  map %w[-v --version] => :version
744
826
 
745
827
  desc 'whois USER', 'Retrieves profile information for the user.'
746
- method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
747
- method_option 'decode_uris', :aliases => '-d', :type => :boolean, :default => false, :desc => 'Decodes t.co URLs into their original form.'
748
- method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
749
- method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
828
+ method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
829
+ method_option 'decode_uris', :aliases => '-d', :type => :boolean, :desc => 'Decodes t.co URLs into their original form.'
830
+ method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify user via ID instead of screen name.'
831
+ method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
750
832
  method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
751
833
  def whois(user) # rubocop:disable CyclomaticComplexity
752
834
  require 't/core_ext/string'
@@ -804,14 +886,14 @@ module T
804
886
 
805
887
  return [] if text !~ at_signs
806
888
 
807
- text.to_s.scan(valid_mentions).map do |before, at, screen_name|
889
+ text.to_s.scan(valid_mentions).collect do |before, at, screen_name|
808
890
  screen_name
809
891
  end
810
892
  end
811
893
 
812
894
  def generate_authorize_uri(consumer, request_token)
813
895
  request = consumer.create_signed_request(:get, consumer.authorize_path, request_token, pin_auth_parameters)
814
- params = request['Authorization'].sub(/^OAuth\s+/, '').split(/,\s+/).map do |param|
896
+ params = request['Authorization'].sub(/^OAuth\s+/, '').split(/,\s+/).collect do |param|
815
897
  key, value = param.split('=')
816
898
  value =~ /"(.*?)"/
817
899
  "#{key}=#{CGI.escape(Regexp.last_match[1])}"
@@ -825,7 +907,7 @@ module T
825
907
 
826
908
  def add_location!(options, opts)
827
909
  if options['location']
828
- lat, lng = options['location'] == 'location' ? [location.lat, location.lng] : options['location'].split(',').map(&:to_f)
910
+ lat, lng = options['location'] == 'location' ? [location.lat, location.lng] : options['location'].split(',').collect(&:to_f)
829
911
  opts.merge!(:lat => lat, :long => lng)
830
912
  end
831
913
  end