t 1.7.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/README.md +21 -8
- data/lib/t.rb +1 -1
- data/lib/t/cli.rb +62 -73
- data/lib/t/collectable.rb +2 -10
- data/lib/t/core_ext/kernel.rb +4 -4
- data/lib/t/delete.rb +4 -4
- data/lib/t/editor.rb +35 -0
- data/lib/t/list.rb +3 -6
- data/lib/t/printable.rb +7 -13
- data/lib/t/requestable.rb +6 -21
- data/lib/t/search.rb +16 -17
- data/lib/t/set.rb +4 -4
- data/lib/t/stream.rb +15 -27
- data/lib/t/utils.rb +10 -10
- data/lib/t/version.rb +3 -3
- data/spec/cli_spec.rb +223 -109
- data/spec/delete_spec.rb +26 -26
- data/spec/editor_spec.rb +102 -0
- data/spec/fixtures/bearer_token.json +1 -0
- data/spec/fixtures/status.json +1 -1
- data/spec/fixtures/status_no_attributes.json +1 -1
- data/spec/fixtures/status_no_country.json +1 -1
- data/spec/fixtures/status_no_full_name.json +1 -1
- data/spec/fixtures/status_no_locality.json +1 -1
- data/spec/fixtures/status_no_place.json +1 -1
- data/spec/fixtures/status_no_street_address.json +1 -1
- data/spec/helper.rb +6 -2
- data/spec/list_spec.rb +3 -3
- data/spec/rcfile_spec.rb +20 -6
- data/spec/search_spec.rb +19 -19
- data/spec/set_spec.rb +4 -4
- data/spec/stream_spec.rb +77 -101
- data/t.gemspec +4 -5
- metadata +11 -57
- metadata.gz.sig +0 -0
- data/spec/fixtures/activity_summary.json +0 -1
data.tar.gz.sig
CHANGED
Binary file
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@
|
|
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
|
-
[![Pledgie](
|
9
|
+
[![Pledgie](https://pledgie.com/campaigns/17330.png)][pledgie]
|
10
10
|
[![Flattr](http://api.flattr.com/button/flattr-badge-large.png)][flattr]
|
11
11
|
|
12
12
|
[gem]: https://rubygems.org/gems/t
|
@@ -38,6 +38,16 @@ If the output looks more like this, you need to [install Ruby][ruby]:
|
|
38
38
|
|
39
39
|
ruby: command not found
|
40
40
|
|
41
|
+
**On Linux**, for Debian-based systems, open a terminal and type:
|
42
|
+
|
43
|
+
sudo apt-get install ruby-dev
|
44
|
+
|
45
|
+
or for Red Hat-based distros like Fedora and CentOS, type:
|
46
|
+
|
47
|
+
sudo yum install ruby-devel
|
48
|
+
|
49
|
+
(if necessary, adapt for your package manager)
|
50
|
+
|
41
51
|
**On Windows**, you can install Ruby with [RubyInstaller][].
|
42
52
|
[rubyinstaller]: http://rubyinstaller.org/
|
43
53
|
|
@@ -49,7 +59,7 @@ To ensure the code you're installing hasn't been tampered with, it's
|
|
49
59
|
recommended that you verify the signature. To do this, you need to add my
|
50
60
|
public key as a trusted certificate (you only need to do this once):
|
51
61
|
|
52
|
-
gem cert --add <(curl -Ls https://
|
62
|
+
gem cert --add <(curl -Ls https://raw.github.com/sferik/t/master/certs/sferik.pem)
|
53
63
|
|
54
64
|
Then, install the gem with the high security trust policy:
|
55
65
|
|
@@ -157,7 +167,7 @@ example, send a user a direct message only if he already follows you:
|
|
157
167
|
t leaders | xargs t unfollow
|
158
168
|
|
159
169
|
#### Unfollow 10 people who haven't tweeted in the longest time
|
160
|
-
t followings -l --sort=
|
170
|
+
t followings -l --sort=tweeted | head -10 | awk '{print $1}' | xargs t unfollow -i
|
161
171
|
|
162
172
|
#### Twitter roulette: randomly follow someone who follows you (who you don't already follow)
|
163
173
|
t groupies | shuf | head -1 | xargs t follow
|
@@ -172,7 +182,7 @@ example, send a user a direct message only if he already follows you:
|
|
172
182
|
t stream timeline
|
173
183
|
|
174
184
|
#### Count the number of employees who work for Twitter
|
175
|
-
t list members twitter
|
185
|
+
t list members twitter/team | wc -l
|
176
186
|
|
177
187
|
#### Search Twitter for the 20 most recent Tweets that match a specified query
|
178
188
|
t search all "query"
|
@@ -218,8 +228,12 @@ your Twitter account.
|
|
218
228
|
|
219
229
|
`t` was also mentioned on [an episode of the Ruby 5 podcast][ruby5].
|
220
230
|
|
231
|
+
`t` was also discussed on [an episode of the Ruby Rogues podcast][rubyrogues].
|
232
|
+
|
221
233
|
[ruby5]: http://ruby5.envylabs.com/episodes/273-episode-269-may-4th-2012/stories/2400-t-command-line-power-tool-for-twitter
|
222
234
|
|
235
|
+
[rubyrogues]: http://rubyrogues.com/127-rr-erik-michaels-ober/
|
236
|
+
|
223
237
|
If you discuss `t` in a blog post or podcast, [let me know][email] and I'll
|
224
238
|
link it here.
|
225
239
|
|
@@ -258,8 +272,8 @@ flags.
|
|
258
272
|
Don't run Zsh? Why not [contribute][] completion support for your favorite
|
259
273
|
shell?
|
260
274
|
|
261
|
-
[completion]: etc
|
262
|
-
[contribute]: CONTRIBUTING.md
|
275
|
+
[completion]: https://github.com/sferik/t/tree/master/etc
|
276
|
+
[contribute]: https://github.com/sferik/t/blob/master/CONTRIBUTING.md
|
263
277
|
|
264
278
|
## History
|
265
279
|
The [twitter gem][gem] previously contained a command-line interface, up until
|
@@ -275,7 +289,6 @@ the original code.
|
|
275
289
|
This library aims to support and is [tested against][travis] the following Ruby
|
276
290
|
implementations:
|
277
291
|
|
278
|
-
* Ruby 1.8.7
|
279
292
|
* Ruby 1.9.2
|
280
293
|
* Ruby 1.9.3
|
281
294
|
* Ruby 2.0.0
|
@@ -302,5 +315,5 @@ If you are running t on a remote computer you can use the flag --display-url dur
|
|
302
315
|
Copyright (c) 2011-2013 Erik Michaels-Ober. See [LICENSE][] for details.
|
303
316
|
Application icon by [@nvk][nvk].
|
304
317
|
|
305
|
-
[license]: LICENSE.md
|
318
|
+
[license]: https://github.com/sferik/t/blob/master/LICENSE.md
|
306
319
|
[nvk]: http://rodolfonovak.com
|
data/lib/t.rb
CHANGED
@@ -6,7 +6,7 @@ module T
|
|
6
6
|
|
7
7
|
# Convert time to local time by applying the `utc_offset` setting.
|
8
8
|
def local_time(time)
|
9
|
-
utc_offset ? (time.utc + utc_offset) : time.localtime
|
9
|
+
utc_offset ? (time.dup.utc + utc_offset) : time.localtime
|
10
10
|
end
|
11
11
|
|
12
12
|
# UTC offset in seconds to apply time instances before displaying.
|
data/lib/t/cli.rb
CHANGED
@@ -5,6 +5,7 @@ require 'thor'
|
|
5
5
|
require 'twitter'
|
6
6
|
require 't/collectable'
|
7
7
|
require 't/delete'
|
8
|
+
require 't/editor'
|
8
9
|
require 't/list'
|
9
10
|
require 't/printable'
|
10
11
|
require 't/rcfile'
|
@@ -28,9 +29,7 @@ module T
|
|
28
29
|
|
29
30
|
check_unknown_options!
|
30
31
|
|
31
|
-
class_option "host", :aliases => "-H", :type => :string, :default => T::Requestable::DEFAULT_HOST, :desc => "Twitter API server"
|
32
32
|
class_option "color", :aliases => "-C", :type => :string, :enum => %w(auto never), :default => "auto", :desc => "Control how color is used in output"
|
33
|
-
class_option "no-ssl", :aliases => "-U", :type => :boolean, :default => false, :desc => "Disable SSL"
|
34
33
|
class_option "profile", :aliases => "-P", :type => :string, :default => File.join(File.expand_path("~"), T::RCFile::FILE_NAME), :desc => "Path to RC file", :banner => "FILE"
|
35
34
|
|
36
35
|
def initialize(*)
|
@@ -50,7 +49,7 @@ module T
|
|
50
49
|
end
|
51
50
|
|
52
51
|
desc "authorize", "Allows an application to request user authorization"
|
53
|
-
method_option "display-
|
52
|
+
method_option "display-uri", :aliases => "-d", :type => :boolean, :default => false, :desc => "Display the authorization URL instead of attempting to open it."
|
54
53
|
def authorize
|
55
54
|
@rcfile.path = options['profile'] if options['profile']
|
56
55
|
if @rcfile.empty?
|
@@ -79,12 +78,12 @@ module T
|
|
79
78
|
say
|
80
79
|
end
|
81
80
|
require 'launchy'
|
82
|
-
open_or_print( "https://dev.twitter.com/apps", :dry_run => options['display-
|
81
|
+
open_or_print( "https://dev.twitter.com/apps", :dry_run => options['display-uri'] )
|
83
82
|
key = ask "Enter your consumer key:"
|
84
83
|
secret = ask "Enter your consumer secret:"
|
85
|
-
consumer = OAuth::Consumer.new(key, secret, :site =>
|
84
|
+
consumer = OAuth::Consumer.new(key, secret, :site => Twitter::REST::Client::ENDPOINT)
|
86
85
|
request_token = consumer.get_request_token
|
87
|
-
|
86
|
+
uri = generate_authorize_uri(consumer, request_token)
|
88
87
|
say
|
89
88
|
say "In a moment, you will be directed to the Twitter app authorization page."
|
90
89
|
say "Perform the following steps to complete the authorization process:"
|
@@ -94,7 +93,7 @@ module T
|
|
94
93
|
say
|
95
94
|
ask "Press [Enter] to open the Twitter app authorization page."
|
96
95
|
say
|
97
|
-
open_or_print(
|
96
|
+
open_or_print(uri, :dry_run => options['display-uri'])
|
98
97
|
pin = ask "Enter the supplied PIN:"
|
99
98
|
access_token = request_token.get_access_token(:oauth_verifier => pin.chomp)
|
100
99
|
oauth_response = access_token.get('/1.1/account/verify_credentials.json?include_entities=false&skip_status=true')
|
@@ -137,7 +136,6 @@ module T
|
|
137
136
|
require 'htmlentities'
|
138
137
|
if options['csv']
|
139
138
|
require 'csv'
|
140
|
-
require 'fastercsv' unless Array.new.respond_to?(:to_csv)
|
141
139
|
say DIRECT_MESSAGE_HEADINGS.to_csv unless direct_messages.empty?
|
142
140
|
direct_messages.each do |direct_message|
|
143
141
|
say [direct_message.id, csv_formatted_time(direct_message), direct_message.sender.screen_name, HTMLEntities.new.decode(direct_message.text)].to_csv
|
@@ -170,7 +168,6 @@ module T
|
|
170
168
|
require 'htmlentities'
|
171
169
|
if options['csv']
|
172
170
|
require 'csv'
|
173
|
-
require 'fastercsv' unless Array.new.respond_to?(:to_csv)
|
174
171
|
say DIRECT_MESSAGE_HEADINGS.to_csv unless direct_messages.empty?
|
175
172
|
direct_messages.each do |direct_message|
|
176
173
|
say [direct_message.id, csv_formatted_time(direct_message), direct_message.recipient.screen_name, HTMLEntities.new.decode(direct_message.text)].to_csv
|
@@ -208,18 +205,14 @@ module T
|
|
208
205
|
client.verify_credentials.screen_name
|
209
206
|
end
|
210
207
|
follower_ids = Thread.new do
|
211
|
-
|
212
|
-
client.follower_ids(user, :cursor => cursor)
|
213
|
-
end
|
208
|
+
client.follower_ids(user).to_a
|
214
209
|
end
|
215
210
|
following_ids = Thread.new do
|
216
|
-
|
217
|
-
client.friend_ids(user, :cursor => cursor)
|
218
|
-
end
|
211
|
+
client.friend_ids(user).to_a
|
219
212
|
end
|
220
213
|
disciple_ids = (follower_ids.value - following_ids.value)
|
221
214
|
require 'retryable'
|
222
|
-
users = retryable(:tries => 3, :on => Twitter::Error
|
215
|
+
users = retryable(:tries => 3, :on => Twitter::Error, :sleep => 0) do
|
223
216
|
client.users(disciple_ids)
|
224
217
|
end
|
225
218
|
print_users(users)
|
@@ -295,7 +288,7 @@ module T
|
|
295
288
|
status_ids.unshift(status_id)
|
296
289
|
status_ids.map!(&:to_i)
|
297
290
|
require 'retryable'
|
298
|
-
favorites = retryable(:tries => 3, :on => Twitter::Error
|
291
|
+
favorites = retryable(:tries => 3, :on => Twitter::Error, :sleep => 0) do
|
299
292
|
client.favorite(status_ids)
|
300
293
|
end
|
301
294
|
number = favorites.length
|
@@ -309,9 +302,17 @@ module T
|
|
309
302
|
method_option "csv", :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
|
310
303
|
method_option "id", :aliases => "-i", :type => :boolean, :default => false, :desc => "Specify user via ID instead of screen name."
|
311
304
|
method_option "long", :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
|
305
|
+
method_option "max_id", :aliases => "-m", :type => :numeric, :desc => "Returns only the results with an ID less than the specified ID."
|
312
306
|
method_option "number", :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => "Limit the number of results."
|
313
307
|
method_option "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
|
308
|
+
method_option "since_id", :aliases => "-s", :type => :numeric, :desc => "Returns only the results with an ID greater than the specified ID."
|
314
309
|
def favorites(user=nil)
|
310
|
+
count = options['number'] || DEFAULT_NUM_RESULTS
|
311
|
+
opts = {}
|
312
|
+
opts[:exclude_replies] = true if options['exclude'] == 'replies'
|
313
|
+
opts[:include_rts] = false if options['exclude'] == 'retweets'
|
314
|
+
opts[:max_id] = options['max_id'] if options['max_id']
|
315
|
+
opts[:since_id] = options['since_id'] if options['since_id']
|
315
316
|
if user
|
316
317
|
require 't/core_ext/string'
|
317
318
|
user = if options['id']
|
@@ -320,9 +321,8 @@ module T
|
|
320
321
|
user.strip_ats
|
321
322
|
end
|
322
323
|
end
|
323
|
-
count = options['number'] || DEFAULT_NUM_RESULTS
|
324
324
|
tweets = collect_with_count(count) do |count_opts|
|
325
|
-
client.favorites(user, count_opts)
|
325
|
+
client.favorites(user, count_opts.merge(opts))
|
326
326
|
end
|
327
327
|
print_tweets(tweets)
|
328
328
|
end
|
@@ -355,11 +355,9 @@ module T
|
|
355
355
|
user.strip_ats
|
356
356
|
end
|
357
357
|
end
|
358
|
-
following_ids =
|
359
|
-
client.friend_ids(user, :cursor => cursor)
|
360
|
-
end
|
358
|
+
following_ids = client.friend_ids(user).to_a
|
361
359
|
require 'retryable'
|
362
|
-
users = retryable(:tries => 3, :on => Twitter::Error
|
360
|
+
users = retryable(:tries => 3, :on => Twitter::Error, :sleep => 0) do
|
363
361
|
client.users(following_ids)
|
364
362
|
end
|
365
363
|
print_users(users)
|
@@ -381,11 +379,9 @@ module T
|
|
381
379
|
user.strip_ats
|
382
380
|
end
|
383
381
|
end
|
384
|
-
follower_ids =
|
385
|
-
client.follower_ids(user, :cursor => cursor)
|
386
|
-
end
|
382
|
+
follower_ids = client.follower_ids(user).to_a
|
387
383
|
require 'retryable'
|
388
|
-
users = retryable(:tries => 3, :on => Twitter::Error
|
384
|
+
users = retryable(:tries => 3, :on => Twitter::Error, :sleep => 0) do
|
389
385
|
client.users(follower_ids)
|
390
386
|
end
|
391
387
|
print_users(users)
|
@@ -410,18 +406,14 @@ module T
|
|
410
406
|
client.verify_credentials.screen_name
|
411
407
|
end
|
412
408
|
following_ids = Thread.new do
|
413
|
-
|
414
|
-
client.friend_ids(user, :cursor => cursor)
|
415
|
-
end
|
409
|
+
client.friend_ids(user).to_a
|
416
410
|
end
|
417
411
|
follower_ids = Thread.new do
|
418
|
-
|
419
|
-
client.follower_ids(user, :cursor => cursor)
|
420
|
-
end
|
412
|
+
client.follower_ids(user).to_a
|
421
413
|
end
|
422
414
|
friend_ids = (following_ids.value & follower_ids.value)
|
423
415
|
require 'retryable'
|
424
|
-
users = retryable(:tries => 3, :on => Twitter::Error
|
416
|
+
users = retryable(:tries => 3, :on => Twitter::Error, :sleep => 0) do
|
425
417
|
client.users(friend_ids)
|
426
418
|
end
|
427
419
|
print_users(users)
|
@@ -446,18 +438,14 @@ module T
|
|
446
438
|
client.verify_credentials.screen_name
|
447
439
|
end
|
448
440
|
following_ids = Thread.new do
|
449
|
-
|
450
|
-
client.friend_ids(user, :cursor => cursor)
|
451
|
-
end
|
441
|
+
client.friend_ids(user).to_a
|
452
442
|
end
|
453
443
|
follower_ids = Thread.new do
|
454
|
-
|
455
|
-
client.follower_ids(user, :cursor => cursor)
|
456
|
-
end
|
444
|
+
client.follower_ids(user).to_a
|
457
445
|
end
|
458
446
|
leader_ids = (following_ids.value - follower_ids.value)
|
459
447
|
require 'retryable'
|
460
|
-
users = retryable(:tries => 3, :on => Twitter::Error
|
448
|
+
users = retryable(:tries => 3, :on => Twitter::Error, :sleep => 0) do
|
461
449
|
client.users(leader_ids)
|
462
450
|
end
|
463
451
|
print_users(users)
|
@@ -503,29 +491,29 @@ module T
|
|
503
491
|
map %w(replies) => :mentions
|
504
492
|
|
505
493
|
desc "open USER", "Opens that user's profile in a web browser."
|
506
|
-
method_option "display-
|
494
|
+
method_option "display-uri", :aliases => "-d", :type => :boolean, :default => false, :desc => "Display the requested URL instead of attempting to open it."
|
507
495
|
method_option "id", :aliases => "-i", :type => :boolean, :default => false, :desc => "Specify user via ID instead of screen name."
|
508
496
|
method_option "status", :aliases => "-s", :type => :boolean, :default => false, :desc => "Specify input as a Twitter status ID instead of a screen name."
|
509
497
|
def open(user)
|
510
498
|
require 'launchy'
|
511
499
|
if options['id']
|
512
500
|
user = client.user(user.to_i)
|
513
|
-
open_or_print(
|
501
|
+
open_or_print(user.website, :dry_run => options['display-uri'])
|
514
502
|
elsif options['status']
|
515
503
|
status = client.status(user.to_i, :include_my_retweet => false)
|
516
|
-
open_or_print(
|
504
|
+
open_or_print(status.uri, :dry_run => options['display-uri'])
|
517
505
|
else
|
518
506
|
require 't/core_ext/string'
|
519
|
-
open_or_print("https://twitter.com/#{user.strip_ats}", :dry_run => options['display-
|
507
|
+
open_or_print("https://twitter.com/#{user.strip_ats}", :dry_run => options['display-uri'])
|
520
508
|
end
|
521
509
|
end
|
522
510
|
|
523
511
|
desc "reply TWEET_ID MESSAGE", "Post your Tweet as a reply directed at another person."
|
524
512
|
method_option "all", :aliases => "-a", :type => :boolean, :default => false, :desc => "Reply to all users mentioned in the Tweet."
|
525
|
-
method_option "location", :aliases => "-l", :type => :
|
513
|
+
method_option "location", :aliases => "-l", :type => :string, :default => "location", :desc => "Add location information. If the optional 'latitude,longitude' parameter is not supplied, looks up location by IP address."
|
526
514
|
def reply(status_id, message)
|
527
515
|
status = client.status(status_id.to_i, :include_my_retweet => false)
|
528
|
-
users = Array(status.
|
516
|
+
users = Array(status.user.screen_name)
|
529
517
|
if options['all']
|
530
518
|
users += extract_mentioned_screen_names(status.full_text)
|
531
519
|
users.uniq!
|
@@ -533,7 +521,7 @@ module T
|
|
533
521
|
require 't/core_ext/string'
|
534
522
|
users.map!(&:prepend_at)
|
535
523
|
opts = {:in_reply_to_status_id => status.id, :trim_user => true}
|
536
|
-
|
524
|
+
add_location!(options, opts)
|
537
525
|
reply = client.update("#{users.join(' ')} #{message}", opts)
|
538
526
|
say "Reply posted by @#{@rcfile.active_profile[0]} to #{users.join(' ')}."
|
539
527
|
say
|
@@ -555,7 +543,7 @@ module T
|
|
555
543
|
status_ids.unshift(status_id)
|
556
544
|
status_ids.map!(&:to_i)
|
557
545
|
require 'retryable'
|
558
|
-
retweets = retryable(:tries => 3, :on => Twitter::Error
|
546
|
+
retweets = retryable(:tries => 3, :on => Twitter::Error, :sleep => 0) do
|
559
547
|
client.retweet(status_ids, :trim_user => true)
|
560
548
|
end
|
561
549
|
number = retweets.length
|
@@ -595,7 +583,8 @@ module T
|
|
595
583
|
desc "ruler", "Prints a 140-character ruler"
|
596
584
|
method_option "indent", :aliases => "-i", :type => :numeric, :default => 0, :desc => "The number of space to print before the ruler."
|
597
585
|
def ruler
|
598
|
-
|
586
|
+
markings = '----|'.chars.cycle.take(140).join
|
587
|
+
say "#{' ' * options['indent'].to_i}#{markings}"
|
599
588
|
end
|
600
589
|
|
601
590
|
desc "status TWEET_ID", "Retrieves detailed information about a Tweet."
|
@@ -603,8 +592,7 @@ module T
|
|
603
592
|
method_option "long", :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
|
604
593
|
def status(status_id)
|
605
594
|
status = client.status(status_id.to_i, :include_my_retweet => false)
|
606
|
-
|
607
|
-
location = if status.place
|
595
|
+
location = if status.place?
|
608
596
|
if status.place.name && status.place.attributes && status.place.attributes[:street_address] && status.place.attributes[:locality] && status.place.attributes[:region] && status.place.country
|
609
597
|
[status.place.name, status.place.attributes[:street_address], status.place.attributes[:locality], status.place.attributes[:region], status.place.country].join(", ")
|
610
598
|
elsif status.place.name && status.place.attributes && status.place.attributes[:locality] && status.place.attributes[:region] && status.place.country
|
@@ -618,28 +606,26 @@ module T
|
|
618
606
|
else
|
619
607
|
status.place.name
|
620
608
|
end
|
621
|
-
elsif status.geo
|
609
|
+
elsif status.geo?
|
622
610
|
reverse_geocode(status.geo)
|
623
611
|
end
|
624
|
-
status_headings = ["ID", "Posted at", "Screen name", "Text", "Retweets", "Favorites", "
|
612
|
+
status_headings = ["ID", "Posted at", "Screen name", "Text", "Retweets", "Favorites", "Source", "Location"]
|
625
613
|
if options['csv']
|
626
614
|
require 'csv'
|
627
|
-
require 'fastercsv' unless Array.new.respond_to?(:to_csv)
|
628
615
|
say status_headings.to_csv
|
629
|
-
say [status.id, csv_formatted_time(status), status.
|
616
|
+
say [status.id, csv_formatted_time(status), status.user.screen_name, decode_full_text(status), status.retweet_count, status.favorite_count, strip_tags(status.source), location].to_csv
|
630
617
|
elsif options['long']
|
631
|
-
array = [status.id, ls_formatted_time(status), "@#{status.
|
618
|
+
array = [status.id, ls_formatted_time(status), "@#{status.user.screen_name}", decode_full_text(status).gsub(/\n+/, ' '), status.retweet_count, status.favorite_count, strip_tags(status.source), location]
|
632
619
|
format = options['format'] || status_headings.size.times.map{"%s"}
|
633
620
|
print_table_with_headings([array], status_headings, format)
|
634
621
|
else
|
635
622
|
array = []
|
636
623
|
array << ["ID", status.id.to_s]
|
637
624
|
array << ["Text", decode_full_text(status).gsub(/\n+/, ' ')]
|
638
|
-
array << ["Screen name", "@#{status.
|
625
|
+
array << ["Screen name", "@#{status.user.screen_name}"]
|
639
626
|
array << ["Posted at", "#{ls_formatted_time(status)} (#{time_ago_in_words(status.created_at)} ago)"]
|
640
627
|
array << ["Retweets", number_with_delimiter(status.retweet_count)]
|
641
|
-
array << ["Favorites", number_with_delimiter(
|
642
|
-
array << ["Replies", number_with_delimiter(status_activity.repliers_count)]
|
628
|
+
array << ["Favorites", number_with_delimiter(status.favorite_count)]
|
643
629
|
array << ["Source", strip_tags(status.source)]
|
644
630
|
array << ["Location", location] unless location.nil?
|
645
631
|
print_table(array)
|
@@ -713,7 +699,6 @@ module T
|
|
713
699
|
places.reverse! if options['reverse']
|
714
700
|
if options['csv']
|
715
701
|
require 'csv'
|
716
|
-
require 'fastercsv' unless Array.new.respond_to?(:to_csv)
|
717
702
|
say TREND_HEADINGS.to_csv unless places.empty?
|
718
703
|
places.each do |place|
|
719
704
|
say [place.woeid, place.parent_id, place.place_type, place.name, place.country].to_csv
|
@@ -741,12 +726,13 @@ module T
|
|
741
726
|
say "Run `#{File.basename($0)} follow #{users.map{|user| "@#{user.screen_name}"}.join(' ')}` to follow again."
|
742
727
|
end
|
743
728
|
|
744
|
-
desc "update MESSAGE", "Post a Tweet."
|
745
|
-
method_option "location", :aliases => "-l", :type => :
|
729
|
+
desc "update [MESSAGE]", "Post a Tweet."
|
730
|
+
method_option "location", :aliases => "-l", :type => :string, :default => "location", :desc => "Add location information. If the optional 'latitude,longitude' parameter is not supplied, looks up location by IP address."
|
746
731
|
method_option "file", :aliases => "-f", :type => :string, :desc => "The path to an image to attach to your tweet."
|
747
|
-
def update(message)
|
732
|
+
def update(message=nil)
|
733
|
+
message = T::Editor.gets if message.nil? || message.empty?
|
748
734
|
opts = {:trim_user => true}
|
749
|
-
|
735
|
+
add_location!(options, opts)
|
750
736
|
status = if options['file']
|
751
737
|
client.update_with_media(message, File.new(File.expand_path(options['file'])), opts)
|
752
738
|
else
|
@@ -808,13 +794,13 @@ module T
|
|
808
794
|
array << ["Screen name", "@#{user.screen_name}"]
|
809
795
|
array << [user.verified ? "Name (Verified)" : "Name", user.name] unless user.name.nil?
|
810
796
|
array << ["Tweets", number_with_delimiter(user.statuses_count)]
|
811
|
-
array << ["Favorites", number_with_delimiter(user.
|
797
|
+
array << ["Favorites", number_with_delimiter(user.favorites_count)]
|
812
798
|
array << ["Listed", number_with_delimiter(user.listed_count)]
|
813
799
|
array << ["Following", number_with_delimiter(user.friends_count)]
|
814
800
|
array << ["Followers", number_with_delimiter(user.followers_count)]
|
815
801
|
array << ["Bio", user.description.gsub(/\n+/, ' ')] unless user.description.nil?
|
816
802
|
array << ["Location", user.location] unless user.location.nil?
|
817
|
-
array << ["URL", user.
|
803
|
+
array << ["URL", user.website] unless user.website.nil?
|
818
804
|
print_table(array)
|
819
805
|
end
|
820
806
|
end
|
@@ -853,24 +839,27 @@ module T
|
|
853
839
|
end
|
854
840
|
end
|
855
841
|
|
856
|
-
def
|
857
|
-
"#{protocol}://#{host}"
|
858
|
-
end
|
859
|
-
|
860
|
-
def generate_authorize_url(consumer, request_token)
|
842
|
+
def generate_authorize_uri(consumer, request_token)
|
861
843
|
request = consumer.create_signed_request(:get, consumer.authorize_path, request_token, pin_auth_parameters)
|
862
844
|
params = request['Authorization'].sub(/^OAuth\s+/, '').split(/,\s+/).map do |param|
|
863
845
|
key, value = param.split('=')
|
864
846
|
value =~ /"(.*?)"/
|
865
847
|
"#{key}=#{CGI::escape($1)}"
|
866
848
|
end.join('&')
|
867
|
-
"#{
|
849
|
+
"#{Twitter::REST::Client::ENDPOINT}#{request.path}?#{params}"
|
868
850
|
end
|
869
851
|
|
870
852
|
def pin_auth_parameters
|
871
853
|
{:oauth_callback => 'oob'}
|
872
854
|
end
|
873
855
|
|
856
|
+
def add_location!(options, opts)
|
857
|
+
if options['location']
|
858
|
+
lat, lng = options['location'] == 'location' ? [location.lat, location.lng] : options['location'].split(',').map(&:to_f)
|
859
|
+
opts.merge!(:lat => lat, :long => lng)
|
860
|
+
end
|
861
|
+
end
|
862
|
+
|
874
863
|
def location
|
875
864
|
return @location if @location
|
876
865
|
require 'geokit'
|