t 2.3.0 → 2.4.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.tar.gz.sig +0 -0
- data/README.md +3 -3
- data/Rakefile +1 -1
- data/lib/t/cli.rb +16 -6
- data/lib/t/delete.rb +5 -5
- data/lib/t/list.rb +22 -22
- data/lib/t/printable.rb +1 -1
- data/lib/t/search.rb +3 -3
- data/lib/t/stream.rb +52 -12
- data/lib/t/utils.rb +5 -5
- data/lib/t/version.rb +1 -1
- data/spec/cli_spec.rb +59 -7
- data/spec/delete_spec.rb +2 -2
- data/spec/helper.rb +1 -1
- data/spec/list_spec.rb +7 -7
- data/spec/rcfile_spec.rb +1 -1
- data/spec/search_spec.rb +7 -7
- data/spec/set_spec.rb +2 -2
- data/spec/stream_spec.rb +127 -132
- data/spec/utils_spec.rb +1 -1
- data/t.gemspec +1 -1
- metadata +27 -9
- metadata.gz.sig +0 -0
- checksums.yaml +0 -7
- checksums.yaml.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/README.md
CHANGED
@@ -253,12 +253,12 @@ used by `t`:
|
|
253
253
|

|
254
254
|
|
255
255
|
## Shell completion
|
256
|
-
If you're running Zsh, you can source one of the [bundled completion
|
256
|
+
If you're running Zsh or Bash, you can source one of the [bundled completion
|
257
257
|
files][completion] to get shell completion for `t` commands, subcommands, and
|
258
258
|
flags.
|
259
259
|
|
260
|
-
Don't run Zsh? Why not [contribute][] completion support for your
|
261
|
-
shell?
|
260
|
+
Don't run Zsh or Bash? Why not [contribute][] completion support for your
|
261
|
+
favorite shell?
|
262
262
|
|
263
263
|
[completion]: https://github.com/sferik/t/tree/master/etc
|
264
264
|
[contribute]: https://github.com/sferik/t/blob/master/CONTRIBUTING.md
|
data/Rakefile
CHANGED
data/lib/t/cli.rb
CHANGED
@@ -204,18 +204,18 @@ module T
|
|
204
204
|
|
205
205
|
desc 'does_contain [USER/]LIST USER', 'Find out whether a list contains a user.'
|
206
206
|
method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify user via ID instead of screen name.'
|
207
|
-
def does_contain(
|
208
|
-
owner,
|
207
|
+
def does_contain(user_list, user = nil)
|
208
|
+
owner, list_name = extract_owner(user_list, options)
|
209
209
|
if user.nil?
|
210
210
|
user = @rcfile.active_profile[0]
|
211
211
|
else
|
212
212
|
require 't/core_ext/string'
|
213
213
|
user = options['id'] ? client.user(user.to_i).screen_name : user.strip_ats
|
214
214
|
end
|
215
|
-
if client.list_member?(owner,
|
216
|
-
say "Yes, #{
|
215
|
+
if client.list_member?(owner, list_name, user)
|
216
|
+
say "Yes, #{list_name} contains @#{user}."
|
217
217
|
else
|
218
|
-
abort "No, #{
|
218
|
+
abort "No, #{list_name} does not contain @#{user}."
|
219
219
|
end
|
220
220
|
end
|
221
221
|
map %w[dc doescontain] => :does_contain
|
@@ -844,7 +844,7 @@ module T
|
|
844
844
|
array << ['Since', "#{ls_formatted_time(user, :created_at, false)} (#{time_ago_in_words(user.created_at)} ago)"]
|
845
845
|
array << ['Last update', "#{decode_full_text(user.status, options['decode_uris']).gsub(/\n+/, ' ')} (#{time_ago_in_words(user.status.created_at)} ago)"] unless user.status.nil?
|
846
846
|
array << ['Screen name', "@#{user.screen_name}"]
|
847
|
-
array << [user.verified ? 'Name (Verified)' : 'Name', user.name] unless user.name.nil?
|
847
|
+
array << [user.verified ? 'Name (Verified)' : 'Name', user.name] unless user.name.nil? # rubocop:disable BlockNesting
|
848
848
|
array << ['Tweets', number_with_delimiter(user.statuses_count)]
|
849
849
|
array << ['Favorites', number_with_delimiter(user.favorites_count)]
|
850
850
|
array << ['Listed', number_with_delimiter(user.listed_count)]
|
@@ -858,6 +858,16 @@ module T
|
|
858
858
|
end
|
859
859
|
map %w[user] => :whois
|
860
860
|
|
861
|
+
desc 'whoami', 'Retrieves profile information for the authenticated user.'
|
862
|
+
method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
|
863
|
+
method_option 'decode_uris', :aliases => '-d', :type => :boolean, :desc => 'Decodes t.co URLs into their original form.'
|
864
|
+
method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
|
865
|
+
method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
|
866
|
+
def whoami
|
867
|
+
user = @rcfile.active_profile[0]
|
868
|
+
whois(user)
|
869
|
+
end
|
870
|
+
|
861
871
|
desc 'delete SUBCOMMAND ...ARGS', 'Delete Tweets, Direct Messages, etc.'
|
862
872
|
subcommand 'delete', T::Delete
|
863
873
|
|
data/lib/t/delete.rb
CHANGED
@@ -18,7 +18,7 @@ module T
|
|
18
18
|
|
19
19
|
desc 'block USER [USER...]', 'Unblock users.'
|
20
20
|
method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify input as Twitter user IDs instead of screen names.'
|
21
|
-
method_option 'force', :aliases => '-f', :type => :boolean
|
21
|
+
method_option 'force', :aliases => '-f', :type => :boolean
|
22
22
|
def block(user, *users)
|
23
23
|
unblocked_users, number = fetch_users(users.unshift(user), options) do |users_to_unblock|
|
24
24
|
client.unblock(users_to_unblock)
|
@@ -29,7 +29,7 @@ module T
|
|
29
29
|
end
|
30
30
|
|
31
31
|
desc 'dm [DIRECT_MESSAGE_ID] [DIRECT_MESSAGE_ID...]', 'Delete the last Direct Message sent.'
|
32
|
-
method_option 'force', :aliases => '-f', :type => :boolean
|
32
|
+
method_option 'force', :aliases => '-f', :type => :boolean
|
33
33
|
def dm(direct_message_id, *direct_message_ids)
|
34
34
|
direct_message_ids.unshift(direct_message_id)
|
35
35
|
require 't/core_ext/string'
|
@@ -51,7 +51,7 @@ module T
|
|
51
51
|
map %w[d m] => :dm
|
52
52
|
|
53
53
|
desc 'favorite TWEET_ID [TWEET_ID...]', 'Delete favorites.'
|
54
|
-
method_option 'force', :aliases => '-f', :type => :boolean
|
54
|
+
method_option 'force', :aliases => '-f', :type => :boolean
|
55
55
|
def favorite(status_id, *status_ids)
|
56
56
|
status_ids.unshift(status_id)
|
57
57
|
require 't/core_ext/string'
|
@@ -73,7 +73,7 @@ module T
|
|
73
73
|
map %w[fave favourite] => :favorite
|
74
74
|
|
75
75
|
desc 'list LIST', 'Delete a list.'
|
76
|
-
method_option 'force', :aliases => '-f', :type => :boolean
|
76
|
+
method_option 'force', :aliases => '-f', :type => :boolean
|
77
77
|
method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify list via ID instead of slug.'
|
78
78
|
def list(list)
|
79
79
|
if options['id']
|
@@ -89,7 +89,7 @@ module T
|
|
89
89
|
end
|
90
90
|
|
91
91
|
desc 'status TWEET_ID [TWEET_ID...]', 'Delete Tweets.'
|
92
|
-
method_option 'force', :aliases => '-f', :type => :boolean
|
92
|
+
method_option 'force', :aliases => '-f', :type => :boolean
|
93
93
|
def status(status_id, *status_ids)
|
94
94
|
status_ids.unshift(status_id)
|
95
95
|
require 't/core_ext/string'
|
data/lib/t/list.rb
CHANGED
@@ -26,34 +26,34 @@ module T
|
|
26
26
|
|
27
27
|
desc 'add LIST USER [USER...]', 'Add members to a list.'
|
28
28
|
method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify input as Twitter user IDs instead of screen names.'
|
29
|
-
def add(
|
29
|
+
def add(list_name, user, *users)
|
30
30
|
added_users, number = fetch_users(users.unshift(user), options) do |users_to_add|
|
31
|
-
client.add_list_members(
|
31
|
+
client.add_list_members(list_name, users_to_add)
|
32
32
|
users_to_add
|
33
33
|
end
|
34
|
-
say "@#{@rcfile.active_profile[0]} added #{pluralize(number, 'member')} to the list \"#{
|
34
|
+
say "@#{@rcfile.active_profile[0]} added #{pluralize(number, 'member')} to the list \"#{list_name}\"."
|
35
35
|
say
|
36
36
|
if options['id']
|
37
|
-
say "Run `#{File.basename($PROGRAM_NAME)} list remove --id #{
|
37
|
+
say "Run `#{File.basename($PROGRAM_NAME)} list remove --id #{list_name} #{added_users.join(' ')}` to undo."
|
38
38
|
else
|
39
|
-
say "Run `#{File.basename($PROGRAM_NAME)} list remove #{
|
39
|
+
say "Run `#{File.basename($PROGRAM_NAME)} list remove #{list_name} #{added_users.collect { |added_user| "@#{added_user}" }.join(' ')}` to undo."
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
43
|
desc 'create LIST [DESCRIPTION]', 'Create a new list.'
|
44
44
|
method_option 'private', :aliases => '-p', :type => :boolean
|
45
|
-
def create(
|
45
|
+
def create(list_name, description = nil)
|
46
46
|
opts = description ? {:description => description} : {}
|
47
47
|
opts.merge!(:mode => 'private') if options['private']
|
48
|
-
client.create_list(
|
49
|
-
say "@#{@rcfile.active_profile[0]} created the list \"#{
|
48
|
+
client.create_list(list_name, opts)
|
49
|
+
say "@#{@rcfile.active_profile[0]} created the list \"#{list_name}\"."
|
50
50
|
end
|
51
51
|
|
52
52
|
desc 'information [USER/]LIST', 'Retrieves detailed information about a Twitter list.'
|
53
53
|
method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
|
54
|
-
def information(
|
55
|
-
owner,
|
56
|
-
list = client.list(owner,
|
54
|
+
def information(user_list)
|
55
|
+
owner, list_name = extract_owner(user_list, options)
|
56
|
+
list = client.list(owner, list_name)
|
57
57
|
if options['csv']
|
58
58
|
require 'csv'
|
59
59
|
say ['ID', 'Description', 'Slug', 'Screen name', 'Created at', 'Members', 'Subscribers', 'Following', 'Mode', 'URL'].to_csv
|
@@ -82,25 +82,25 @@ module T
|
|
82
82
|
method_option 'reverse', :aliases => '-r', :type => :boolean, :desc => 'Reverse the order of the sort.'
|
83
83
|
method_option 'sort', :aliases => '-s', :type => :string, :enum => %w[favorites followers friends listed screen_name since tweets tweeted], :default => 'screen_name', :desc => 'Specify the order of the results.', :banner => 'ORDER'
|
84
84
|
method_option 'unsorted', :aliases => '-u', :type => :boolean, :desc => 'Output is not sorted.'
|
85
|
-
def members(
|
86
|
-
owner,
|
87
|
-
users = client.list_members(owner,
|
85
|
+
def members(user_list)
|
86
|
+
owner, list_name = extract_owner(user_list, options)
|
87
|
+
users = client.list_members(owner, list_name).to_a
|
88
88
|
print_users(users)
|
89
89
|
end
|
90
90
|
|
91
91
|
desc 'remove LIST USER [USER...]', 'Remove members from a list.'
|
92
92
|
method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify input as Twitter user IDs instead of screen names.'
|
93
|
-
def remove(
|
93
|
+
def remove(list_name, user, *users)
|
94
94
|
removed_users, number = fetch_users(users.unshift(user), options) do |users_to_remove|
|
95
|
-
client.remove_list_members(
|
95
|
+
client.remove_list_members(list_name, users_to_remove)
|
96
96
|
users_to_remove
|
97
97
|
end
|
98
|
-
say "@#{@rcfile.active_profile[0]} removed #{pluralize(number, 'member')} from the list \"#{
|
98
|
+
say "@#{@rcfile.active_profile[0]} removed #{pluralize(number, 'member')} from the list \"#{list_name}\"."
|
99
99
|
say
|
100
100
|
if options['id']
|
101
|
-
say "Run `#{File.basename($PROGRAM_NAME)} list add --id #{
|
101
|
+
say "Run `#{File.basename($PROGRAM_NAME)} list add --id #{list_name} #{removed_users.join(' ')}` to undo."
|
102
102
|
else
|
103
|
-
say "Run `#{File.basename($PROGRAM_NAME)} list add #{
|
103
|
+
say "Run `#{File.basename($PROGRAM_NAME)} list add #{list_name} #{removed_users.collect { |removed_user| "@#{removed_user}" }.join(' ')}` to undo."
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
@@ -112,13 +112,13 @@ module T
|
|
112
112
|
method_option 'number', :aliases => '-n', :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => 'Limit the number of results.'
|
113
113
|
method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
|
114
114
|
method_option 'reverse', :aliases => '-r', :type => :boolean, :desc => 'Reverse the order of the sort.'
|
115
|
-
def timeline(
|
116
|
-
owner,
|
115
|
+
def timeline(user_list)
|
116
|
+
owner, list_name = extract_owner(user_list, options)
|
117
117
|
count = options['number'] || DEFAULT_NUM_RESULTS
|
118
118
|
opts = {}
|
119
119
|
opts[:include_entities] = !!options['decode_uris']
|
120
120
|
tweets = collect_with_count(count) do |count_opts|
|
121
|
-
client.list_timeline(owner,
|
121
|
+
client.list_timeline(owner, list_name, count_opts.merge(opts))
|
122
122
|
end
|
123
123
|
print_tweets(tweets)
|
124
124
|
end
|
data/lib/t/printable.rb
CHANGED
@@ -157,7 +157,7 @@ module T
|
|
157
157
|
when 'tweets'
|
158
158
|
users.sort_by { |user| user.statuses_count.to_i }
|
159
159
|
when 'tweeted'
|
160
|
-
users.sort_by { |user| user.status? ? user.status.created_at : Time.at(0) }
|
160
|
+
users.sort_by { |user| user.status? ? user.status.created_at : Time.at(0) } # rubocop:disable BlockNesting
|
161
161
|
else
|
162
162
|
users.sort_by { |user| user.screen_name.downcase }
|
163
163
|
end unless options['unsorted']
|
data/lib/t/search.rb
CHANGED
@@ -93,13 +93,13 @@ module T
|
|
93
93
|
method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify user via ID instead of screen name.'
|
94
94
|
method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
|
95
95
|
method_option 'relative_dates', :aliases => '-a', :type => :boolean, :desc => 'Show relative dates.'
|
96
|
-
def list(
|
97
|
-
owner,
|
96
|
+
def list(user_list, query)
|
97
|
+
owner, list_name = extract_owner(user_list, options)
|
98
98
|
opts = {:count => MAX_NUM_RESULTS}
|
99
99
|
opts[:include_entities] = !!options['decode_uris']
|
100
100
|
tweets = collect_with_max_id do |max_id|
|
101
101
|
opts[:max_id] = max_id unless max_id.nil?
|
102
|
-
client.list_timeline(owner,
|
102
|
+
client.list_timeline(owner, list_name, opts)
|
103
103
|
end
|
104
104
|
tweets = tweets.select do |tweet|
|
105
105
|
/#{query}/i.match(tweet.full_text)
|
data/lib/t/stream.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
require 'thor'
|
2
2
|
require 't/printable'
|
3
3
|
require 't/rcfile'
|
4
|
+
require 't/requestable'
|
5
|
+
require 't/utils'
|
4
6
|
|
5
7
|
module T
|
6
8
|
class Stream < Thor
|
7
9
|
include T::Printable
|
10
|
+
include T::Requestable
|
8
11
|
include T::Utils
|
9
12
|
|
10
13
|
TWEET_HEADINGS_FORMATTING = [
|
@@ -23,9 +26,10 @@ module T
|
|
23
26
|
|
24
27
|
desc 'all', 'Stream a random sample of all Tweets (Control-C to stop)'
|
25
28
|
method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
|
29
|
+
method_option 'decode_uris', :aliases => '-d', :type => :boolean, :desc => 'Decodes t.co URLs into their original form.'
|
26
30
|
method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
|
27
31
|
def all
|
28
|
-
|
32
|
+
streaming_client.before_request do
|
29
33
|
if options['csv']
|
30
34
|
require 'csv'
|
31
35
|
say TWEET_HEADINGS.to_csv
|
@@ -36,7 +40,7 @@ module T
|
|
36
40
|
print_table([headings])
|
37
41
|
end
|
38
42
|
end
|
39
|
-
|
43
|
+
streaming_client.sample do |tweet|
|
40
44
|
next unless tweet.is_a?(Twitter::Tweet)
|
41
45
|
if options['csv']
|
42
46
|
print_csv_tweet(tweet)
|
@@ -51,9 +55,42 @@ module T
|
|
51
55
|
end
|
52
56
|
end
|
53
57
|
|
58
|
+
desc 'list [USER/]LIST', 'Stream a timeline for members of the specified list (Control-C to stop)'
|
59
|
+
method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
|
60
|
+
method_option 'decode_uris', :aliases => '-d', :type => :boolean, :desc => 'Decodes t.co URLs into their original form.'
|
61
|
+
method_option 'id', :aliases => '-i', :type => :boolean, :desc => 'Specify user via ID instead of screen name.'
|
62
|
+
method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
|
63
|
+
method_option 'reverse', :aliases => '-r', :type => :boolean, :desc => 'Reverse the order of the sort.'
|
64
|
+
def list(user_list)
|
65
|
+
owner, list_name = extract_owner(user_list, options)
|
66
|
+
require 't/list'
|
67
|
+
streaming_client.before_request do
|
68
|
+
list = T::List.new
|
69
|
+
list.options = list.options.merge(options)
|
70
|
+
list.options = list.options.merge(:reverse => true)
|
71
|
+
list.options = list.options.merge(:format => TWEET_HEADINGS_FORMATTING)
|
72
|
+
list.timeline(user_list)
|
73
|
+
end
|
74
|
+
user_ids = client.list_members(owner, list_name).collect(&:id)
|
75
|
+
streaming_client.filter(:follow => user_ids.join(',')) do |tweet|
|
76
|
+
next unless tweet.is_a?(Twitter::Tweet)
|
77
|
+
if options['csv']
|
78
|
+
print_csv_tweet(tweet)
|
79
|
+
elsif options['long']
|
80
|
+
array = build_long_tweet(tweet).each_with_index.collect do |element, index|
|
81
|
+
TWEET_HEADINGS_FORMATTING[index] % element
|
82
|
+
end
|
83
|
+
print_table([array], :truncate => STDOUT.tty?)
|
84
|
+
else
|
85
|
+
print_message(tweet.user.screen_name, tweet.text)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
map %w[tl] => :timeline
|
90
|
+
|
54
91
|
desc 'matrix', 'Unfortunately, no one can be told what the Matrix is. You have to see it for yourself.'
|
55
92
|
def matrix
|
56
|
-
|
93
|
+
streaming_client.sample(:language => 'ja') do |tweet|
|
57
94
|
next unless tweet.is_a?(Twitter::Tweet)
|
58
95
|
say(tweet.full_text.gsub("\n", '').reverse, [:bold, :green, :on_black])
|
59
96
|
end
|
@@ -61,18 +98,19 @@ module T
|
|
61
98
|
|
62
99
|
desc 'search KEYWORD [KEYWORD...]', 'Stream Tweets that contain specified keywords, joined with logical ORs (Control-C to stop)'
|
63
100
|
method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
|
101
|
+
method_option 'decode_uris', :aliases => '-d', :type => :boolean, :desc => 'Decodes t.co URLs into their original form.'
|
64
102
|
method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
|
65
103
|
def search(keyword, *keywords)
|
66
104
|
keywords.unshift(keyword)
|
67
105
|
require 't/search'
|
68
|
-
|
106
|
+
streaming_client.before_request do
|
69
107
|
search = T::Search.new
|
70
108
|
search.options = search.options.merge(options)
|
71
109
|
search.options = search.options.merge(:reverse => true)
|
72
110
|
search.options = search.options.merge(:format => TWEET_HEADINGS_FORMATTING)
|
73
111
|
search.all(keywords.join(' OR '))
|
74
112
|
end
|
75
|
-
|
113
|
+
streaming_client.filter(:track => keywords.join(',')) do |tweet|
|
76
114
|
next unless tweet.is_a?(Twitter::Tweet)
|
77
115
|
if options['csv']
|
78
116
|
print_csv_tweet(tweet)
|
@@ -89,17 +127,18 @@ module T
|
|
89
127
|
|
90
128
|
desc 'timeline', 'Stream your timeline (Control-C to stop)'
|
91
129
|
method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
|
130
|
+
method_option 'decode_uris', :aliases => '-d', :type => :boolean, :desc => 'Decodes t.co URLs into their original form.'
|
92
131
|
method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
|
93
132
|
def timeline
|
94
133
|
require 't/cli'
|
95
|
-
|
134
|
+
streaming_client.before_request do
|
96
135
|
cli = T::CLI.new
|
97
136
|
cli.options = cli.options.merge(options)
|
98
137
|
cli.options = cli.options.merge(:reverse => true)
|
99
138
|
cli.options = cli.options.merge(:format => TWEET_HEADINGS_FORMATTING)
|
100
139
|
cli.timeline
|
101
140
|
end
|
102
|
-
|
141
|
+
streaming_client.user do |tweet|
|
103
142
|
next unless tweet.is_a?(Twitter::Tweet)
|
104
143
|
if options['csv']
|
105
144
|
print_csv_tweet(tweet)
|
@@ -116,11 +155,12 @@ module T
|
|
116
155
|
|
117
156
|
desc 'users USER_ID [USER_ID...]', 'Stream Tweets either from or in reply to specified users (Control-C to stop)'
|
118
157
|
method_option 'csv', :aliases => '-c', :type => :boolean, :desc => 'Output in CSV format.'
|
158
|
+
method_option 'decode_uris', :aliases => '-d', :type => :boolean, :desc => 'Decodes t.co URLs into their original form.'
|
119
159
|
method_option 'long', :aliases => '-l', :type => :boolean, :desc => 'Output in long format.'
|
120
160
|
def users(user_id, *user_ids)
|
121
161
|
user_ids.unshift(user_id)
|
122
162
|
user_ids.collect!(&:to_i)
|
123
|
-
|
163
|
+
streaming_client.before_request do
|
124
164
|
if options['csv']
|
125
165
|
require 'csv'
|
126
166
|
say TWEET_HEADINGS.to_csv
|
@@ -131,7 +171,7 @@ module T
|
|
131
171
|
print_table([headings])
|
132
172
|
end
|
133
173
|
end
|
134
|
-
|
174
|
+
streaming_client.filter(:follow => user_ids.join(',')) do |tweet|
|
135
175
|
next unless tweet.is_a?(Twitter::Tweet)
|
136
176
|
if options['csv']
|
137
177
|
print_csv_tweet(tweet)
|
@@ -148,10 +188,10 @@ module T
|
|
148
188
|
|
149
189
|
private
|
150
190
|
|
151
|
-
def
|
152
|
-
return @
|
191
|
+
def streaming_client
|
192
|
+
return @streaming_client if @streaming_client
|
153
193
|
@rcfile.path = options['profile'] if options['profile']
|
154
|
-
@
|
194
|
+
@streaming_client = Twitter::Streaming::Client.new do |config|
|
155
195
|
config.consumer_key = @rcfile.active_consumer_key
|
156
196
|
config.consumer_secret = @rcfile.active_consumer_secret
|
157
197
|
config.access_token = @rcfile.active_token
|
data/lib/t/utils.rb
CHANGED
@@ -61,16 +61,16 @@ module T
|
|
61
61
|
options['id'] ? users.collect!(&:to_i) : users.collect!(&:strip_ats)
|
62
62
|
end
|
63
63
|
|
64
|
-
def extract_owner(
|
65
|
-
owner,
|
66
|
-
if
|
67
|
-
|
64
|
+
def extract_owner(user_list, options)
|
65
|
+
owner, list_name = user_list.split('/')
|
66
|
+
if list_name.nil?
|
67
|
+
list_name = owner
|
68
68
|
owner = @rcfile.active_profile[0]
|
69
69
|
else
|
70
70
|
require 't/core_ext/string'
|
71
71
|
owner = options['id'] ? owner.to_i : owner.strip_ats
|
72
72
|
end
|
73
|
-
[owner,
|
73
|
+
[owner, list_name]
|
74
74
|
end
|
75
75
|
|
76
76
|
def strip_tags(html)
|
data/lib/t/version.rb
CHANGED
data/spec/cli_spec.rb
CHANGED
@@ -8,12 +8,7 @@ describe T::CLI do
|
|
8
8
|
T.utc_offset = 'PST'
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
T.utc_offset = nil
|
13
|
-
Timecop.return
|
14
|
-
end
|
15
|
-
|
16
|
-
before :each do
|
11
|
+
before do
|
17
12
|
T::RCFile.instance.path = fixture_path + '/.trc'
|
18
13
|
@cli = T::CLI.new
|
19
14
|
@cli.options = @cli.options.merge('color' => 'always')
|
@@ -23,12 +18,17 @@ describe T::CLI do
|
|
23
18
|
$stdout = StringIO.new
|
24
19
|
end
|
25
20
|
|
26
|
-
after
|
21
|
+
after do
|
27
22
|
T::RCFile.instance.reset
|
28
23
|
$stderr = @old_stderr
|
29
24
|
$stdout = @old_stdout
|
30
25
|
end
|
31
26
|
|
27
|
+
after :all do
|
28
|
+
T.utc_offset = nil
|
29
|
+
Timecop.return
|
30
|
+
end
|
31
|
+
|
32
32
|
describe '#account' do
|
33
33
|
before do
|
34
34
|
@cli.options = @cli.options.merge('profile' => fixture_path + '/.trc')
|
@@ -4035,6 +4035,58 @@ ID,Since,Last tweeted at,Tweets,Favorites,Listed,Following,Followers,Screen name
|
|
4035
4035
|
@cli.whois('sferik')
|
4036
4036
|
expect($stdout.string).to eq <<-eos
|
4037
4037
|
ID Since Last tweeted at Tweets Favorites Listed Following ...
|
4038
|
+
7505382 Jul 16 2007 Jul 8 10:29 7890 3755 118 212 ...
|
4039
|
+
eos
|
4040
|
+
end
|
4041
|
+
end
|
4042
|
+
end
|
4043
|
+
|
4044
|
+
describe '#whoami' do
|
4045
|
+
before do
|
4046
|
+
stub_get('/1.1/users/show.json').with(:query => {:screen_name => 'testcli', :include_entities => 'false'}).to_return(:body => fixture('sferik.json'))
|
4047
|
+
end
|
4048
|
+
it 'requests the correct resource' do
|
4049
|
+
@cli.whoami
|
4050
|
+
expect(a_get('/1.1/users/show.json').with(:query => {:screen_name => 'testcli', :include_entities => 'false'})).to have_been_made
|
4051
|
+
end
|
4052
|
+
it 'has the correct output' do
|
4053
|
+
@cli.whoami
|
4054
|
+
expect($stdout.string).to eq <<-eos
|
4055
|
+
ID 7505382
|
4056
|
+
Since Jul 16 2007 (4 years ago)
|
4057
|
+
Last update @goldman You're near my home town! Say hi to Woodstock for me. (7 months ago)
|
4058
|
+
Screen name @sferik
|
4059
|
+
Name Erik Michaels-Ober
|
4060
|
+
Tweets 7,890
|
4061
|
+
Favorites 3,755
|
4062
|
+
Listed 118
|
4063
|
+
Following 212
|
4064
|
+
Followers 2,262
|
4065
|
+
Bio Vagabond.
|
4066
|
+
Location San Francisco
|
4067
|
+
URL https://github.com/sferik
|
4068
|
+
eos
|
4069
|
+
end
|
4070
|
+
context '--csv' do
|
4071
|
+
before do
|
4072
|
+
@cli.options = @cli.options.merge('csv' => true)
|
4073
|
+
end
|
4074
|
+
it 'has the correct output' do
|
4075
|
+
@cli.whoami
|
4076
|
+
expect($stdout.string).to eq <<-eos
|
4077
|
+
ID,Since,Last tweeted at,Tweets,Favorites,Listed,Following,Followers,Screen name,Name,Verified,Protected,Bio,Status,Location,URL
|
4078
|
+
7505382,2007-07-16 12:59:01 +0000,2012-07-08 18:29:20 +0000,7890,3755,118,212,2262,sferik,Erik Michaels-Ober,false,false,Vagabond.,@goldman You're near my home town! Say hi to Woodstock for me.,San Francisco,https://github.com/sferik
|
4079
|
+
eos
|
4080
|
+
end
|
4081
|
+
end
|
4082
|
+
context '--long' do
|
4083
|
+
before do
|
4084
|
+
@cli.options = @cli.options.merge('long' => true)
|
4085
|
+
end
|
4086
|
+
it 'outputs in long format' do
|
4087
|
+
@cli.whoami
|
4088
|
+
expect($stdout.string).to eq <<-eos
|
4089
|
+
ID Since Last tweeted at Tweets Favorites Listed Following ...
|
4038
4090
|
7505382 Jul 16 2007 Jul 8 10:29 7890 3755 118 212 ...
|
4039
4091
|
eos
|
4040
4092
|
end
|