t 0.5.1 → 0.6.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.
@@ -5,3 +5,4 @@ rvm:
5
5
  - 1.9.3
6
6
  - rbx-18mode
7
7
  - rbx-19mode
8
+ - ruby-head
@@ -3,14 +3,17 @@ require 'active_support/core_ext/array/grouping'
3
3
  require 'active_support/core_ext/date/calculations'
4
4
  require 'active_support/core_ext/integer/time'
5
5
  require 'active_support/core_ext/numeric/time'
6
- require 'highline'
6
+ require 'geokit'
7
7
  require 'launchy'
8
8
  require 'oauth'
9
+ require 'open-uri'
9
10
  require 't/collectable'
10
11
  require 't/core_ext/string'
11
12
  require 't/delete'
12
13
  require 't/list'
14
+ require 't/printable'
13
15
  require 't/rcfile'
16
+ require 't/requestable'
14
17
  require 't/search'
15
18
  require 't/set'
16
19
  require 't/version'
@@ -23,10 +26,11 @@ module T
23
26
  class CLI < Thor
24
27
  include ActionView::Helpers::DateHelper
25
28
  include ActionView::Helpers::NumberHelper
29
+ include ActionView::Helpers::TextHelper
26
30
  include T::Collectable
31
+ include T::Printable
32
+ include T::Requestable
27
33
 
28
- DEFAULT_HOST = 'api.twitter.com'
29
- DEFAULT_PROTOCOL = 'https'
30
34
  DEFAULT_NUM_RESULTS = 20
31
35
  MAX_SCREEN_NAME_SIZE = 20
32
36
  MAX_USERS_PER_REQUEST = 100
@@ -95,7 +99,7 @@ module T
95
99
  def block(screen_name, *screen_names)
96
100
  screen_names.unshift(screen_name)
97
101
  screen_names.threaded_each do |screen_name|
98
- screen_name.strip_at
102
+ screen_name.strip_ats
99
103
  retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
100
104
  client.block(screen_name, :include_entities => false)
101
105
  end
@@ -107,8 +111,8 @@ module T
107
111
 
108
112
  desc "direct_messages", "Returns the #{DEFAULT_NUM_RESULTS} most recent Direct Messages sent to you."
109
113
  method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
110
- method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
111
- method_option :reverse, :aliases => "-r", :type => :boolean, :default => false
114
+ method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => "Limit the number of results."
115
+ method_option :reverse, :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
112
116
  def direct_messages
113
117
  count = options['number'] || DEFAULT_NUM_RESULTS
114
118
  direct_messages = client.direct_messages(:count => count, :include_entities => false)
@@ -116,11 +120,11 @@ module T
116
120
  if options['long']
117
121
  array = direct_messages.map do |direct_message|
118
122
  created_at = direct_message.created_at > 6.months.ago ? direct_message.created_at.strftime("%b %e %H:%M") : direct_message.created_at.strftime("%b %e %Y")
119
- [direct_message.id.to_s, created_at, direct_message.sender.screen_name, direct_message.text.gsub(/\n+/, ' ')]
123
+ [number_with_delimiter(direct_message.id), created_at, direct_message.sender.screen_name, direct_message.text.gsub(/\n+/, ' ')]
120
124
  end
121
125
  if STDOUT.tty?
122
- headings = ["ID", "Created at", "Screen name", "Text"]
123
- array.unshift(headings)
126
+ headings = ["ID", "Posted at", "Screen name", "Text"]
127
+ array.unshift(headings) unless direct_messages.empty?
124
128
  end
125
129
  print_table(array)
126
130
  else
@@ -133,8 +137,8 @@ module T
133
137
 
134
138
  desc "direct_messages_sent", "Returns the #{DEFAULT_NUM_RESULTS} most recent Direct Messages sent to you."
135
139
  method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
