t 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +0 -1
- data/.travis.yml +0 -1
- data/README.md +28 -99
- data/lib/t.rb +0 -13
- data/lib/t/cli.rb +385 -147
- data/lib/t/collectable.rb +1 -1
- data/lib/t/delete.rb +84 -0
- data/lib/t/list.rb +103 -0
- data/lib/t/search.rb +133 -0
- data/lib/t/set.rb +57 -0
- data/lib/t/version.rb +1 -1
- data/spec/cli_spec.rb +330 -201
- data/spec/{cli/delete_spec.rb → delete_spec.rb} +86 -124
- data/spec/fixtures/recommendations.json +1 -1
- data/spec/fixtures/users.json +1 -0
- data/spec/helper.rb +0 -1
- data/spec/{cli/list_spec.rb → list_spec.rb} +77 -6
- data/spec/rcfile_spec.rb +0 -4
- data/spec/{cli/search_spec.rb → search_spec.rb} +1 -1
- data/spec/{cli/set_spec.rb → set_spec.rb} +1 -1
- data/t.gemspec +2 -2
- metadata +26 -36
- data/lib/t/cli/delete.rb +0 -85
- data/lib/t/cli/follow.rb +0 -78
- data/lib/t/cli/list.rb +0 -58
- data/lib/t/cli/list/add.rb +0 -144
- data/lib/t/cli/list/remove.rb +0 -136
- data/lib/t/cli/search.rb +0 -124
- data/lib/t/cli/set.rb +0 -59
- data/lib/t/cli/unfollow.rb +0 -121
- data/spec/cli/follow_spec.rb +0 -240
- data/spec/cli/list/add_spec.rb +0 -518
- data/spec/cli/list/remove_spec.rb +0 -422
- data/spec/cli/unfollow_spec.rb +0 -410
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -12,7 +12,6 @@ however it offers many more commands than are available via SMS.
|
|
12
12
|
## <a name="installation"></a>Installation
|
13
13
|
gem install t
|
14
14
|
|
15
|
-
|
16
15
|
## <a name="configuration"></a>Configuration
|
17
16
|
|
18
17
|
Because Twitter requires OAuth for most of its functionality, you'll need to
|
@@ -49,134 +48,66 @@ username and consumer key pair, like so:
|
|
49
48
|
Account information is stored in the YAML-formatted file `~/.trc`.
|
50
49
|
|
51
50
|
## <a name="examples"></a>Usage Examples
|
52
|
-
|
53
51
|
Typing `t help` will give you a list of all the available commands. You can
|
54
52
|
type `t help TASK` to get help for a specific command.
|
55
53
|
|
56
54
|
t help
|
57
55
|
|
58
56
|
### <a name="update"></a>Update your status
|
59
|
-
|
60
57
|
t update "I'm tweeting from the command line. Isn't that special?"
|
61
58
|
|
62
|
-
### <a name="
|
63
|
-
|
64
|
-
t dm sferik "Want to get dinner tonight?"
|
65
|
-
|
66
|
-
### <a name="location"></a>Update the location field in your profile
|
67
|
-
|
68
|
-
t set location "San Francisco"
|
69
|
-
|
70
|
-
### <a name="whois"></a>Retrieve profile information for a user
|
71
|
-
|
72
|
-
t whois sferik
|
73
|
-
|
74
|
-
### <a name="stats"></a>Retrieve stats about a user
|
75
|
-
|
76
|
-
t stats sferik
|
77
|
-
|
78
|
-
### <a name="suggest"></a>Return a user you might enjoy following
|
79
|
-
|
80
|
-
t suggest
|
59
|
+
### <a name="stats"></a>Retrieve stats about users
|
60
|
+
t users -l sferik gem
|
81
61
|
|
82
|
-
### <a name="follow
|
62
|
+
### <a name="follow"></a>Follow users
|
63
|
+
t follow sferik gem
|
83
64
|
|
84
|
-
|
65
|
+
### <a name="friends"></a>List your friends (ordered by number of followers)
|
66
|
+
t friends -lf
|
85
67
|
|
86
|
-
### <a name="
|
68
|
+
### <a name="leaders"></a>List your leaders (people you follow who don't follow you back)
|
69
|
+
t leaders -lf
|
87
70
|
|
88
|
-
|
71
|
+
### <a name="unfollow"></a>Unfollow everyone you follow who doesn't follow you back
|
72
|
+
t leaders | xargs t unfollow
|
89
73
|
|
90
|
-
###
|
91
|
-
|
92
|
-
t unfollow users sferik gem
|
93
|
-
|
94
|
-
### <a name="unfollow-nonfollowers"></a>Unfollow all non-followers
|
95
|
-
|
96
|
-
t unfollow nonfollowers
|
74
|
+
### Follow back everyone who follows you
|
75
|
+
t followers | xargs t follow
|
97
76
|
|
98
77
|
### <a name="list-create"></a>Create a list
|
99
|
-
|
100
78
|
t list create presidents
|
101
79
|
|
102
|
-
### <a name="list-add
|
103
|
-
|
104
|
-
t list add users presidents BarackObama Jasonfinn
|
105
|
-
|
106
|
-
### <a name="list-add-friends"></a>Add all friends to a list
|
107
|
-
|
108
|
-
t list add friends presidents
|
109
|
-
|
110
|
-
### <a name="list-add-followers"></a>Add all followers to a list
|
111
|
-
|
112
|
-
t list add followers presidents
|
113
|
-
|
114
|
-
### <a name="list-add-followers"></a>Add all members of one list to another
|
115
|
-
|
116
|
-
t list add listed democrats presidents
|
80
|
+
### <a name="list-add"></a>Add users to a list
|
81
|
+
t list add presidents BarackObama Jasonfinn
|
117
82
|
|
118
|
-
### <a name="
|
83
|
+
### <a name="following"></a>Create a list that contains today's date in the name
|
84
|
+
date "+following-%Y-%m-%d" | xargs t list create
|
119
85
|
|
120
|
-
|
86
|
+
### Add everyone you're following to a list
|
87
|
+
t followings | xargs t list add following-`date "+%Y-%m-%d"`
|
121
88
|
|
122
|
-
### <a name="
|
89
|
+
### <a name="members"></a>Display members of a list
|
90
|
+
t members following-`date "+%Y-%m-%d"`
|
123
91
|
|
124
|
-
|
125
|
-
|
126
|
-
### <a name="list-timeline"></a>Retrieve the timeline of status updates from a list
|
127
|
-
|
128
|
-
t list timeline presidents
|
129
|
-
|
130
|
-
### <a name="timeline"></a>Retrieve the timeline of status updates posted by you and the users you follow
|
131
|
-
|
132
|
-
t timeline
|
133
|
-
|
134
|
-
### <a name="timeline-user"></a>Retrieve the timeline of status updates posted by a user
|
135
|
-
|
136
|
-
t timeline sferik
|
137
|
-
|
138
|
-
### <a name="mentions"></a>Retrieve the timeline of status updates that mention you
|
139
|
-
|
140
|
-
t mentions
|
141
|
-
|
142
|
-
### <a name="favorites"></a>Retrieve the timeline of status updates that you favorited
|
143
|
-
|
144
|
-
t favorites
|
145
|
-
|
146
|
-
### <a name="reply"></a>Reply to a Tweet
|
147
|
-
|
148
|
-
t reply sferik "Thanks Erik"
|
149
|
-
|
150
|
-
### <a name="retweet"></a>Send another user's latest Tweet to your followers
|
151
|
-
|
152
|
-
t retweet sferik
|
153
|
-
|
154
|
-
### <a name="favorite"></a>Mark a user's latest Tweet as one of your favorites
|
155
|
-
|
156
|
-
t favorite sferik
|
157
|
-
|
158
|
-
### <a name="search-all"></a>Retrieve the 20 most recent Tweets that match a specified query
|
92
|
+
### Count the number of Twitter employees
|
93
|
+
t members twitter team | wc -l
|
159
94
|
|
95
|
+
### <a name="search-all"></a>Search Twitter for the 20 most recent Tweets that match a specified query
|
160
96
|
t search all "query"
|
161
97
|
|
162
|
-
### <a name="search-retweets"></a>
|
163
|
-
|
98
|
+
### <a name="search-retweets"></a>Search Tweets you've favorited that match a specified query
|
164
99
|
t search favorites "query"
|
165
100
|
|
166
|
-
### <a name="search-mentions"></a>
|
167
|
-
|
101
|
+
### <a name="search-mentions"></a>Search Tweets mentioning you that match a specified query
|
168
102
|
t search mentions "query"
|
169
103
|
|
170
|
-
### <a name="search-retweets"></a>
|
171
|
-
|
104
|
+
### <a name="search-retweets"></a>Search Tweets you've retweeted that match a specified query
|
172
105
|
t search retweets "query"
|
173
106
|
|
174
|
-
### <a name="search-timeline"></a>
|
175
|
-
|
107
|
+
### <a name="search-timeline"></a>Search Tweets in your timeline that match a specified query
|
176
108
|
t search timeline "query"
|
177
109
|
|
178
|
-
### <a name="search-user"></a>
|
179
|
-
|
110
|
+
### <a name="search-user"></a>Search Tweets in a user's timeline that match a specified query
|
180
111
|
t search user sferik "query"
|
181
112
|
|
182
113
|
## <a name="history"></a>History
|
@@ -240,10 +171,8 @@ implementations:
|
|
240
171
|
* Ruby 1.8.7
|
241
172
|
* Ruby 1.9.2
|
242
173
|
* Ruby 1.9.3
|
243
|
-
* [JRuby][]
|
244
174
|
* [Rubinius][]
|
245
175
|
|
246
|
-
[jruby]: http://www.jruby.org/
|
247
176
|
[rubinius]: http://rubini.us/
|
248
177
|
|
249
178
|
If something doesn't work on one of these interpreters, it should be considered
|
data/lib/t.rb
CHANGED
@@ -1,14 +1 @@
|
|
1
|
-
require 'active_support/string_inquirer'
|
2
1
|
require 't/cli'
|
3
|
-
|
4
|
-
module T
|
5
|
-
class << self
|
6
|
-
def env
|
7
|
-
@env ||= ActiveSupport::StringInquirer.new("development")
|
8
|
-
end
|
9
|
-
|
10
|
-
def env=(environment)
|
11
|
-
@env = ActiveSupport::StringInquirer.new(environment)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
data/lib/t/cli.rb
CHANGED
@@ -1,9 +1,19 @@
|
|
1
1
|
require 'action_view'
|
2
|
+
require 'active_support/core_ext/array/grouping'
|
3
|
+
require 'active_support/core_ext/date/calculations'
|
4
|
+
require 'active_support/core_ext/integer/time'
|
5
|
+
require 'active_support/core_ext/numeric/time'
|
6
|
+
require 'highline'
|
2
7
|
require 'launchy'
|
3
8
|
require 'oauth'
|
4
|
-
require '
|
9
|
+
require 't/collectable'
|
5
10
|
require 't/core_ext/string'
|
11
|
+
require 't/delete'
|
12
|
+
require 't/list'
|
6
13
|
require 't/rcfile'
|
14
|
+
require 't/search'
|
15
|
+
require 't/set'
|
16
|
+
require 't/version'
|
7
17
|
require 'thor'
|
8
18
|
require 'time'
|
9
19
|
require 'twitter'
|
@@ -13,12 +23,13 @@ module T
|
|
13
23
|
class CLI < Thor
|
14
24
|
include ActionView::Helpers::DateHelper
|
15
25
|
include ActionView::Helpers::NumberHelper
|
16
|
-
include
|
26
|
+
include T::Collectable
|
17
27
|
|
18
28
|
DEFAULT_HOST = 'api.twitter.com'
|
19
29
|
DEFAULT_PROTOCOL = 'https'
|
20
30
|
DEFAULT_NUM_RESULTS = 20
|
21
31
|
MAX_SCREEN_NAME_SIZE = 20
|
32
|
+
MAX_USERS_PER_REQUEST = 100
|
22
33
|
|
23
34
|
check_unknown_options!
|
24
35
|
|
@@ -77,86 +88,248 @@ module T
|
|
77
88
|
}
|
78
89
|
}
|
79
90
|
@rcfile.default_profile = {'username' => screen_name, 'consumer_key' => options['consumer_key']}
|
80
|
-
say "Authorization successful"
|
91
|
+
say "Authorization successful."
|
81
92
|
end
|
82
93
|
|
83
|
-
desc "block SCREEN_NAME", "Block
|
84
|
-
def block(screen_name)
|
85
|
-
screen_name
|
86
|
-
|
87
|
-
|
94
|
+
desc "block SCREEN_NAME [SCREEN_NAME...]", "Block users."
|
95
|
+
def block(screen_name, *screen_names)
|
96
|
+
screen_names.unshift(screen_name)
|
97
|
+
screen_names.threaded_each do |screen_name|
|
98
|
+
screen_name.strip_at
|
99
|
+
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
100
|
+
client.block(screen_name, :include_entities => false)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
say "@#{@rcfile.default_profile[0]} blocked @#{screen_names.join(' ')}."
|
88
104
|
say
|
89
|
-
say "Run `#{File.basename($0)} delete block #{
|
105
|
+
say "Run `#{File.basename($0)} delete block #{screen_names.join(' ')}` to unblock."
|
90
106
|
end
|
91
107
|
|
92
108
|
desc "direct_messages", "Returns the #{DEFAULT_NUM_RESULTS} most recent Direct Messages sent to you."
|
109
|
+
method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
|
93
110
|
method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
|
111
|
+
method_option :reverse, :aliases => "-r", :type => :boolean, :default => false
|
94
112
|
def direct_messages
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
113
|
+
count = options['number'] || DEFAULT_NUM_RESULTS
|
114
|
+
direct_messages = client.direct_messages(:count => count, :include_entities => false)
|
115
|
+
direct_messages.reverse! if options['reverse']
|
116
|
+
if options['long']
|
117
|
+
array = direct_messages.map do |direct_message|
|
118
|
+
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+/, ' ')]
|
120
|
+
end
|
121
|
+
if STDOUT.tty?
|
122
|
+
headings = ["ID", "Created at", "Screen name", "Text"]
|
123
|
+
array.unshift(headings)
|
124
|
+
end
|
125
|
+
print_table(array)
|
126
|
+
else
|
127
|
+
direct_messages.each do |direct_message|
|
128
|
+
say "#{direct_message.sender.screen_name.rjust(MAX_SCREEN_NAME_SIZE)}: #{direct_message.text.gsub(/\n+/, ' ')} (#{time_ago_in_words(direct_message.created_at)} ago)"
|
129
|
+
end
|
100
130
|
end
|
101
131
|
end
|
102
132
|
map %w(dms) => :direct_messages
|
103
133
|
|
134
|
+
desc "direct_messages_sent", "Returns the #{DEFAULT_NUM_RESULTS} most recent Direct Messages sent to you."
|
135
|
+
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
|
138
|
+
def direct_messages_sent
|
139
|
+
count = options['number'] || DEFAULT_NUM_RESULTS
|
140
|
+
direct_messages = client.direct_messages_sent(:count => count, :include_entities => false)
|
141
|
+
direct_messages.reverse! if options['reverse']
|
142
|
+
if options['long']
|
143
|
+
array = direct_messages.map do |direct_message|
|
144
|
+
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+/, ' ')]
|
146
|
+
end
|
147
|
+
if STDOUT.tty?
|
148
|
+
headings = ["ID", "Created at", "Screen name", "Text"]
|
149
|
+
array.unshift(headings)
|
150
|
+
end
|
151
|
+
print_table(array)
|
152
|
+
else
|
153
|
+
direct_messages.each do |direct_message|
|
154
|
+
say "#{direct_message.recipient.screen_name.rjust(MAX_SCREEN_NAME_SIZE)}: #{direct_message.text.gsub(/\n+/, ' ')} (#{time_ago_in_words(direct_message.created_at)} ago)"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
map %w(sent_messages sms) => :direct_messages_sent
|
159
|
+
|
104
160
|
desc "dm SCREEN_NAME MESSAGE", "Sends that person a Direct Message."
|
105
161
|
def dm(screen_name, message)
|
106
162
|
screen_name = screen_name.strip_at
|
107
163
|
direct_message = client.direct_message_create(screen_name, message, :include_entities => false)
|
108
|
-
say "Direct Message sent from @#{@rcfile.default_profile[0]} to @#{direct_message.recipient.screen_name} (#{time_ago_in_words(direct_message.created_at)} ago)"
|
164
|
+
say "Direct Message sent from @#{@rcfile.default_profile[0]} to @#{direct_message.recipient.screen_name} (#{time_ago_in_words(direct_message.created_at)} ago)."
|
109
165
|
end
|
110
|
-
map %w(m) => :dm
|
111
|
-
|
112
|
-
desc "favorite
|
113
|
-
def favorite(
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
say
|
120
|
-
say "Run `#{File.basename($0)} delete favorite` to unfavorite."
|
121
|
-
else
|
122
|
-
raise Thor::Error, "Tweet not found"
|
166
|
+
map %w(d m) => :dm
|
167
|
+
|
168
|
+
desc "favorite STATUS_ID [STATUS_ID...]", "Marks Tweets as favorites."
|
169
|
+
def favorite(status_id, *status_ids)
|
170
|
+
status_ids.unshift(status_id)
|
171
|
+
favorites = status_ids.threaded_map do |status_id|
|
172
|
+
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
173
|
+
client.favorite(status_id, :include_entities => false)
|
174
|
+
end
|
123
175
|
end
|
124
|
-
|
125
|
-
|
126
|
-
say "@#{@rcfile.default_profile[0]} favorited @#{user.screen_name}'s latest status: \"#{user.status.text}\""
|
127
|
-
else
|
128
|
-
raise
|
176
|
+
favorites.each do |status|
|
177
|
+
say "@#{@rcfile.default_profile[0]} favorited @#{status.user.screen_name}'s status: \"#{status.text.gsub(/\n+/, ' ')}\""
|
129
178
|
end
|
179
|
+
say
|
180
|
+
say "Run `#{File.basename($0)} delete favorite #{status_ids.join(' ')}` to unfavorite."
|
130
181
|
end
|
131
182
|
map %w(fave) => :favorite
|
132
183
|
|
133
184
|
desc "favorites", "Returns the #{DEFAULT_NUM_RESULTS} most recent Tweets you favorited."
|
185
|
+
method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
|
134
186
|
method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
|
135
187
|
method_option :reverse, :aliases => "-r", :type => :boolean, :default => false
|
136
188
|
def favorites
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
timeline.reverse! if options['reverse']
|
141
|
-
page unless T.env.test?
|
142
|
-
timeline.each do |status|
|
143
|
-
say "#{status.user.screen_name.rjust(MAX_SCREEN_NAME_SIZE)}: #{status.text} (#{time_ago_in_words(status.created_at)} ago)"
|
144
|
-
end
|
189
|
+
count = options['number'] || DEFAULT_NUM_RESULTS
|
190
|
+
statuses = client.favorites(:count => count, :include_entities => false)
|
191
|
+
print_status_list(statuses)
|
145
192
|
end
|
146
193
|
map %w(faves) => :favorites
|
147
194
|
|
195
|
+
desc "follow SCREEN_NAME [SCREEN_NAME...]", "Allows you to start following users."
|
196
|
+
def follow(screen_name, *screen_names)
|
197
|
+
screen_names.unshift(screen_name)
|
198
|
+
screen_names.threaded_each do |screen_name|
|
199
|
+
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
200
|
+
client.follow(screen_name, :include_entities => false)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
number = screen_names.length
|
204
|
+
say "@#{@rcfile.default_profile[0]} is now following #{number} more #{number == 1 ? 'user' : 'users'}."
|
205
|
+
say
|
206
|
+
say "Run `#{File.basename($0)} unfollow users #{screen_names.join(' ')}` to stop."
|
207
|
+
end
|
208
|
+
|
209
|
+
desc "followings", "Returns a list of the people you follow on Twitter."
|
210
|
+
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."
|
213
|
+
method_option :listed, :aliases => "-i", :type => :boolean, :default => false, :desc => "Sort by number of list memberships."
|
214
|
+
method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
|
215
|
+
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."
|
217
|
+
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
|
+
def followings
|
220
|
+
following_ids = collect_with_cursor do |cursor|
|
221
|
+
client.friend_ids(:cursor => cursor)
|
222
|
+
end
|
223
|
+
users = following_ids.in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_map do |following_id_group|
|
224
|
+
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
225
|
+
client.users(following_id_group, :include_entities => false)
|
226
|
+
end
|
227
|
+
end.flatten
|
228
|
+
print_user_list(users)
|
229
|
+
end
|
230
|
+
|
231
|
+
desc "followers", "Returns a list of the people who follow you on Twitter."
|
232
|
+
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."
|
235
|
+
method_option :listed, :aliases => "-i", :type => :boolean, :default => false, :desc => "Sort by number of list memberships."
|
236
|
+
method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
|
237
|
+
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."
|
239
|
+
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
|
+
def followers
|
242
|
+
follower_ids = collect_with_cursor do |cursor|
|
243
|
+
client.follower_ids(:cursor => cursor)
|
244
|
+
end
|
245
|
+
users = follower_ids.in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_map do |follower_id_group|
|
246
|
+
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
247
|
+
client.users(follower_id_group, :include_entities => false)
|
248
|
+
end
|
249
|
+
end.flatten
|
250
|
+
print_user_list(users)
|
251
|
+
end
|
252
|
+
|
253
|
+
desc "friends", "Returns the list of people who you follow and follow you back."
|
254
|
+
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."
|
257
|
+
method_option :listed, :aliases => "-i", :type => :boolean, :default => false, :desc => "Sort by number of list memberships."
|
258
|
+
method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
|
259
|
+
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."
|
261
|
+
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
|
+
def friends
|
264
|
+
following_ids = collect_with_cursor do |cursor|
|
265
|
+
client.friend_ids(:cursor => cursor)
|
266
|
+
end
|
267
|
+
follower_ids = collect_with_cursor do |cursor|
|
268
|
+
client.follower_ids(:cursor => cursor)
|
269
|
+
end
|
270
|
+
friend_ids = (following_ids & follower_ids)
|
271
|
+
users = friend_ids.in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_map do |friend_id_group|
|
272
|
+
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
273
|
+
client.users(friend_id_group, :include_entities => false)
|
274
|
+
end
|
275
|
+
end.flatten
|
276
|
+
print_user_list(users)
|
277
|
+
end
|
278
|
+
|
279
|
+
desc "leaders", "Returns the list of people who you follow but don't follow you back."
|
280
|
+
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."
|
283
|
+
method_option :listed, :aliases => "-i", :type => :boolean, :default => false, :desc => "Sort by number of list memberships."
|
284
|
+
method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
|
285
|
+
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."
|
287
|
+
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
|
+
def leaders
|
290
|
+
following_ids = collect_with_cursor do |cursor|
|
291
|
+
client.friend_ids(:cursor => cursor)
|
292
|
+
end
|
293
|
+
follower_ids = collect_with_cursor do |cursor|
|
294
|
+
client.follower_ids(:cursor => cursor)
|
295
|
+
end
|
296
|
+
leader_ids = (following_ids - follower_ids)
|
297
|
+
users = leader_ids.in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_map do |leader_id_group|
|
298
|
+
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
299
|
+
client.users(leader_id_group, :include_entities => false)
|
300
|
+
end
|
301
|
+
end.flatten
|
302
|
+
print_user_list(users)
|
303
|
+
end
|
304
|
+
|
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
|
+
|
148
325
|
desc "mentions", "Returns the #{DEFAULT_NUM_RESULTS} most recent Tweets mentioning you."
|
326
|
+
method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
|
149
327
|
method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
|
150
328
|
method_option :reverse, :aliases => "-r", :type => :boolean, :default => false
|
151
329
|
def mentions
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
timeline.reverse! if options['reverse']
|
156
|
-
page unless T.env.test?
|
157
|
-
timeline.each do |status|
|
158
|
-
say "#{status.user.screen_name.rjust(MAX_SCREEN_NAME_SIZE)}: #{status.text} (#{time_ago_in_words(status.created_at)} ago)"
|
159
|
-
end
|
330
|
+
count = options['number'] || DEFAULT_NUM_RESULTS
|
331
|
+
statuses = client.mentions(:count => count, :include_entities => false)
|
332
|
+
print_status_list(statuses)
|
160
333
|
end
|
161
334
|
map %w(replies) => :mentions
|
162
335
|
|
@@ -167,126 +340,136 @@ module T
|
|
167
340
|
Launchy.open("https://twitter.com/#{screen_name}", :dry_run => options.fetch('dry_run', false))
|
168
341
|
end
|
169
342
|
|
170
|
-
desc "reply
|
343
|
+
desc "reply STATUS_ID MESSAGE", "Post your Tweet as a reply directed at another person."
|
171
344
|
method_option :location, :aliases => "-l", :type => :boolean, :default => false
|
172
|
-
def reply(
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
status = client.update("@#{user.screen_name} #{message}", defaults)
|
179
|
-
say "Reply created by @#{@rcfile.default_profile[0]} to @#{user.screen_name} (#{time_ago_in_words(status.created_at)} ago)"
|
345
|
+
def reply(status_id, message)
|
346
|
+
status = client.status(status_id, :include_entities => false, :include_my_retweet => false, :trim_user => true)
|
347
|
+
opts = {:in_reply_to_status_id => status.id, :include_entities => false, :trim_user => true}
|
348
|
+
opts.merge!(:lat => location.lat, :long => location.lng) if options['location']
|
349
|
+
reply = client.update("@#{status.user.screen_name} #{message}", opts)
|
350
|
+
say "Reply created by @#{@rcfile.default_profile[0]} to @#{status.user.screen_name} (#{time_ago_in_words(reply.created_at)} ago)."
|
180
351
|
say
|
181
|
-
say "Run `#{File.basename($0)} delete status` to delete."
|
352
|
+
say "Run `#{File.basename($0)} delete status #{reply.id}` to delete."
|
182
353
|
end
|
183
354
|
|
184
|
-
desc "
|
185
|
-
def
|
186
|
-
screen_name
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
say "Run `#{File.basename($0)} delete status` to undo."
|
193
|
-
else
|
194
|
-
raise Thor::Error, "Tweet not found"
|
355
|
+
desc "report_spam SCREEN_NAME [SCREEN_NAME...]", "Report users for spam."
|
356
|
+
def report_spam(screen_name, *screen_names)
|
357
|
+
screen_names.unshift(screen_name)
|
358
|
+
screen_names.threaded_each do |screen_name|
|
359
|
+
screen_name.strip_at
|
360
|
+
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
361
|
+
client.report_spam(screen_name, :include_entities => false)
|
362
|
+
end
|
195
363
|
end
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
364
|
+
say "@#{@rcfile.default_profile[0]} reported @#{screen_names.join(' ')}."
|
365
|
+
end
|
366
|
+
map %w(report spam) => :report_spam
|
367
|
+
|
368
|
+
desc "retweet STATUS_ID [STATUS_ID...]", "Sends Tweets to your followers."
|
369
|
+
def retweet(status_id, *status_ids)
|
370
|
+
status_ids.unshift(status_id)
|
371
|
+
retweets = status_ids.threaded_map do |status_id|
|
372
|
+
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
373
|
+
client.retweet(status_id, :include_entities => false, :trim_user => true)
|
374
|
+
end
|
375
|
+
end
|
376
|
+
retweets.each do |status|
|
377
|
+
say "@#{@rcfile.default_profile[0]} retweeted @#{status.user.screen_name}'s status: \"#{status.text.gsub(/\n+/, ' ')}\""
|
201
378
|
end
|
379
|
+
say
|
380
|
+
say "Run `#{File.basename($0)} delete status #{status_ids.join(' ')}` to undo."
|
202
381
|
end
|
203
382
|
map %w(rt) => :retweet
|
204
383
|
|
205
384
|
desc "retweets [SCREEN_NAME]", "Returns the #{DEFAULT_NUM_RESULTS} most recent Retweets by a user."
|
385
|
+
method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
|
206
386
|
method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
|
207
387
|
method_option :reverse, :aliases => "-r", :type => :boolean, :default => false
|
208
388
|
def retweets(screen_name=nil)
|
209
389
|
screen_name = screen_name.strip_at if screen_name
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
timeline.reverse! if options['reverse']
|
214
|
-
page unless T.env.test?
|
215
|
-
timeline.each do |status|
|
216
|
-
say "#{status.user.screen_name.rjust(MAX_SCREEN_NAME_SIZE)}: #{status.text} (#{time_ago_in_words(status.created_at)} ago)"
|
217
|
-
end
|
390
|
+
count = options['number'] || DEFAULT_NUM_RESULTS
|
391
|
+
statuses = client.retweeted_by(screen_name, :count => count, :include_entities => false)
|
392
|
+
print_status_list(statuses)
|
218
393
|
end
|
219
394
|
map %w(rts) => :retweets
|
220
395
|
|
221
|
-
desc "sent_messages", "Returns the #{DEFAULT_NUM_RESULTS} most recent Direct Messages sent to you."
|
222
|
-
method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
|
223
|
-
def sent_messages
|
224
|
-
defaults = {:include_entities => false}
|
225
|
-
defaults.merge!(:count => options['number']) if options['number']
|
226
|
-
page unless T.env.test?
|
227
|
-
client.direct_messages_sent(defaults).each do |direct_message|
|
228
|
-
say "#{direct_message.recipient.screen_name.rjust(MAX_SCREEN_NAME_SIZE)}: #{direct_message.text} (#{time_ago_in_words(direct_message.created_at)} ago)"
|
229
|
-
end
|
230
|
-
end
|
231
|
-
map %w(sms) => :sent_messages
|
232
|
-
|
233
|
-
desc "stats SCREEN_NAME", "Retrieves the given user's number of followers and how many people they're following."
|
234
|
-
def stats(screen_name)
|
235
|
-
screen_name = screen_name.strip_at
|
236
|
-
user = client.user(screen_name, :include_entities => false)
|
237
|
-
say "Tweets: #{number_with_delimiter(user.statuses_count)}"
|
238
|
-
say "Following: #{number_with_delimiter(user.friends_count)}"
|
239
|
-
say "Followers: #{number_with_delimiter(user.followers_count)}"
|
240
|
-
say "Favorites: #{number_with_delimiter(user.favorites_count)}"
|
241
|
-
say "Listed: #{number_with_delimiter(user.listed_count)}"
|
242
|
-
say
|
243
|
-
say "Run `#{File.basename($0)} whois #{user.screen_name}` to view profile."
|
244
|
-
end
|
245
|
-
|
246
396
|
desc "status MESSAGE", "Post a Tweet."
|
247
397
|
method_option :location, :aliases => "-l", :type => :boolean, :default => false
|
248
398
|
def status(message)
|
249
|
-
|
250
|
-
|
251
|
-
status = client.update(message,
|
252
|
-
say "Tweet created by @#{@rcfile.default_profile[0]} (#{time_ago_in_words(status.created_at)} ago)"
|
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)."
|
253
403
|
say
|
254
|
-
say "Run `#{File.basename($0)} delete status` to delete."
|
404
|
+
say "Run `#{File.basename($0)} delete status #{status.id}` to delete."
|
255
405
|
end
|
256
406
|
map %w(post tweet update) => :status
|
257
407
|
|
258
408
|
desc "suggest", "This command returns a listing of Twitter users' accounts we think you might enjoy following."
|
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."
|
411
|
+
method_option :listed, :aliases => "-i", :type => :boolean, :default => false, :desc => "Sort by number of list memberships."
|
412
|
+
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 :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 :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."
|
259
419
|
def suggest
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
say
|
264
|
-
say "Run `#{File.basename($0)} follow #{recommendation.screen_name}` to follow."
|
265
|
-
say "Run `#{File.basename($0)} whois #{recommendation.screen_name}` for profile."
|
266
|
-
say "Run `#{File.basename($0)} suggest` for another recommendation."
|
267
|
-
end
|
420
|
+
limit = options['number'] || DEFAULT_NUM_RESULTS
|
421
|
+
users = client.recommendations(:limit => limit, :include_entities => false)
|
422
|
+
print_user_list(users)
|
268
423
|
end
|
269
424
|
|
270
425
|
desc "timeline [SCREEN_NAME]", "Returns the #{DEFAULT_NUM_RESULTS} most recent Tweets posted by a user."
|
426
|
+
method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
|
271
427
|
method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
|
272
428
|
method_option :reverse, :aliases => "-r", :type => :boolean, :default => false
|
273
429
|
def timeline(screen_name=nil)
|
274
|
-
|
275
|
-
defaults.merge!(:count => options['number']) if options['number']
|
430
|
+
count = options['number'] || DEFAULT_NUM_RESULTS
|
276
431
|
if screen_name
|
277
432
|
screen_name = screen_name.strip_at
|
278
|
-
|
433
|
+
statuses = client.user_timeline(screen_name, :count => count, :include_entities => false)
|
279
434
|
else
|
280
|
-
|
281
|
-
end
|
282
|
-
timeline.reverse! if options['reverse']
|
283
|
-
page unless T.env.test?
|
284
|
-
timeline.each do |status|
|
285
|
-
say "#{status.user.screen_name.rjust(MAX_SCREEN_NAME_SIZE)}: #{status.text} (#{time_ago_in_words(status.created_at)} ago)"
|
435
|
+
statuses = client.home_timeline(:count => count, :include_entities => false)
|
286
436
|
end
|
437
|
+
print_status_list(statuses)
|
287
438
|
end
|
288
439
|
map %w(tl) => :timeline
|
289
440
|
|
441
|
+
desc "unfollow SCREEN_NAME [SCREEN_NAME...]", "Allows you to stop following users."
|
442
|
+
def unfollow(screen_name, *screen_names)
|
443
|
+
screen_names.unshift(screen_name)
|
444
|
+
screen_names.threaded_each do |screen_name|
|
445
|
+
retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
|
446
|
+
client.unfollow(screen_name, :include_entities => false)
|
447
|
+
end
|
448
|
+
end
|
449
|
+
number = screen_names.length
|
450
|
+
say "@#{@rcfile.default_profile[0]} is no longer following #{number} #{number == 1 ? 'user' : 'users'}."
|
451
|
+
say
|
452
|
+
say "Run `#{File.basename($0)} follow users #{screen_names.join(' ')}` to follow again."
|
453
|
+
end
|
454
|
+
|
455
|
+
desc "users SCREEN_NAME [SCREEN_NAME...]", "Returns a list of users you specify."
|
456
|
+
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."
|
459
|
+
method_option :listed, :aliases => "-i", :type => :boolean, :default => false, :desc => "Sort by number of list memberships."
|
460
|
+
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
|
+
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."
|
464
|
+
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
|
+
def users(screen_name, *screen_names)
|
467
|
+
screen_names.unshift(screen_name)
|
468
|
+
users = client.users(screen_names, :include_entities => false)
|
469
|
+
print_user_list(users)
|
470
|
+
end
|
471
|
+
map %w(stats) => :users
|
472
|
+
|
290
473
|
desc "version", "Show version."
|
291
474
|
def version
|
292
475
|
say T::Version
|
@@ -304,30 +487,19 @@ module T
|
|
304
487
|
say "web: #{user.url}"
|
305
488
|
end
|
306
489
|
|
307
|
-
require 't/cli/delete'
|
308
490
|
desc "delete SUBCOMMAND ...ARGS", "Delete Tweets, Direct Messages, etc."
|
309
|
-
method_option :force, :aliases => "-f", :type => :boolean
|
310
|
-
subcommand 'delete',
|
491
|
+
method_option :force, :aliases => "-f", :type => :boolean, :default => false
|
492
|
+
subcommand 'delete', T::Delete
|
311
493
|
|
312
|
-
require 't/cli/follow'
|
313
|
-
desc "follow SUBCOMMAND ...ARGS", "Follow users."
|
314
|
-
subcommand 'follow', CLI::Follow
|
315
|
-
|
316
|
-
require 't/cli/list'
|
317
494
|
desc "list SUBCOMMAND ...ARGS", "Do various things with lists."
|
318
|
-
subcommand 'list',
|
495
|
+
subcommand 'list', T::List
|
319
496
|
|
320
|
-
require 't/cli/search'
|
321
497
|
desc "search SUBCOMMAND ...ARGS", "Search through Tweets."
|
322
|
-
|
498
|
+
method_option :long, :aliases => "-l", :type => :boolean, :default => false, :desc => "List in long format."
|
499
|
+
subcommand 'search', T::Search
|
323
500
|
|
324
|
-
require 't/cli/set'
|
325
501
|
desc "set SUBCOMMAND ...ARGS", "Change various account settings."
|
326
|
-
subcommand 'set',
|
327
|
-
|
328
|
-
require 't/cli/unfollow'
|
329
|
-
desc "unfollow SUBCOMMAND ...ARGS", "Unfollow users."
|
330
|
-
subcommand 'unfollow', CLI::Unfollow
|
502
|
+
subcommand 'set', T::Set
|
331
503
|
|
332
504
|
private
|
333
505
|
|
@@ -383,6 +555,72 @@ module T
|
|
383
555
|
{:oauth_callback => 'oob'}
|
384
556
|
end
|
385
557
|
|
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.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
|
+
|
386
624
|
def protocol
|
387
625
|
options['no_ssl'] ? 'http' : DEFAULT_PROTOCOL
|
388
626
|
end
|