t 0.8.1 → 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +121 -103
- data/lib/t/cli.rb +12 -6
- data/lib/t/core_ext/enumerable.rb +5 -8
- data/lib/t/printable.rb +16 -9
- data/lib/t/search.rb +4 -2
- data/lib/t/version.rb +1 -1
- data/spec/cli_spec.rb +181 -181
- data/spec/helper.rb +2 -0
- data/spec/list_spec.rb +37 -37
- data/spec/search_spec.rb +100 -100
- data/t.gemspec +1 -1
- metadata +10 -4
data/README.md
CHANGED
@@ -1,159 +1,171 @@
|
|
1
1
|
# Twitter CLI [![Build Status](https://secure.travis-ci.org/sferik/t.png?branch=master)][travis] [![Dependency Status](https://gemnasium.com/sferik/t.png?travis)][gemnasium]
|
2
2
|
### A command-line power tool for Twitter.
|
3
3
|
|
4
|
-
The CLI
|
5
|
-
|
6
|
-
SMS.
|
4
|
+
The CLI takes syntactic cues from the [Twitter SMS commands][sms], however it
|
5
|
+
offers vastly more commands and capabilities than are available via SMS.
|
7
6
|
|
8
7
|
[travis]: http://travis-ci.org/sferik/t
|
9
8
|
[gemnasium]: https://gemnasium.com/sferik/t
|
10
9
|
[gem]: https://rubygems.org/gems/twitter
|
11
10
|
[sms]: https://support.twitter.com/articles/14020-twitter-sms-command
|
12
11
|
|
13
|
-
##
|
12
|
+
## Installation
|
13
|
+
# Requires Ruby :)
|
14
14
|
gem install t
|
15
15
|
|
16
|
-
##
|
16
|
+
## Configuration
|
17
17
|
|
18
|
-
|
18
|
+
Twitter requires OAuth for most of its functionality, so you'll need to
|
19
19
|
register a new application at <http://dev.twitter.com/apps/new>. Once you
|
20
|
-
create your application make sure to set
|
21
|
-
and Access direct messages", otherwise you
|
22
|
-
|
20
|
+
create your application, make sure to set your application's Access Level to
|
21
|
+
"Read, Write and Access direct messages", otherwise you may receive an error
|
22
|
+
that looks something like this:
|
23
23
|
|
24
|
-
|
25
|
-
|
24
|
+
Read-only application cannot POST
|
25
|
+
|
26
|
+
Once you've successfully registered your application, you'll be given a
|
27
|
+
consumer key and secret, which you can use to authorize your Twitter account.
|
26
28
|
|
27
29
|
t authorize -c YOUR_CONSUMER_KEY -s YOUR_CONSUMER_SECRET
|
28
30
|
|
29
|
-
This
|
30
|
-
enter the returned PIN back into the terminal.
|
31
|
-
authorized to use `t` as that user. To authorize
|
32
|
-
repeat the last step
|
31
|
+
This command directs you to a URL where you can sign-in to Twitter and then
|
32
|
+
enter the returned PIN back into the terminal. If you type the PIN correctly,
|
33
|
+
you should now be authorized authorized to use `t` as that user. To authorize
|
34
|
+
multiple accounts, simply repeat the last step, signing into Twitter as a
|
35
|
+
different user.
|
33
36
|
|
34
|
-
You can see a list of all the accounts you've authorized
|
37
|
+
You can see a list of all the accounts you've authorized by typing the command:
|
35
38
|
|
36
39
|
t accounts
|
37
40
|
|
41
|
+
The output of which will be structured like this:
|
42
|
+
|
38
43
|
sferik
|
39
44
|
UDfNTpOz5ZDG4a6w7dIWj
|
40
45
|
uuP7Xbl2mEfGMiDu1uIyFN
|
41
46
|
gem
|
42
47
|
thG9EfWoADtIr6NjbL9ON (active)
|
43
48
|
|
44
|
-
|
45
|
-
use the `set` subcommand, passing either
|
46
|
-
unambiguous, or the username and consumer key pair
|
49
|
+
**Note**: One account (specifically, the last one you authorized) is marked as
|
50
|
+
active. To change the active account use the `set` subcommand, passing either
|
51
|
+
just the username, if it's unambiguous, or the username and consumer key pair.
|
52
|
+
Something like this:
|
47
53
|
|
48
54
|
t set active sferik UDfNTpOz5ZDG4a6w7dIWj
|
49
55
|
|
50
|
-
Account information is stored in
|
51
|
-
Anyone with access to this file can masquerade as you on Twitter, so
|
52
|
-
important to keep it secure, just as you would treat your SSH private key.
|
53
|
-
this reason, the file is hidden and has the permission bits set to 0600.
|
56
|
+
Account information is stored in a YAML-formatted file located at `~/.trc`.
|
57
|
+
**Note**: Anyone with access to this file can masquerade as you on Twitter, so
|
58
|
+
it's important to keep it secure, just as you would treat your SSH private key.
|
59
|
+
For this reason, the file is hidden and has the permission bits set to 0600.
|
54
60
|
|
55
|
-
##
|
56
|
-
Typing `t help` will
|
57
|
-
|
61
|
+
## Usage Examples
|
62
|
+
Typing `t help` will list all the available commands. You can type `t help
|
63
|
+
TASK` to get help for a specific command.
|
58
64
|
|
59
65
|
t help
|
60
66
|
|
61
|
-
###
|
67
|
+
### Update your status
|
62
68
|
t update "I'm tweeting from the command line. Isn't that special?"
|
63
69
|
|
64
70
|
**Note**: If your tweet includes special characters (e.g. `!`), make sure to
|
65
71
|
wrap it in single quotes instead of double quotes, so those characters are not
|
66
|
-
interpreted by your shell. However, if you use single quotes, your Tweet
|
67
|
-
contain any apostrophes.
|
72
|
+
interpreted by your shell. (However, if you use single quotes, your Tweet
|
73
|
+
obviously can't contain any apostrophes.)
|
74
|
+
|
75
|
+
### Retrieve detailed information about a Twitter user
|
76
|
+
t whois @sferik
|
68
77
|
|
69
|
-
###
|
78
|
+
### Retrieve stats for multiple users
|
70
79
|
t users -l @sferik @gem
|
71
80
|
|
72
|
-
###
|
81
|
+
### Follow users
|
73
82
|
t follow @sferik @gem
|
74
83
|
|
75
|
-
###
|
84
|
+
### Check whether one user follows another
|
76
85
|
t does_follow @ev @sferik
|
77
86
|
|
78
|
-
**Note**: If the first user
|
79
|
-
non-zero exit code. This allows you to execute
|
80
|
-
example
|
87
|
+
**Note**: If the first user does not follow the second, `t` will exit with a
|
88
|
+
non-zero exit code. This allows you to execute commands conditionally, for
|
89
|
+
example, only attempt to send a user a direct message if he are already
|
90
|
+
follows you:
|
81
91
|
|
82
|
-
t does_follow @ev
|
92
|
+
t does_follow @ev && t dm @ev "What's up, bro?"
|
83
93
|
|
84
|
-
###
|
94
|
+
### Create a list for everyone you're following
|
95
|
+
t list create following-`date "+%Y-%m-%d"`
|
96
|
+
|
97
|
+
### Add everyone you're following to that list (up to 500 users)
|
98
|
+
t followings | xargs t list add following-`date "+%Y-%m-%d"`
|
99
|
+
|
100
|
+
### List all the members of a list, in long format
|
101
|
+
t list members -l following-`date "+%Y-%m-%d"`
|
102
|
+
|
103
|
+
### List all your lists, in long format
|
104
|
+
t lists -l
|
105
|
+
|
106
|
+
### List all your friends, ordered by number of followers
|
85
107
|
t friends -lf
|
86
108
|
|
87
|
-
###
|
109
|
+
### List all your leaders (people you follow who don't follow you back)
|
88
110
|
t leaders -lf
|
89
111
|
|
90
|
-
###
|
112
|
+
### Unfollow everyone you follow who doesn't follow you back
|
91
113
|
t leaders | xargs t unfollow
|
92
114
|
|
93
|
-
###
|
94
|
-
t disciples | xargs t follow
|
95
|
-
|
96
|
-
### <a name="follow-roulette"></a>Follow roulette: randomly follow someone who follows you
|
115
|
+
### Follow roulette: randomly follow someone who follows you (who you don't already follow)
|
97
116
|
t disciples | shuf | head -1 | xargs t follow
|
98
117
|
|
99
|
-
###
|
100
|
-
t timeline -n 200 --csv > timeline.csv
|
101
|
-
|
102
|
-
### <a name="favorite"></a>Favorite the last 10 tweets that mention you
|
118
|
+
### Favorite the last 10 tweets that mention you
|
103
119
|
t mentions -n 10 -l | awk '{print $1}' | xargs t favorite
|
104
120
|
|
105
|
-
###
|
106
|
-
t
|
107
|
-
|
108
|
-
### <a name="list-add"></a>Add users to a list
|
109
|
-
t list add presidents @BarackObama @Jasonfinn
|
110
|
-
|
111
|
-
### Create a list that contains today's date in the name
|
112
|
-
t list create following-`date "+%Y-%m-%d"`
|
113
|
-
|
114
|
-
### <a name="followings"></a>Add everyone you're following to a list
|
115
|
-
t followings | xargs t list add following-`date "+%Y-%m-%d"`
|
116
|
-
|
117
|
-
### <a name="list-members"></a>Display members of a list
|
118
|
-
t list members following-`date "+%Y-%m-%d"`
|
121
|
+
### Output the last 200 tweets in your timeline to a CSV file
|
122
|
+
t timeline -n 200 --csv > timeline.csv
|
119
123
|
|
120
|
-
###
|
124
|
+
### Count the number of employees who work for Twitter
|
121
125
|
t list members twitter team | wc -l
|
122
126
|
|
123
|
-
###
|
127
|
+
### Search Twitter for the 20 most recent Tweets that match a specified query
|
124
128
|
t search all "query"
|
125
129
|
|
126
|
-
###
|
130
|
+
### Download the latest Linux kernel via BitTorrent (possibly NSFW, depending where you work)
|
131
|
+
t search all "lang:en filter:links linux torrent" -n 1 | grep -o "http://t.co/[0-9A-Za-z]*" | xargs open
|
132
|
+
|
133
|
+
### Search Tweets you've favorited that match a specified query
|
127
134
|
t search favorites "query"
|
128
135
|
|
129
|
-
###
|
136
|
+
### Search Tweets mentioning you that match a specified query
|
130
137
|
t search mentions "query"
|
131
138
|
|
132
|
-
###
|
139
|
+
### Search Tweets you've retweeted that match a specified query
|
133
140
|
t search retweets "query"
|
134
141
|
|
135
|
-
###
|
142
|
+
### Search Tweets in your timeline that match a specified query
|
136
143
|
t search timeline "query"
|
137
144
|
|
138
|
-
###
|
145
|
+
### Search Tweets in another user's timeline that match a specified query
|
139
146
|
t search user @sferik "query"
|
140
147
|
|
141
|
-
##
|
148
|
+
## Features
|
149
|
+
* Deep search: Instead of using the Twitter Search API, [which only only goes
|
150
|
+
back 6-9 days][index], `t search` fetches up to 3,200 tweets via the REST API
|
151
|
+
and then checks each one against a regular expression.
|
142
152
|
* Multithreaded: Whenever possible, Twitter API requests are made in parallel,
|
143
153
|
resulting in faster performance for bulk operations.
|
144
|
-
* Designed for Unix:
|
145
|
-
|
146
|
-
*
|
147
|
-
|
148
|
-
|
154
|
+
* Designed for Unix: Output is designed to be piped to other Unix utilities,
|
155
|
+
like grep, cut, awk, bc, wc, and xargs for advanced text processing.
|
156
|
+
* Generate spreadsheets: Convert the output of any command to CSV format simply
|
157
|
+
by adding the `--csv` flag.
|
158
|
+
* 98% C0 Code Coverage: Well tested, with a 3:1 test-to-code ratio.
|
159
|
+
|
160
|
+
[search]: https://dev.twitter.com/docs/using-search
|
149
161
|
|
150
|
-
##
|
162
|
+
## Relationship Terminology
|
151
163
|
|
152
164
|
There is some ambiguity in the terminology used to describe relationships on
|
153
|
-
Twitter. For example, some people use the term "friends" to mean
|
154
|
-
|
155
|
-
|
156
|
-
|
165
|
+
Twitter. For example, some people use the term "friends" to mean everyone you
|
166
|
+
follow. In `t`, "friends" refers to just the subset of people who follow you
|
167
|
+
back (i.e., friendship is bidirectional). Here is the full table of terminology
|
168
|
+
used by `t`:
|
157
169
|
|
158
170
|
___________________________________________________
|
159
171
|
| | |
|
@@ -169,17 +181,20 @@ terminology used throughout `t`:
|
|
169
181
|
| followings |
|
170
182
|
|_________________________|
|
171
183
|
|
172
|
-
##
|
173
|
-
![
|
184
|
+
## Screenshots
|
185
|
+
![Timeline](https://github.com/sferik/t/raw/master/screenshots/timeline.png)
|
186
|
+
![List](https://github.com/sferik/t/raw/master/screenshots/list.png)
|
174
187
|
|
188
|
+
## History
|
175
189
|
The [twitter gem][gem] previously contained a command-line interface, up until
|
176
190
|
version 0.5.0, when it was [removed][]. This project is offered as a sucessor
|
177
191
|
to that effort, however it is a clean room implementation that contains none of
|
178
|
-
|
192
|
+
the original code.
|
179
193
|
|
180
194
|
[removed]: https://github.com/jnunemaker/twitter/commit/dd2445e3e2c97f38b28a3f32ea902536b3897adf
|
195
|
+
![History](https://github.com/sferik/t/raw/master/screenshots/history.png)
|
181
196
|
|
182
|
-
##
|
197
|
+
## Contributing
|
183
198
|
In the spirit of [free software][fsf], **everyone** is encouraged to help
|
184
199
|
improve this project.
|
185
200
|
|
@@ -200,7 +215,7 @@ Here are some ways *you* can contribute:
|
|
200
215
|
|
201
216
|
[issues]: https://github.com/sferik/t/issues
|
202
217
|
|
203
|
-
##
|
218
|
+
## Submitting an Issue
|
204
219
|
We use the [GitHub issue tracker][issues] to track bugs and features. Before
|
205
220
|
submitting a bug report or feature request, check to make sure it hasn't
|
206
221
|
already been submitted. You can indicate support for an existing issue by
|
@@ -211,19 +226,23 @@ bug report should include a pull request with failing specs.
|
|
211
226
|
|
212
227
|
[gist]: https://gist.github.com/
|
213
228
|
|
214
|
-
##
|
215
|
-
1. Fork the
|
216
|
-
2. Create a topic branch.
|
217
|
-
3.
|
218
|
-
4.
|
219
|
-
5.
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
229
|
+
## Submitting a Pull Request
|
230
|
+
1. [Fork the repository.][fork]
|
231
|
+
2. [Create a topic branch.][branch]
|
232
|
+
3. Add specs for your unimplemented feature or bug fix.
|
233
|
+
4. Run `bundle exec rake spec`. If your specs pass, return to step 3.
|
234
|
+
5. Implement your feature or bug fix.
|
235
|
+
6. Run `bundle exec rake spec`. If your specs fail, return to step 5.
|
236
|
+
7. Run `open coverage/index.html`. If your changes are not completely covered
|
237
|
+
by your tests, return to step 3.
|
238
|
+
6. Add, commit, and push your changes.
|
239
|
+
7. [Submit a pull request.][pr]
|
240
|
+
|
241
|
+
[fork]: http://help.github.com/fork-a-repo/
|
242
|
+
[branch]: http://learn.github.com/p/branching.html
|
243
|
+
[pr]: http://help.github.com/send-pull-requests/
|
244
|
+
|
245
|
+
## Supported Ruby Versions
|
227
246
|
This library aims to support and is [tested against][travis] the following Ruby
|
228
247
|
implementations:
|
229
248
|
|
@@ -234,8 +253,7 @@ implementations:
|
|
234
253
|
|
235
254
|
[rubinius]: http://rubini.us/
|
236
255
|
|
237
|
-
If something doesn't work on one of these
|
238
|
-
a bug.
|
256
|
+
If something doesn't work on one of these Ruby versions, it's a bug.
|
239
257
|
|
240
258
|
This library may inadvertently work (or seem to work) on other Ruby
|
241
259
|
implementations, however support will only be provided for the versions listed
|
@@ -244,11 +262,11 @@ above.
|
|
244
262
|
If you would like this library to support another Ruby version, you may
|
245
263
|
volunteer to be a maintainer. Being a maintainer entails making sure all tests
|
246
264
|
run and pass on that implementation. When something breaks on your
|
247
|
-
implementation, you will be
|
248
|
-
|
249
|
-
|
265
|
+
implementation, you will be responsible for providing patches in a timely
|
266
|
+
fashion. If critical issues for a particular implementation exist at the time
|
267
|
+
of a major release, support for that Ruby version may be dropped.
|
250
268
|
|
251
|
-
##
|
269
|
+
## Copyright
|
252
270
|
Copyright (c) 2011 Erik Michaels-Ober. See [LICENSE][] for details.
|
253
271
|
|
254
272
|
[license]: https://github.com/sferik/t/blob/master/LICENSE.md
|
data/lib/t/cli.rb
CHANGED
@@ -142,13 +142,15 @@ module T
|
|
142
142
|
elsif options['long']
|
143
143
|
array = direct_messages.map do |direct_message|
|
144
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
|
145
|
+
[direct_message.id, created_at, "@#{direct_message.sender.screen_name}", direct_message.text.gsub(/\n+/, ' ')]
|
146
146
|
end
|
147
147
|
if STDOUT.tty?
|
148
148
|
headings = ["ID", "Posted at", "Screen name", "Text"]
|
149
149
|
array.unshift(headings) unless direct_messages.empty?
|
150
|
+
print_table(array, :truncate => true)
|
151
|
+
else
|
152
|
+
print_table(array)
|
150
153
|
end
|
151
|
-
print_table(array)
|
152
154
|
else
|
153
155
|
direct_messages.each do |direct_message|
|
154
156
|
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)"
|
@@ -174,13 +176,15 @@ module T
|
|
174
176
|
elsif options['long']
|
175
177
|
array = direct_messages.map do |direct_message|
|
176
178
|
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")
|
177
|
-
[direct_message.id
|
179
|
+
[direct_message.id, created_at, "@#{direct_message.recipient.screen_name}", direct_message.text.gsub(/\n+/, ' ')]
|
178
180
|
end
|
179
181
|
if STDOUT.tty?
|
180
182
|
headings = ["ID", "Posted at", "Screen name", "Text"]
|
181
183
|
array.unshift(headings) unless direct_messages.empty?
|
184
|
+
print_table(array, :truncate => true)
|
185
|
+
else
|
186
|
+
print_table(array)
|
182
187
|
end
|
183
|
-
print_table(array)
|
184
188
|
else
|
185
189
|
direct_messages.each do |direct_message|
|
186
190
|
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)"
|
@@ -727,13 +731,15 @@ module T
|
|
727
731
|
end
|
728
732
|
elsif options['long']
|
729
733
|
array = places.map do |place|
|
730
|
-
[place.woeid
|
734
|
+
[place.woeid, place.parent_id, place.place_type, place.name, place.country]
|
731
735
|
end
|
732
736
|
if STDOUT.tty?
|
733
737
|
headings = ["WOEID", "Parent ID", "Type", "Name", "Country"]
|
734
738
|
array.unshift(headings) unless places.empty?
|
739
|
+
print_table(array, :truncate => true)
|
740
|
+
else
|
741
|
+
print_table(array)
|
735
742
|
end
|
736
|
-
print_table(array)
|
737
743
|
else
|
738
744
|
if STDOUT.tty?
|
739
745
|
print_in_columns(places.map(&:name))
|
@@ -2,21 +2,18 @@ module Enumerable
|
|
2
2
|
|
3
3
|
def threaded_each
|
4
4
|
threads = []
|
5
|
-
|
5
|
+
each do |object|
|
6
6
|
threads << Thread.new{yield object}
|
7
7
|
end
|
8
|
-
threads.each(&:
|
9
|
-
result
|
8
|
+
threads.each(&:value)
|
10
9
|
end
|
11
10
|
|
12
11
|
def threaded_map
|
13
|
-
results = map{nil}
|
14
12
|
threads = []
|
15
|
-
|
16
|
-
threads << Thread.new{
|
13
|
+
each do |object|
|
14
|
+
threads << Thread.new{yield object}
|
17
15
|
end
|
18
|
-
threads.
|
19
|
-
results
|
16
|
+
threads.map(&:value)
|
20
17
|
end
|
21
18
|
|
22
19
|
end
|
data/lib/t/printable.rb
CHANGED
@@ -44,13 +44,15 @@ module T
|
|
44
44
|
elsif options['long']
|
45
45
|
array = lists.map do |list|
|
46
46
|
created_at = list.created_at > 6.months.ago ? list.created_at.strftime("%b %e %H:%M") : list.created_at.strftime("%b %e %Y")
|
47
|
-
[list.id
|
47
|
+
[list.id, created_at, list.full_name, number_with_delimiter(list.member_count), number_with_delimiter(list.subscriber_count), list.mode, list.description]
|
48
48
|
end
|
49
49
|
if STDOUT.tty?
|
50
50
|
headings = ["ID", "Created at", "Slug", "Members", "Subscribers", "Mode", "Description"]
|
51
51
|
array.unshift(headings) unless lists.empty?
|
52
|
+
print_table(array, :truncate => true)
|
53
|
+
else
|
54
|
+
print_table(array)
|
52
55
|
end
|
53
|
-
print_table(array)
|
54
56
|
else
|
55
57
|
if STDOUT.tty?
|
56
58
|
print_in_columns(lists.map(&:full_name))
|
@@ -72,26 +74,29 @@ module T
|
|
72
74
|
elsif options['long']
|
73
75
|
array = statuses.map do |status|
|
74
76
|
created_at = status.created_at > 6.months.ago ? status.created_at.strftime("%b %e %H:%M") : status.created_at.strftime("%b %e %Y")
|
75
|
-
[status.id
|
77
|
+
[status.id, created_at, "@#{status.user.screen_name}", status.text.gsub(/\n+/, ' ')]
|
76
78
|
end
|
77
79
|
if STDOUT.tty?
|
78
80
|
headings = ["ID", "Posted at", "Screen name", "Text"]
|
79
81
|
array.unshift(headings) unless statuses.empty?
|
82
|
+
print_table(array, :truncate => true)
|
83
|
+
else
|
84
|
+
print_table(array)
|
80
85
|
end
|
81
|
-
print_table(array)
|
82
86
|
else
|
83
|
-
ENV['THOR_COLUMNS'] = "80"
|
84
87
|
if STDOUT.tty? && !options['no-color']
|
88
|
+
say unless statuses.empty?
|
85
89
|
statuses.each do |status|
|
86
90
|
say(" #{Thor::Shell::Color::BOLD}@#{status.user.screen_name}", :yellow)
|
87
|
-
|
91
|
+
print_wrapped(status.text, :indent => 3)
|
88
92
|
say(" #{Thor::Shell::Color::BOLD}#{time_ago_in_words(status.created_at)} ago", :black)
|
89
93
|
say
|
90
94
|
end
|
91
95
|
else
|
96
|
+
say unless statuses.empty?
|
92
97
|
statuses.each do |status|
|
93
98
|
say(" @#{status.user.screen_name}")
|
94
|
-
|
99
|
+
print_wrapped(status.text, :indent => 3)
|
95
100
|
say(" #{time_ago_in_words(status.created_at)} ago")
|
96
101
|
say
|
97
102
|
end
|
@@ -123,13 +128,15 @@ module T
|
|
123
128
|
elsif options['long']
|
124
129
|
array = users.map do |user|
|
125
130
|
created_at = user.created_at > 6.months.ago ? user.created_at.strftime("%b %e %H:%M") : user.created_at.strftime("%b %e %Y")
|
126
|
-
[user.id
|
131
|
+
[user.id, created_at, number_with_delimiter(user.statuses_count), number_with_delimiter(user.favourites_count), number_with_delimiter(user.listed_count), number_with_delimiter(user.friends_count), number_with_delimiter(user.followers_count), "@#{user.screen_name}", user.name]
|
127
132
|
end
|
128
133
|
if STDOUT.tty?
|
129
134
|
headings = ["ID", "Since", "Tweets", "Favorites", "Listed", "Following", "Followers", "Screen name", "Name"]
|
130
135
|
array.unshift(headings) unless users.empty?
|
136
|
+
print_table(array, :truncate => true)
|
137
|
+
else
|
138
|
+
print_table(array)
|
131
139
|
end
|
132
|
-
print_table(array)
|
133
140
|
else
|
134
141
|
if STDOUT.tty?
|
135
142
|
print_in_columns(users.map{|user| "@#{user.screen_name}"})
|