136
- method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
137
- method_option :reverse, :aliases => "-r", :type => :boolean, :default => false
140
+ method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => "Limit the number of results."
141
+ method_option :reverse, :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
138
142
  def direct_messages_sent
139
143
  count = options['number'] || DEFAULT_NUM_RESULTS
140
144
  direct_messages = client.direct_messages_sent(:count => count, :include_entities => false)
@@ -142,11 +146,11 @@ module T
142
146
  if options['long']
143
147
  array = direct_messages.map do |direct_message|
144
148
  created_at = direct_message.created_at > 6.months.ago ? direct_message.created_at.strftime("%b %e %H:%M") : direct_message.created_at.strftime("%b %e %Y")
145
- [direct_message.id.to_s, created_at, direct_message.recipient.screen_name, direct_message.text.gsub(/\n+/, ' ')]
149
+ [number_with_delimiter(direct_message.id), created_at, direct_message.recipient.screen_name, direct_message.text.gsub(/\n+/, ' ')]
146
150
  end
147
151
  if STDOUT.tty?
148
- headings = ["ID", "Created at", "Screen name", "Text"]
149
- array.unshift(headings)
152
+ headings = ["ID", "Posted at", "Screen name", "Text"]
153
+ array.unshift(headings) unless direct_messages.empty?
150
154
  end
151
155
  print_table(array)
152
156
  else
@@ -159,7 +163,7 @@ module T
159
163
 
160
164
  desc "dm SCREEN_NAME MESSAGE", "Sends that person a Direct Message."
161
165
  def dm(screen_name, message)
162
- screen_name = screen_name.strip_at
166
+ screen_name = screen_name.strip_ats
163
167
  direct_message = client.direct_message_create(screen_name, message, :include_entities => false)
164
168
  say "Direct Message sent from @#{@rcfile.default_profile[0]} to @#{direct_message.recipient.screen_name} (#{time_ago_in_words(direct_message.created_at)} ago)."
165
169
  end
@@ -168,6 +172,7 @@ module T
168
172
  desc "favorite STATUS_ID [STATUS_ID...]", "Marks Tweets as favorites."
169
173
  def favorite(status_id, *status_ids)
170
174
  status_ids.unshift(status_id)
175
+ status_ids.map!(&:strip_commas).map!(&:to_i)
171
176
  favorites = status_ids.threaded_map do |status_id|
172
177
  retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
173
178
  client.favorite(status_id, :include_entities => false)
@@ -183,8 +188,8 @@ module T
183
188
 
184
189
  desc "favorites", "Returns the #{DEFAULT_NUM_RESULTS} most recent Tweets you favorited."
185
190
  method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
186
- method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
187
- method_option :reverse, :aliases => "-r", :type => :boolean, :default => false
191
+ method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => "Limit the number of results."
192
+ method_option :reverse, :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
188
193
  def favorites
189
194
  count = options['number'] || DEFAULT_NUM_RESULTS
190
195
  statuses = client.favorites(:count => count, :include_entities => false)
@@ -208,14 +213,14 @@ module T
208
213
 
209
214
  desc "followings", "Returns a list of the people you follow on Twitter."
210
215
  method_option :created, :aliases => "-c", :type => :boolean, :default => false, :desc => "Sort by the time when Twitter acount was created."
211
- method_option :friends, :aliases => "-d", :type => :boolean, :default => false, :desc => "Sort by total number of friends."
212
- method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by total number of followers."
216
+ method_option :favorites, :aliases => "-v", :type => :boolean, :default => false, :desc => "Sort by number of favorites."
217
+ method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by number of followers."
218
+ method_option :friends, :aliases => "-d", :type => :boolean, :default => false, :desc => "Sort by number of friends."
213
219
  method_option :listed, :aliases => "-i", :type => :boolean, :default => false, :desc => "Sort by number of list memberships."
214
220
  method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
215
221
  method_option :reverse, :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
