t 2.2.1 → 2.3.0

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.
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