t 0.4.0 → 0.5.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/.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
|