216
- method_option :tweets, :aliases => "-t", :type => :boolean, :default => false, :desc => "Sort by total number of Tweets."
222
+ method_option :tweets, :aliases => "-t", :type => :boolean, :default => false, :desc => "Sort by number of Tweets."
217
223
  method_option :unsorted, :aliases => "-u", :type => :boolean, :default => false, :desc => "Output is not sorted."
218
- method_option :favorites, :aliases => "-v", :type => :boolean, :default => false, :desc => "Sort by total number of favorites."
219
224
  def followings
220
225
  following_ids = collect_with_cursor do |cursor|
221
226
  client.friend_ids(:cursor => cursor)
@@ -230,14 +235,14 @@ module T
230
235
 
231
236
  desc "followers", "Returns a list of the people who follow you on Twitter."
232
237
  method_option :created, :aliases => "-c", :type => :boolean, :default => false, :desc => "Sort by the time when Twitter acount was created."
233
- method_option :friends, :aliases => "-d", :type => :boolean, :default => false, :desc => "Sort by total number of friends."
234
- method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by total number of followers."
238
+ method_option :favorites, :aliases => "-v", :type => :boolean, :default => false, :desc => "Sort by number of favorites."
239
+ method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by number of followers."
240
+ method_option :friends, :aliases => "-d", :type => :boolean, :default => false, :desc => "Sort by number of friends."
235
241
  method_option :listed, :aliases => "-i", :type => :boolean, :default => false, :desc => "Sort by number of list memberships."
236
242
  method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
237
243
  method_option :reverse, :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
238
- method_option :tweets, :aliases => "-t", :type => :boolean, :default => false, :desc => "Sort by total number of Tweets."
244
+ method_option :tweets, :aliases => "-t", :type => :boolean, :default => false, :desc => "Sort by number of Tweets."
239
245
  method_option :unsorted, :aliases => "-u", :type => :boolean, :default => false, :desc => "Output is not sorted."
240
- method_option :favorites, :aliases => "-v", :type => :boolean, :default => false, :desc => "Sort by total number of favorites."
241
246
  def followers
242
247
  follower_ids = collect_with_cursor do |cursor|
243
248
  client.follower_ids(:cursor => cursor)
@@ -252,14 +257,14 @@ module T
252
257
 
253
258
  desc "friends", "Returns the list of people who you follow and follow you back."
254
259
  method_option :created, :aliases => "-c", :type => :boolean, :default => false, :desc => "Sort by the time when Twitter acount was created."
255
- method_option :friends, :aliases => "-d", :type => :boolean, :default => false, :desc => "Sort by total number of friends."
256
- method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by total number of followers."
260
+ method_option :favorites, :aliases => "-v", :type => :boolean, :default => false, :desc => "Sort by number of favorites."
261
+ method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by number of followers."
262
+ method_option :friends, :aliases => "-d", :type => :boolean, :default => false, :desc => "Sort by number of friends."
257
263
  method_option :listed, :aliases => "-i", :type => :boolean, :default => false, :desc => "Sort by number of list memberships."
258
264
  method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
259
265
  method_option :reverse, :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
260
- method_option :tweets, :aliases => "-t", :type => :boolean, :default => false, :desc => "Sort by total number of Tweets."
266
+ method_option :tweets, :aliases => "-t", :type => :boolean, :default => false, :desc => "Sort by number of Tweets."
261
267
  method_option :unsorted, :aliases => "-u", :type => :boolean, :default => false, :desc => "Output is not sorted."
262
- method_option :favorites, :aliases => "-v", :type => :boolean, :default => false, :desc => "Sort by total number of favorites."
263
268
  def friends
264
269
  following_ids = collect_with_cursor do |cursor|
265
270
  client.friend_ids(:cursor => cursor)
@@ -278,14 +283,14 @@ module T
278
283
 
279
284
  desc "leaders", "Returns the list of people who you follow but don't follow you back."
280
285
  method_option :created, :aliases => "-c", :type => :boolean, :default => false, :desc => "Sort by the time when Twitter acount was created."
