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.
- data/.travis.yml +1 -0
- data/lib/t/cli.rb +113 -181
- data/lib/t/core_ext/string.rb +5 -1
- data/lib/t/delete.rb +13 -13
- data/lib/t/list.rb +35 -28
- data/lib/t/printable.rb +82 -0
- data/lib/t/requestable.rb +5 -3
- data/lib/t/search.rb +6 -24
- data/lib/t/set.rb +2 -2
- data/lib/t/version.rb +2 -2
- data/spec/cli_spec.rb +1129 -282
- data/spec/delete_spec.rb +71 -90
- data/spec/fixtures/direct_messages.json +1 -1
- data/spec/fixtures/search.json +1 -1
- data/spec/fixtures/status.json +1 -1
- data/spec/fixtures/statuses.json +1 -1
- data/spec/fixtures/users_list.json +1 -1
- data/spec/helper.rb +3 -1
- data/spec/list_spec.rb +250 -37
- data/spec/search_spec.rb +310 -255
- data/t.gemspec +1 -1
- metadata +12 -3
data/.travis.yml
CHANGED
data/lib/t/cli.rb
CHANGED
@@ -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 '
|
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.
|
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
|
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", "
|
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
|
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", "
|
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.
|
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 :
|
212
|
-
method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by
|
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
|
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 :
|
234
|
-
method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by
|
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
|
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 :
|
256
|
-
method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by
|
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
|
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 :
|
282
|
-
method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by
|
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
|
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.
|
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.
|
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.
|
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
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
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 :
|
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
|
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.
|
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 :
|
458
|
-
method_option :followers, :aliases => "-f", :type => :boolean, :default => false, :desc => "Sort by
|
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
|
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.
|
492
|
+
screen_name = screen_name.strip_ats
|
482
493
|
user = client.user(screen_name, :include_entities => false)
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
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
|