281
- method_option :friends, :aliases => "-d", :type => :boolean, :default => false, :desc => "Sort by total number of friends."
282
- method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by total number of followers."
286
+ method_option :favorites, :aliases => "-v", :type => :boolean, :default => false, :desc => "Sort by number of favorites."
287
+ method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by number of followers."
288
+ method_option :friends, :aliases => "-d", :type => :boolean, :default => false, :desc => "Sort by number of friends."
283
289
  method_option :listed, :aliases => "-i", :type => :boolean, :default => false, :desc => "Sort by number of list memberships."
284
290
  method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
285
291
  method_option :reverse, :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
286
- method_option :tweets, :aliases => "-t", :type => :boolean, :default => false, :desc => "Sort by total number of Tweets."
292
+ method_option :tweets, :aliases => "-t", :type => :boolean, :default => false, :desc => "Sort by number of Tweets."
287
293
  method_option :unsorted, :aliases => "-u", :type => :boolean, :default => false, :desc => "Output is not sorted."
288
- method_option :favorites, :aliases => "-v", :type => :boolean, :default => false, :desc => "Sort by total number of favorites."
289
294
  def leaders
290
295
  following_ids = collect_with_cursor do |cursor|
291
296
  client.friend_ids(:cursor => cursor)
@@ -302,30 +307,10 @@ module T
302
307
  print_user_list(users)
303
308
  end
304
309
 
305
- desc "members [SCREEN_NAME] LIST_NAME", "Returns the members of a Twitter list."
306
- method_option :created, :aliases => "-c", :type => :boolean, :default => false, :desc => "Sort by the time when Twitter acount was created."
307
- method_option :friends, :aliases => "-d", :type => :boolean, :default => false, :desc => "Sort by total number of friends."
308
- method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by total number of followers."
309
- method_option :listed, :aliases => "-i", :type => :boolean, :default => false, :desc => "Sort by number of list memberships."
310
- method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
311
- method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
312
- method_option :reverse, :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
313
- method_option :tweets, :aliases => "-t", :type => :boolean, :default => false, :desc => "Sort by total number of Tweets."
314
- method_option :unsorted, :aliases => "-u", :type => :boolean, :default => false, :desc => "Output is not sorted."
315
- method_option :favorites, :aliases => "-v", :type => :boolean, :default => false, :desc => "Sort by total number of favorites."
316
- def members(*args)
317
- list = args.pop
318
- owner = args.pop || @rcfile.default_profile[0]
319
- users = collect_with_cursor do |cursor|
320
- client.list_members(owner, list, :cursor => cursor, :include_entities => false, :skip_status => true)
321
- end
322
- print_user_list(users)
323
- end
324
-
325
310
  desc "mentions", "Returns the #{DEFAULT_NUM_RESULTS} most recent Tweets mentioning you."
326
311
  method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
327
- method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
328
- method_option :reverse, :aliases => "-r", :type => :boolean, :default => false
312
+ method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => "Limit the number of results."
313
+ method_option :reverse, :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
329
314
  def mentions
330
315
  count = options['number'] || DEFAULT_NUM_RESULTS
331
316
  statuses = client.mentions(:count => count, :include_entities => false)
@@ -336,13 +321,14 @@ module T
336
321
  desc "open SCREEN_NAME", "Opens that user's profile in a web browser."
337
322
  method_option :dry_run, :type => :boolean
338
323
  def open(screen_name)
339
- screen_name = screen_name.strip_at
324
+ screen_name = screen_name.strip_ats
340
325
  Launchy.open("https://twitter.com/#{screen_name}", :dry_run => options.fetch('dry_run', false))
341
326
  end
342
327
 
343
328
  desc "reply STATUS_ID MESSAGE", "Post your Tweet as a reply directed at another person."
344
329
  method_option :location, :aliases => "-l", :type => :boolean, :default => false
345
330
  def reply(status_id, message)
331
+ status_id = status_id.strip_commas
346
332
  status = client.status(status_id, :include_entities => false, :include_my_retweet => false, :trim_user => true)
347
333
  opts = {:in_reply_to_status_id => status.id, :include_entities => false, :trim_user => true}
348
334
  opts.merge!(:lat => location.lat, :long => location.lng) if options['location']
@@ -356,7 +342,7 @@ module T
356
342
  def report_spam(screen_name, *screen_names)
357
343
  screen_names.unshift(screen_name)
358
344
  screen_names.threaded_each do |screen_name|
359
- screen_name.strip_at
345
+ screen_name.strip_ats
360
346
  retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
361
347
  client.report_spam(screen_name, :include_entities => false)
362
348
  end
@@ -368,6 +354,7 @@ module T
368
354
  desc "retweet STATUS_ID [STATUS_ID...]", "Sends Tweets to your followers."
369
355
  def retweet(status_id, *status_ids)
370
356
  status_ids.unshift(status_id)
357
+ status_ids.map!(&:strip_commas).map!(&:to_i)
371
358
  retweets = status_ids.threaded_map do |status_id|
372
359
  retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
373
360
  client.retweet(status_id, :include_entities => false, :trim_user => true)
@@ -383,39 +370,52 @@ module T
383
370
 
384
371
  desc "retweets [SCREEN_NAME]", "Returns the #{DEFAULT_NUM_RESULTS} most recent Retweets by a user."
385
372
  method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
386
- method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
387
- method_option :reverse, :aliases => "-r", :type => :boolean, :default => false
373
+ method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => "Limit the number of results."
374
+ method_option :reverse, :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
388
375
  def retweets(screen_name=nil)
389
- screen_name = screen_name.strip_at if screen_name
376
+ screen_name = screen_name.strip_ats if screen_name
390
377
  count = options['number'] || DEFAULT_NUM_RESULTS
391
378
  statuses = client.retweeted_by(screen_name, :count => count, :include_entities => false)
392
379
  print_status_list(statuses)
393
380
  end
394
381
  map %w(rts) => :retweets
395
382
 
396
- desc "status MESSAGE", "Post a Tweet."
397
- method_option :location, :aliases => "-l", :type => :boolean, :default => false
398
- def status(message)
399
- opts = {:include_entities => false, :trim_user => true}
400
- opts.merge!(:lat => location.lat, :long => location.lng) if options['location']
401
- status = client.update(message, opts)
402
- say "Tweet created by @#{@rcfile.default_profile[0]} (#{time_ago_in_words(status.created_at)} ago)."
403
- say
404
- say "Run `#{File.basename($0)} delete status #{status.id}` to delete."
383
+ desc "status STATUS_ID", "Retrieves detailed information about a Tweet."
384
+ def status(status_id)
385
+ status_id = status_id.strip_commas
386
+ status = client.status(status_id, :include_entities => false, :include_my_retweet => false)
387
+ created_at = status.created_at > 6.months.ago ? status.created_at.strftime("%b %e %H:%M") : status.created_at.strftime("%b %e %Y")
388
+ array = []
389
+ array << ["Text", status.text.gsub(/\n+/, ' ')]
390
+ array << ["Screen name", "@#{status.user.screen_name}"]
391
+ array << ["Posted at", created_at]
392
+ unless status.geo.nil?
393
+ location = Geokit::Geocoders::MultiGeocoder.reverse_geocode(status.geo.coordinates)
394
+ if location.city && location.state && location.country
395
+ array << ["Location", [location.city, location.state, location.country].join(", ")]
396
+ elsif location.state && location.country
397
+ array << ["Location", [location.state, location.country].join(", ")]
398
+ elsif location.country
399
+ array << ["Location", [location.country].join(", ")]
400
+ end
401
+ end
402
+ array << ["Retweets", number_with_delimiter(status.retweet_count)] unless status.retweet_count.zero?
403
+ array << ["Source", strip_tags(status.source)]
404
+ array << ["URL", "https://twitter.com/#{status.user.screen_name}/status/#{status.id}"]
405
+ print_table(array)
405
406
  end
406
- map %w(post tweet update) => :status
407
407
 
408
408
  desc "suggest", "This command returns a listing of Twitter users' accounts we think you might enjoy following."
409
409
  method_option :created, :aliases => "-c", :type => :boolean, :default => false, :desc => "Sort by the time when Twitter acount was created."
410
- method_option :friends, :aliases => "-d", :type => :boolean, :default => false, :desc => "Sort by total number of friends."
410
+ method_option :favorites, :aliases => "-v", :type => :boolean, :default => false, :desc => "Sort by number of favorites."
411
+ method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by number of followers."
412
+ method_option :friends, :aliases => "-d", :type => :boolean, :default => false, :desc => "Sort by number of friends."
411
413
  method_option :listed, :aliases => "-i", :type => :boolean, :default => false, :desc => "Sort by number of list memberships."
412
414
  method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
413
- method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
414
- method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by total number of followers."
415
+ method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => "Limit the number of results."
415
416
  method_option :reverse, :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
416
- method_option :tweets, :aliases => "-t", :type => :boolean, :default => false, :desc => "Sort by total number of Tweets."
417
+ method_option :tweets, :aliases => "-t", :type => :boolean, :default => false, :desc => "Sort by number of Tweets."
417
418
  method_option :unsorted, :aliases => "-u", :type => :boolean, :default => false, :desc => "Output is not sorted."
418
- method_option :favorites, :aliases => "-v", :type => :boolean, :default => false, :desc => "Sort by total number of favorites."
419
419
  def suggest
420
420
  limit = options['number'] || DEFAULT_NUM_RESULTS
421
421
  users = client.recommendations(:limit => limit, :include_entities => false)
@@ -424,12 +424,12 @@ module T
424
424
 
425
425
  desc "timeline [SCREEN_NAME]", "Returns the #{DEFAULT_NUM_RESULTS} most recent Tweets posted by a user."
426
426
  method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
427
- method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
428
- method_option :reverse, :aliases => "-r", :type => :boolean, :default => false
427
+ method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => "Limit the number of results."
428
+ method_option :reverse, :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
429
429
  def timeline(screen_name=nil)
430
430
  count = options['number'] || DEFAULT_NUM_RESULTS
431
431
  if screen_name
432
- screen_name = screen_name.strip_at
432
+ screen_name = screen_name.strip_ats
433
433
  statuses = client.user_timeline(screen_name, :count => count, :include_entities => false)
434
434
  else
435
435
  statuses = client.home_timeline(:count => count, :include_entities => false)
@@ -452,17 +452,28 @@ module T
452
452
  say "Run `#{File.basename($0)} follow users #{screen_names.join(' ')}` to follow again."
453
453
  end
454
454
 
455
+ desc "update MESSAGE", "Post a Tweet."
456
+ method_option :location, :aliases => "-l", :type => :boolean, :default => false
457
+ def update(message)
458
+ opts = {:include_entities => false, :trim_user => true}
459
+ opts.merge!(:lat => location.lat, :long => location.lng) if options['location']
460
+ status = client.update(message, opts)
461
+ say "Tweet created by @#{@rcfile.default_profile[0]} (#{time_ago_in_words(status.created_at)} ago)."
462
+ say
463
+ say "Run `#{File.basename($0)} delete status #{status.id}` to delete."
464
+ end
465
+ map %w(post tweet) => :update
466
+
455
467
  desc "users SCREEN_NAME [SCREEN_NAME...]", "Returns a list of users you specify."
456
468
  method_option :created, :aliases => "-c", :type => :boolean, :default => false, :desc => "Sort by the time when Twitter acount was created."
457
- method_option :friends, :aliases => "-d", :type => :boolean, :default => false, :desc => "Sort by total number of friends."
458
- method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by total number of followers."
469
+ method_option :favorites, :aliases => "-v", :type => :boolean, :default => false, :desc => "Sort by number of favorites."
470
+ method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by number of followers."
471
+ method_option :friends, :aliases => "-d", :type => :boolean, :default => false, :desc => "Sort by number of friends."
459
472
  method_option :listed, :aliases => "-i", :type => :boolean, :default => false, :desc => "Sort by number of list memberships."
460
473
  method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
461
- method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
462
474
  method_option :reverse, :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
463
- method_option :tweets, :aliases => "-t", :type => :boolean, :default => false, :desc => "Sort by total number of Tweets."
475
+ method_option :tweets, :aliases => "-t", :type => :boolean, :default => false, :desc => "Sort by number of Tweets."
464
476
  method_option :unsorted, :aliases => "-u", :type => :boolean, :default => false, :desc => "Output is not sorted."
465
- method_option :favorites, :aliases => "-v", :type => :boolean, :default => false, :desc => "Sort by total number of favorites."
466
477
  def users(screen_name, *screen_names)
467
478
  screen_names.unshift(screen_name)
468
479
  users = client.users(screen_names, :include_entities => false)
@@ -478,13 +489,26 @@ module T
478
489
 
479
490
  desc "whois SCREEN_NAME", "Retrieves profile information for the user."
480
491
  def whois(screen_name)
481
- screen_name = screen_name.strip_at
492
+ screen_name = screen_name.strip_ats
482
493
  user = client.user(screen_name, :include_entities => false)
483
- say "id: ##{number_with_delimiter(user.id)}"
484
- say "#{user.name}, since #{user.created_at.strftime("%b %Y")}."
485
- say "bio: #{user.description}"
486
- say "location: #{user.location}"
487
- say "web: #{user.url}"
494
+ array = []
495
+ name_label = user.verified ? "Name (Verified)" : "Name"
496
+ array << ["ID", number_with_delimiter(user.id)]
497
+ array << [name_label, user.name] unless user.name.nil?
498
+ array << ["Bio", user.description.gsub(/\n+/, ' ')] unless user.description.nil?
499
+ array << ["Location", user.location] unless user.location.nil?
500
+ array << ["URL", user.url] unless user.url.nil?
501
+ following = user.following ? "Following" : "Not following"
502
+ array << ["Status", following] unless user.following.nil?
503
+ array << ["Last update", "#{user.status.text.gsub(/\n+/, ' ')} (#{time_ago_in_words(user.status.created_at)} ago)"] unless user.status.nil?
504
+ created_at = user.created_at > 6.months.ago ? user.created_at.strftime("%b %e %H:%M") : user.created_at.strftime("%b %e %Y")
505
+ array << ["Since", created_at]
506
+ array << ["Tweets", number_with_delimiter(user.statuses_count)]
507
+ array << ["Favorites", number_with_delimiter(user.favourites_count)]
508
+ array << ["Listed", number_with_delimiter(user.listed_count)]
509
+ array << ["Following", number_with_delimiter(user.friends_count)]
510
+ array << ["Followers", number_with_delimiter(user.followers_count)]
511
+ print_table(array)
488
512
  end
489
513
 
490
514
  desc "delete SUBCOMMAND ...ARGS", "Delete Tweets, Direct Messages, etc."
@@ -503,22 +527,6 @@ module T
503
527
 
504
528
  private
505
529
 
506
- def base_url
507
- "#{protocol}://#{host}"
508
- end
509
-
510
- def client
511
- return @client if @client
512
- @rcfile.path = options['profile'] if options['profile']
513
- @client = Twitter::Client.new(
514
- :endpoint => base_url,
515
- :consumer_key => @rcfile.default_consumer_key,
516
- :consumer_secret => @rcfile.default_consumer_secret,
517
- :oauth_token => @rcfile.default_token,
518
- :oauth_token_secret => @rcfile.default_secret
519
- )
520
- end
521
-
522
530
  def consumer
523
531
  OAuth::Consumer.new(
524
532
  options['consumer_key'],
@@ -537,14 +545,8 @@ module T
537
545
  "#{base_url}#{request.path}?#{params}"
538
546
  end
539
547
 
540
- def host
541
- options['host'] || DEFAULT_HOST
542
- end
543
-
544
548
  def location
545
549
  return @location if @location
546
- require 'geokit'
547
- require 'open-uri'
548
550
  ip_address = Kernel::open("http://checkip.dyndns.org/") do |body|
549
551
  /(?:\d{1,3}\.){3}\d{1,3}/.match(body.read)[0]
550
552
  end
@@ -555,75 +557,5 @@ module T
555
557
  {:oauth_callback => 'oob'}
556
558
  end
557
559
 
558
- def print_in_columns(array)
559
- cols = HighLine::SystemExtensions.terminal_size[0]
560
- width = (array.map{|el| el.to_s.size}.max || 0) + 2
561
- array.each_with_index do |value, index|
562
- puts if (((index) % (cols / width))).zero? && !index.zero?
563
- printf("%-#{width}s", value)
564
- end
565
- puts
566
- end
567
-
568
- def print_status_list(statuses)
569
- statuses.reverse! if options['reverse']
570
- if options['long']
571
- array = statuses.map do |status|
572
- created_at = status.created_at > 6.months.ago ? status.created_at.strftime("%b %e %H:%M") : status.created_at.strftime("%b %e %Y")
573
- [status.id.to_s, created_at, status.user.screen_name, status.text.gsub(/\n+/, ' ')]
574
- end
575
- if STDOUT.tty?
576
- headings = ["ID", "Created at", "Screen name", "Text"]
577
- array.unshift(headings)
578
- end
579
- print_table(array)
580
- else
581
- statuses.each do |status|
582
- say "#{status.user.screen_name.rjust(MAX_SCREEN_NAME_SIZE)}: #{status.text.gsub(/\n+/, ' ')} (#{time_ago_in_words(status.created_at)} ago)"
583
- end
584
- end
585
- end
586
-
587
- def print_user_list(users)
588
- users = users.sort_by{|user| user.screen_name.downcase} unless options['unsorted']
589
- if options['created']
590
- users = users.sort_by{|user| user.created_at}
591
- elsif options['favorites']
592
- users = users.sort_by{|user| user.favourites_count}
593
- elsif options['followers']
594
- users = users.sort_by{|user| user.followers_count}
595
- elsif options['friends']
596
- users = users.sort_by{|user| user.friends_count}
597
- elsif options['listed']
598
- users = users.sort_by{|user| user.listed_count}
599
- elsif options['tweets']
600
- users = users.sort_by{|user| user.statuses_count}
601
- end
602
- users.reverse! if options['reverse']
603
- if options['long']
604
- array = users.map do |user|
605
- created_at = user.created_at > 6.months.ago ? user.created_at.strftime("%b %e %H:%M") : user.created_at.strftime("%b %e %Y")
606
- [user.id, created_at, user.statuses_count, user.friends_count, user.followers_count, user.favourites_count, user.listed_count, user.screen_name, user.name]
607
- end
608
- if STDOUT.tty?
609
- headings = ["ID", "Created at", "Tweets", "Following", "Followers", "Favorites", "Listed", "Screen name", "Name"]
610
- array.unshift(headings)
611
- end
612
- print_table(array)
613
- else
614
- if STDOUT.tty?
615
- print_in_columns(users.map(&:screen_name))
616
- else
617
- users.map(&:screen_name).each do |user|
618
- say user
619
- end
620
- end
621
- end
622
- end
623
-
624
- def protocol
625
- options['no_ssl'] ? 'http' : DEFAULT_PROTOCOL
626
- end
627
-
628
560
  end
629
561
  end