t 2.0.1 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.sig CHANGED
Binary file
data/CONTRIBUTING.md CHANGED
@@ -37,7 +37,7 @@ Ideally, a bug report should include a pull request with failing specs.
37
37
  3. Add specs for your unimplemented feature or bug fix.
38
38
  4. Run `bundle exec rake spec`. If your specs pass, return to step 3.
39
39
  5. Implement your feature or bug fix.
40
- 6. Run `bundle exec rake spec`. If your specs fail, return to step 5.
40
+ 6. Run `bundle exec rake default`. If your specs fail, return to step 5.
41
41
  7. Run `open coverage/index.html`. If your changes are not completely covered
42
42
  by your tests, return to step 3.
43
43
  8. Add, commit, and push your changes.
data/README.md CHANGED
@@ -15,7 +15,7 @@
15
15
  [gittip]: https://www.gittip.com/sferik/
16
16
 
17
17
  #### A command-line power tool for Twitter.
18
- The CLI takes syntactic cues from the [Twitter SMS commands][sms], however it
18
+ The CLI takes syntactic cues from the [Twitter SMS commands][sms], but it
19
19
  offers vastly more commands and capabilities than are available via SMS.
20
20
 
21
21
  [sms]: https://support.twitter.com/articles/14020-twitter-sms-command
@@ -29,7 +29,7 @@ First, make sure you have Ruby installed.
29
29
 
30
30
  If the output looks something like this, you're in good shape:
31
31
 
32
- ruby 1.9.3p385 (2013-02-06 revision 39114) [x86_64-darwin12.2.1]
32
+ ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-darwin13.0.0]
33
33
 
34
34
  If the output looks more like this, you need to [install Ruby][ruby]:
35
35
  [ruby]: http://www.ruby-lang.org/en/downloads/
@@ -59,14 +59,14 @@ public key as a trusted certificate (you only need to do this once):
59
59
 
60
60
  gem cert --add <(curl -Ls https://raw.github.com/sferik/t/master/certs/sferik.pem)
61
61
 
62
- Then, install the gem with the high security trust policy:
62
+ Then, install the gem with the medium security trust policy:
63
63
 
64
- gem install t -P HighSecurity
64
+ gem install t -P MediumSecurity
65
65
 
66
66
  ## Configuration
67
67
  Twitter API v1.1 requires OAuth for all of its functionality, so you'll need a
68
68
  registered Twitter application. If you've never registered a Twitter
69
- application before, it's easy! Just sign-in using your Twitter account and the
69
+ application before, it's easy! Just sign-in using your Twitter account and then
70
70
  fill out the short form at <http://dev.twitter.com/apps/new>. If you've
71
71
  previously registered a Twitter application, it should be listed at
72
72
  <http://dev.twitter.com/apps>. Once you've registered an application, make sure
@@ -138,8 +138,8 @@ obviously can't contain any apostrophes.)
138
138
  t does_follow @ev @sferik
139
139
 
140
140
  **Note**: If the first user does not follow the second, `t` will exit with a
141
- non-zero exit code. This allows you to execute commands conditionally, for
142
- example, send a user a direct message only if he already follows you:
141
+ non-zero exit code. This allows you to execute commands conditionally. For
142
+ example, here's how to send a user a direct message only if they already follow you:
143
143
 
144
144
  t does_follow @ev && t dm @ev "What's up, bro?"
145
145
 
@@ -179,13 +179,13 @@ example, send a user a direct message only if he already follows you:
179
179
  #### Start streaming your timeline (Control-C to stop)
180
180
  t stream timeline
181
181
 
182
- #### Count the number of employees who work for Twitter
183
- t list members twitter/team | wc -l
182
+ #### Count the number of official Twitter engineering accounts
183
+ t list members twitter/engineering | wc -l
184
184
 
185
185
  #### Search Twitter for the 20 most recent Tweets that match a specified query
186
186
  t search all "query"
187
187
 
188
- #### Download the latest Linux kernel via BitTorrent (possibly NSFW, depending where you work)
188
+ #### Download the latest Linux kernel via BitTorrent (possibly NSFW, depending on where you work)
189
189
  t search all "lang:en filter:links linux torrent" -n 1 | grep -o "http://t.co/[0-9A-Za-z]*" | xargs open
190
190
 
191
191
  #### Search Tweets you've favorited that match a specified query
@@ -204,7 +204,7 @@ example, send a user a direct message only if he already follows you:
204
204
  t search timeline @sferik "query"
205
205
 
206
206
  ## Features
207
- * Deep search: Instead of using the Twitter Search API, [which only only goes
207
+ * Deep search: Instead of using the Twitter Search API, [which only goes
208
208
  back 6-9 days][search], `t search` fetches up to 3,200 tweets via the REST API
209
209
  and then checks each one against a regular expression.
210
210
  * Multi-threaded: Whenever possible, Twitter API requests are made in parallel,
@@ -275,7 +275,7 @@ shell?
275
275
 
276
276
  ## History
277
277
  The [twitter gem][gem] previously contained a command-line interface, up until
278
- version 0.5.0, when it was [removed][]. This project is offered as a sucessor
278
+ version 0.5.0, when it was [removed][]. This project is offered as a successor
279
279
  to that effort, however it is a clean room implementation that contains none of
280
280
  the original code.
281
281
 
data/Rakefile CHANGED
@@ -4,8 +4,18 @@ Bundler::GemHelper.install_tasks
4
4
  require 'rspec/core/rake_task'
5
5
  RSpec::Core::RakeTask.new(:spec)
6
6
 
7
+ begin
8
+ require 'rubocop/rake_task'
9
+ Rubocop::RakeTask.new
10
+ rescue LoadError
11
+ desc 'Run RuboCop'
12
+ task :rubocop do
13
+ $stderr.puts 'Rubocop is disabled'
14
+ end
15
+ end
16
+
7
17
  Dir.glob('tasks/*.rake').each { |r| import r }
8
18
 
9
19
  task :release => 'completion:zsh'
10
20
  task :test => :spec
11
- task :default => :spec
21
+ task :default => [:spec, :rubocop]
data/bin/t CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Trap interrupts to quit cleanly. See
4
4
  # https://twitter.com/mitchellh/status/283014103189053442
5
- Signal.trap("INT") { exit 1 }
5
+ Signal.trap('INT') { exit 1 }
6
6
 
7
7
  require 'oauth'
8
8
  require 't'
@@ -11,7 +11,7 @@ require 'twitter'
11
11
  # Output message to $stderr, prefixed with the program name
12
12
  def pute(*args)
13
13
  first = args.shift.dup
14
- first.insert(0, "#{$0}: ")
14
+ first.insert(0, "#{$PROGRAM_NAME}: ")
15
15
  args.unshift(first)
16
16
  $stderr.puts(*args)
17
17
  end
@@ -19,29 +19,29 @@ end
19
19
  begin
20
20
  T::CLI.start(ARGV)
21
21
  rescue Interrupt
22
- pute "Quitting..."
22
+ pute 'Quitting...'
23
23
  exit 1
24
24
  rescue OAuth::Unauthorized
25
- pute "Authorization failed"
25
+ pute 'Authorization failed'
26
26
  exit 1
27
27
  rescue Twitter::Error::TooManyRequests => error
28
28
  pute error.message,
29
- "The rate limit for this request will reset in #{error.rate_limit.reset_in} seconds.",
30
- "While you wait, consider making a polite request for Twitter to increase the API rate limit at https://dev.twitter.com/discussions/10644"
29
+ "The rate limit for this request will reset in #{error.rate_limit.reset_in} seconds.",
30
+ 'While you wait, consider making a polite request for Twitter to increase the API rate limit at https://dev.twitter.com/discussions/10644'
31
31
  exit 1
32
32
  rescue Twitter::Error::BadRequest => error
33
33
  pute error.message,
34
- "Run `t authorize` to authorize."
34
+ 'Run `t authorize` to authorize.'
35
35
  exit 1
36
36
  rescue Twitter::Error::Forbidden, Twitter::Error::Unauthorized => error
37
37
  pute error.message
38
- if error.message == "Error processing your OAuth request: Read-only application cannot POST" ||
39
- error.message == "This application is not allowed to access or delete your direct messages"
38
+ if error.message == 'Error processing your OAuth request: Read-only application cannot POST' ||
39
+ error.message == 'This application is not allowed to access or delete your direct messages'
40
40
  $stderr.puts(%q(Make sure to set your Twitter application's Access Level to "Read, Write and Access direct messages".))
41
41
  require 'thor'
42
- Thor::Shell::Basic.new.ask "Press [Enter] to open the Twitter Developer site."
42
+ Thor::Shell::Basic.new.ask 'Press [Enter] to open the Twitter Developer site.'
43
43
  require 'launchy'
44
- Launchy.open("https://dev.twitter.com/apps") { |u,o,e| $stderr.puts "Manually open #{u}" }
44
+ Launchy.open('https://dev.twitter.com/apps') { |u, o, e| $stderr.puts "Manually open #{u}" }
45
45
  end
46
46
  exit 1
47
47
  rescue Twitter::Error => error
data/lib/t.rb CHANGED
@@ -3,7 +3,6 @@ require 'time'
3
3
 
4
4
  module T
5
5
  class << self
6
-
7
6
  # Convert time to local time by applying the `utc_offset` setting.
8
7
  def local_time(time)
9
8
  utc_offset ? (time.dup.utc + utc_offset) : time.localtime
@@ -15,14 +14,13 @@ module T
15
14
 
16
15
  def utc_offset=(offset)
17
16
  @utc_offset = case offset
18
- when String
19
- Time.zone_offset(offset)
20
- when NilClass
21
- nil
22
- else
23
- offset.to_i
24
- end
17
+ when String
18
+ Time.zone_offset(offset)
19
+ when NilClass
20
+ nil
21
+ else
22
+ offset.to_i
23
+ end
25
24
  end
26
-
27
25
  end
28
26
  end
data/lib/t/cli.rb CHANGED
@@ -24,20 +24,20 @@ module T
24
24
  include T::Utils
25
25
 
26
26
  DEFAULT_NUM_RESULTS = 20
27
- DIRECT_MESSAGE_HEADINGS = ["ID", "Posted at", "Screen name", "Text"]
28
- TREND_HEADINGS = ["WOEID", "Parent ID", "Type", "Name", "Country"]
27
+ DIRECT_MESSAGE_HEADINGS = ['ID', 'Posted at', 'Screen name', 'Text']
28
+ TREND_HEADINGS = ['WOEID', 'Parent ID', 'Type', 'Name', 'Country']
29
29
 
30
30
  check_unknown_options!
31
31
 
32
- class_option "color", :aliases => "-C", :type => :string, :enum => %w(auto never), :default => "auto", :desc => "Control how color is used in output"
33
- class_option "profile", :aliases => "-P", :type => :string, :default => File.join(File.expand_path("~"), T::RCFile::FILE_NAME), :desc => "Path to RC file", :banner => "FILE"
32
+ class_option 'color', :aliases => '-C', :type => :string, :enum => %w(auto never), :default => 'auto', :desc => 'Control how color is used in output'
33
+ class_option 'profile', :aliases => '-P', :type => :string, :default => File.join(File.expand_path('~'), T::RCFile::FILE_NAME), :desc => 'Path to RC file', :banner => 'FILE'
34
34
 
35
35
  def initialize(*)
36
36
  @rcfile = T::RCFile.instance
37
37
  super
38
38
  end
39
39
 
40
- desc "accounts", "List accounts"
40
+ desc 'accounts', 'List accounts'
41
41
  def accounts
42
42
  @rcfile.path = options['profile'] if options['profile']
43
43
  @rcfile.profiles.each do |profile|
@@ -48,53 +48,53 @@ module T
48
48
  end
49
49
  end
50
50
 
51
- desc "authorize", "Allows an application to request user authorization"
52
- method_option "display-uri", :aliases => "-d", :type => :boolean, :default => false, :desc => "Display the authorization URL instead of attempting to open it."
51
+ desc 'authorize', 'Allows an application to request user authorization'
52
+ method_option 'display-uri', :aliases => '-d', :type => :boolean, :default => false, :desc => 'Display the authorization URL instead of attempting to open it.'
53
53
  def authorize
54
54
  @rcfile.path = options['profile'] if options['profile']
55
55
  if @rcfile.empty?
56
56
  say "Welcome! Before you can use t, you'll first need to register an"
57
- say "application with Twitter. Just follow the steps below:"
58
- say " 1. Sign in to the Twitter Developer site and click"
57
+ say 'application with Twitter. Just follow the steps below:'
58
+ say ' 1. Sign in to the Twitter Developer site and click'
59
59
  say " \"Create a new application\"."
60
- say " 2. Complete the required fields and submit the form."
61
- say " Note: Your application must have a unique name."
60
+ say ' 2. Complete the required fields and submit the form.'
61
+ say ' Note: Your application must have a unique name.'
62
62
  say " We recommend: \"<your handle>/t\"."
63
- say " 3. Go to the Settings tab of your application, and change the"
63
+ say ' 3. Go to the Settings tab of your application, and change the'
64
64
  say " Access setting to \"Read, Write and Access direct messages\"."
65
- say " 4. Go to the Details tab to view the consumer key and secret,"
65
+ say ' 4. Go to the Details tab to view the consumer key and secret,'
66
66
  say " which you'll need to copy and paste below when prompted."
67
67
  say
68
- ask "Press [Enter] to open the Twitter Developer site."
68
+ ask 'Press [Enter] to open the Twitter Developer site.'
69
69
  say
70
70
  else
71
71
  say "It looks like you've already registered an application with Twitter."
72
- say "To authorize a new account, just follow the steps below:"
73
- say " 1. Sign in to the Twitter Developer site."
72
+ say 'To authorize a new account, just follow the steps below:'
73
+ say ' 1. Sign in to the Twitter Developer site.'
74
74
  say " 2. Select the application for which you'd like to authorize an account."
75
- say " 3. Copy and paste the consumer key and secret below when prompted."
75
+ say ' 3. Copy and paste the consumer key and secret below when prompted.'
76
76
  say
77
- ask "Press [Enter] to open the Twitter Developer site."
77
+ ask 'Press [Enter] to open the Twitter Developer site.'
78
78
  say
79
79
  end
80
80
  require 'launchy'
81
- open_or_print( "https://dev.twitter.com/apps", :dry_run => options['display-uri'] )
82
- key = ask "Enter your consumer key:"
83
- secret = ask "Enter your consumer secret:"
81
+ open_or_print('https://dev.twitter.com/apps', :dry_run => options['display-uri'])
82
+ key = ask 'Enter your consumer key:'
83
+ secret = ask 'Enter your consumer secret:'
84
84
  consumer = OAuth::Consumer.new(key, secret, :site => Twitter::REST::Client::ENDPOINT)
85
85
  request_token = consumer.get_request_token
86
86
  uri = generate_authorize_uri(consumer, request_token)
87
87
  say
88
- say "In a moment, you will be directed to the Twitter app authorization page."
89
- say "Perform the following steps to complete the authorization process:"
90
- say " 1. Sign in to Twitter."
88
+ say 'In a moment, you will be directed to the Twitter app authorization page.'
89
+ say 'Perform the following steps to complete the authorization process:'
90
+ say ' 1. Sign in to Twitter.'
91
91
  say " 2. Press \"Authorize app\"."
92
- say " 3. Copy and paste the supplied PIN below when prompted."
92
+ say ' 3. Copy and paste the supplied PIN below when prompted.'
93
93
  say
94
- ask "Press [Enter] to open the Twitter app authorization page."
94
+ ask 'Press [Enter] to open the Twitter app authorization page.'
95
95
  say
96
96
  open_or_print(uri, :dry_run => options['display-uri'])
97
- pin = ask "Enter the supplied PIN:"
97
+ pin = ask 'Enter the supplied PIN:'
98
98
  access_token = request_token.get_access_token(:oauth_verifier => pin.chomp)
99
99
  oauth_response = access_token.get('/1.1/account/verify_credentials.json?include_entities=false&skip_status=true')
100
100
  screen_name = oauth_response.body.match(/"screen_name"\s*:\s*"(.*?)"/).captures.first
@@ -108,25 +108,25 @@ module T
108
108
  }
109
109
  }
110
110
  @rcfile.active_profile = {'username' => screen_name, 'consumer_key' => key}
111
- say "Authorization successful."
111
+ say 'Authorization successful.'
112
112
  end
113
113
 
114
- desc "block USER [USER...]", "Block users."
115
- method_option "id", :aliases => "-i", :type => :boolean, :default => false, :desc => "Specify input as Twitter user IDs instead of screen names."
114
+ desc 'block USER [USER...]', 'Block users.'
115
+ method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify input as Twitter user IDs instead of screen names.'
116
116
  def block(user, *users)
117
- users, number = fetch_users(users.unshift(user), options) do |users|
118
- client.block(users)
117
+ blocked_users, number = fetch_users(users.unshift(user), options) do |users_to_block|
118
+ client.block(users_to_block)
119
119
  end
120
120
  say "@#{@rcfile.active_profile[0]} blocked #{pluralize(number, 'user')}."
121
121
  say
122
- say "Run `#{File.basename($0)} delete block #{users.map{|user| "@#{user.screen_name}"}.join(' ')}` to unblock."
122
+ say "Run `#{File.basename($PROGRAM_NAME)} delete block #{blocked_users.map { |blocked_user| "@#{blocked_user.screen_name}" }.join(' ')}` to unblock."
123
123
  end
124
124
 
125
- desc "direct_messages", "Returns the #{DEFAULT_NUM_RESULTS} most recent Direct Messages sent to you."
126
- method_option "csv", :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
127
- method_option "long", :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
128
- method_option "number", :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => "Limit the number of results."
129
- method_option "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
125
+ desc 'direct_messages', "Returns the #{DEFAULT_NUM_RESULTS} most recent Direct Messages sent to you."
126
+ method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
127
+ method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
128
+ method_option 'number', :aliases => '-n', :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => 'Limit the number of results.'
129
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
130
130
  def direct_messages
131
131
  count = options['number'] || DEFAULT_NUM_RESULTS
132
132
  direct_messages = collect_with_count(count) do |count_opts|
@@ -144,7 +144,7 @@ module T
144
144
  array = direct_messages.map do |direct_message|
145
145
  [direct_message.id, ls_formatted_time(direct_message), "@#{direct_message.sender.screen_name}", HTMLEntities.new.decode(direct_message.text).gsub(/\n+/, ' ')]
146
146
  end
147
- format = options['format'] || DIRECT_MESSAGE_HEADINGS.size.times.map{"%s"}
147
+ format = options['format'] || DIRECT_MESSAGE_HEADINGS.size.times.map { '%s' }
148
148
  print_table_with_headings(array, DIRECT_MESSAGE_HEADINGS, format)
149
149
  else
150
150
  direct_messages.each do |direct_message|
@@ -154,11 +154,11 @@ module T
154
154
  end
155
155
  map %w(directmessages dms) => :direct_messages
156
156
 
157
- desc "direct_messages_sent", "Returns the #{DEFAULT_NUM_RESULTS} most recent Direct Messages you've sent."
158
- method_option "csv", :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
159
- method_option "long", :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
160
- method_option "number", :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => "Limit the number of results."
161
- method_option "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
157
+ desc 'direct_messages_sent', "Returns the #{DEFAULT_NUM_RESULTS} most recent Direct Messages you've sent."
158
+ method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
159
+ method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
160
+ method_option 'number', :aliases => '-n', :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => 'Limit the number of results.'
161
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
162
162
  def direct_messages_sent
163
163
  count = options['number'] || DEFAULT_NUM_RESULTS
164
164
  direct_messages = collect_with_count(count) do |count_opts|
@@ -176,7 +176,7 @@ module T
176
176
  array = direct_messages.map do |direct_message|
177
177
  [direct_message.id, ls_formatted_time(direct_message), "@#{direct_message.recipient.screen_name}", HTMLEntities.new.decode(direct_message.text).gsub(/\n+/, ' ')]
178
178
  end
179
- format = options['format'] || DIRECT_MESSAGE_HEADINGS.size.times.map{"%s"}
179
+ format = options['format'] || DIRECT_MESSAGE_HEADINGS.size.times.map { '%s' }
180
180
  print_table_with_headings(array, DIRECT_MESSAGE_HEADINGS, format)
181
181
  else
182
182
  direct_messages.each do |direct_message|
@@ -186,24 +186,20 @@ module T
186
186
  end
187
187
  map %w(directmessagessent sent_messages sentmessages sms) => :direct_messages_sent
188
188
 
189
- desc "groupies [USER]", "Returns the list of people who follow you but you don't follow back."
190
- method_option "csv", :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
191
- method_option "id", :aliases => "-i", :type => :boolean, :default => false, :desc => "Specify user via ID instead of screen name."
192
- method_option "long", :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
193
- method_option "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
194
- method_option "sort", :aliases => "-s", :type => :string, :enum => %w(favorites followers friends listed screen_name since tweets tweeted), :default => "screen_name", :desc => "Specify the order of the results.", :banner => "ORDER"
195
- method_option "unsorted", :aliases => "-u", :type => :boolean, :default => false, :desc => "Output is not sorted."
196
- def groupies(user=nil)
189
+ desc 'groupies [USER]', "Returns the list of people who follow you but you don't follow back."
190
+ method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
191
+ method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
192
+ method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
193
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
194
+ method_option 'sort', :aliases => '-s', :type => :string, :enum => %w(favorites followers friends listed screen_name since tweets tweeted), :default => 'screen_name', :desc => 'Specify the order of the results.', :banner => 'ORDER'
195
+ method_option 'unsorted', :aliases => '-u', :type => :boolean, :default => false, :desc => 'Output is not sorted.'
196
+ def groupies(user = nil)
197
197
  user = if user
198
- require 't/core_ext/string'
199
- if options['id']
200
- user.to_i
201
- else
202
- user.strip_ats
203
- end
204
- else
205
- client.verify_credentials.screen_name
206
- end
198
+ require 't/core_ext/string'
199
+ options['id'] ? user.to_i : user.strip_ats
200
+ else
201
+ client.verify_credentials.screen_name
202
+ end
207
203
  follower_ids = Thread.new do
208
204
  client.follower_ids(user).to_a
209
205
  end
@@ -219,33 +215,25 @@ module T
219
215
  end
220
216
  map %w(disciples) => :groupies
221
217
 
222
- desc "dm USER MESSAGE", "Sends that person a Direct Message."
223
- method_option "id", :aliases => "-i", :type => :boolean, :default => false, :desc => "Specify user via ID instead of screen name."
218
+ desc 'dm USER MESSAGE', 'Sends that person a Direct Message.'
219
+ method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
224
220
  def dm(user, message)
225
221
  require 't/core_ext/string'
226
- user = if options['id']
227
- user.to_i
228
- else
229
- user.strip_ats
230
- end
231
- direct_message = client.direct_message_create(user, message)
222
+ user = options['id'] ? user.to_i : user.strip_ats
223
+ direct_message = client.create_direct_message(user, message)
232
224
  say "Direct Message sent from @#{@rcfile.active_profile[0]} to @#{direct_message.recipient.screen_name}."
233
225
  end
234
226
  map %w(d m) => :dm
235
227
 
236
- desc "does_contain [USER/]LIST USER", "Find out whether a list contains a user."
237
- method_option "id", :aliases => "-i", :type => :boolean, :default => false, :desc => "Specify user via ID instead of screen name."
238
- def does_contain(list, user=nil)
228
+ desc 'does_contain [USER/]LIST USER', 'Find out whether a list contains a user.'
229
+ method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
230
+ def does_contain(list, user = nil)
239
231
  owner, list = extract_owner(list, options)
240
232
  if user.nil?
241
233
  user = @rcfile.active_profile[0]
242
234
  else
243
235
  require 't/core_ext/string'
244
- user = if options['id']
245
- user = client.user(user.to_i).screen_name
246
- else
247
- user.strip_ats
248
- end
236
+ user = options['id'] ? client.user(user.to_i).screen_name : user.strip_ats
249
237
  end
250
238
  if client.list_member?(owner, list, user)
251
239
  say "Yes, #{list} contains @#{user}."
@@ -256,23 +244,15 @@ module T
256
244
  end
257
245
  map %w(dc doescontain) => :does_contain
258
246
 
259
- desc "does_follow USER [USER]", "Find out whether one user follows another."
260
- method_option "id", :aliases => "-i", :type => :boolean, :default => false, :desc => "Specify user via ID instead of screen name."
261
- def does_follow(user1, user2=nil)
247
+ desc 'does_follow USER [USER]', 'Find out whether one user follows another.'
248
+ method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
249
+ def does_follow(user1, user2 = nil)
262
250
  require 't/core_ext/string'
263
- user1 = if options['id']
264
- client.user(user1.to_i).screen_name
265
- else
266
- user1.strip_ats
267
- end
251
+ user1 = options['id'] ? client.user(user1.to_i).screen_name : user1.strip_ats
268
252
  if user2.nil?
269
253
  user2 = @rcfile.active_profile[0]
270
254
  else
271
- user2 = if options['id']
272
- client.user(user2.to_i).screen_name
273
- else
274
- user2.strip_ats
275
- end
255
+ user2 = options['id'] ? client.user(user2.to_i).screen_name : user2.strip_ats
276
256
  end
277
257
  if client.friendship?(user1, user2)
278
258
  say "Yes, @#{user1} follows @#{user2}."
@@ -283,7 +263,7 @@ module T
283
263
  end
284
264
  map %w(df doesfollow) => :does_follow
285
265
 
286
- desc "favorite TWEET_ID [TWEET_ID...]", "Marks Tweets as favorites."
266
+ desc 'favorite TWEET_ID [TWEET_ID...]', 'Marks Tweets as favorites.'
287
267
  def favorite(status_id, *status_ids)
288
268
  status_ids.unshift(status_id)
289
269
  status_ids.map!(&:to_i)
@@ -294,19 +274,19 @@ module T
294
274
  number = favorites.length
295
275
  say "@#{@rcfile.active_profile[0]} favorited #{pluralize(number, 'tweet')}."
296
276
  say
297
- say "Run `#{File.basename($0)} delete favorite #{status_ids.join(' ')}` to unfavorite."
277
+ say "Run `#{File.basename($PROGRAM_NAME)} delete favorite #{status_ids.join(' ')}` to unfavorite."
298
278
  end
299
279
  map %w(fave favourite) => :favorite
300
280
 
301
- desc "favorites [USER]", "Returns the #{DEFAULT_NUM_RESULTS} most recent Tweets you favorited."
302
- method_option "csv", :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
303
- method_option "id", :aliases => "-i", :type => :boolean, :default => false, :desc => "Specify user via ID instead of screen name."
304
- method_option "long", :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
305
- method_option "max_id", :aliases => "-m", :type => :numeric, :desc => "Returns only the results with an ID less than the specified ID."
306
- method_option "number", :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => "Limit the number of results."
307
- method_option "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
308
- method_option "since_id", :aliases => "-s", :type => :numeric, :desc => "Returns only the results with an ID greater than the specified ID."
309
- def favorites(user=nil)
281
+ desc 'favorites [USER]', "Returns the #{DEFAULT_NUM_RESULTS} most recent Tweets you favorited."
282
+ method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
283
+ method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
284
+ method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
285
+ method_option 'max_id', :aliases => '-m', :type => :numeric, :desc => 'Returns only the results with an ID less than the specified ID.'
286
+ method_option 'number', :aliases => '-n', :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => 'Limit the number of results.'
287
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
288
+ method_option 'since_id', :aliases => '-s', :type => :numeric, :desc => 'Returns only the results with an ID greater than the specified ID.'
289
+ def favorites(user = nil)
310
290
  count = options['number'] || DEFAULT_NUM_RESULTS
311
291
  opts = {}
312
292
  opts[:exclude_replies] = true if options['exclude'] == 'replies'
@@ -315,11 +295,7 @@ module T
315
295
  opts[:since_id] = options['since_id'] if options['since_id']
316
296
  if user
317
297
  require 't/core_ext/string'
318
- user = if options['id']
319
- user.to_i
320
- else
321
- user.strip_ats
322
- end
298
+ user = options['id'] ? user.to_i : user.strip_ats
323
299
  end
324
300
  tweets = collect_with_count(count) do |count_opts|
325
301
  client.favorites(user, count_opts.merge(opts))
@@ -328,32 +304,28 @@ module T
328
304
  end
329
305
  map %w(faves favourites) => :favorites
330
306
 
331
- desc "follow USER [USER...]", "Allows you to start following users."
332
- method_option "id", :aliases => "-i", :type => :boolean, :default => false, :desc => "Specify input as Twitter user IDs instead of screen names."
307
+ desc 'follow USER [USER...]', 'Allows you to start following users.'
308
+ method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify input as Twitter user IDs instead of screen names.'
333
309
  def follow(user, *users)
334
- users, number = fetch_users(users.unshift(user), options) do |users|
335
- client.follow(users)
310
+ followed_users, number = fetch_users(users.unshift(user), options) do |users_to_follow|
311
+ client.follow(users_to_follow)
336
312
  end
337
313
  say "@#{@rcfile.active_profile[0]} is now following #{pluralize(number, 'more user')}."
338
314
  say
339
- say "Run `#{File.basename($0)} unfollow #{users.map{|user| "@#{user.screen_name}"}.join(' ')}` to stop."
315
+ say "Run `#{File.basename($PROGRAM_NAME)} unfollow #{followed_users.map { |followed_user| "@#{followed_user.screen_name}" }.join(' ')}` to stop."
340
316
  end
341
317
 
342
- desc "followings [USER]", "Returns a list of the people you follow on Twitter."
343
- method_option "csv", :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
344
- method_option "id", :aliases => "-i", :type => :boolean, :default => false, :desc => "Specify user via ID instead of screen name."
345
- method_option "long", :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
346
- method_option "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
347
- method_option "sort", :aliases => "-s", :type => :string, :enum => %w(favorites followers friends listed screen_name since tweets tweeted), :default => "screen_name", :desc => "Specify the order of the results.", :banner => "ORDER"
348
- method_option "unsorted", :aliases => "-u", :type => :boolean, :default => false, :desc => "Output is not sorted."
349
- def followings(user=nil)
318
+ desc 'followings [USER]', 'Returns a list of the people you follow on Twitter.'
319
+ method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
320
+ method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
321
+ method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
322
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
323
+ method_option 'sort', :aliases => '-s', :type => :string, :enum => %w(favorites followers friends listed screen_name since tweets tweeted), :default => 'screen_name', :desc => 'Specify the order of the results.', :banner => 'ORDER'
324
+ method_option 'unsorted', :aliases => '-u', :type => :boolean, :default => false, :desc => 'Output is not sorted.'
325
+ def followings(user = nil)
350
326
  if user
351
327
  require 't/core_ext/string'
352
- user = if options['id']
353
- user.to_i
354
- else
355
- user.strip_ats
356
- end
328
+ user = options['id'] ? user.to_i : user.strip_ats
357
329
  end
358
330
  following_ids = client.friend_ids(user).to_a
359
331
  require 'retryable'
@@ -363,21 +335,17 @@ module T
363
335
  print_users(users)
364
336
  end
365
337
 
366
- desc "followers [USER]", "Returns a list of the people who follow you on Twitter."
367
- method_option "csv", :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
368
- method_option "id", :aliases => "-i", :type => :boolean, :default => false, :desc => "Specify user via ID instead of screen name."
369
- method_option "long", :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
370
- method_option "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
371
- method_option "sort", :aliases => "-s", :type => :string, :enum => %w(favorites followers friends listed screen_name since tweets tweeted), :default => "screen_name", :desc => "Specify the order of the results.", :banner => "ORDER"
372
- method_option "unsorted", :aliases => "-u", :type => :boolean, :default => false, :desc => "Output is not sorted."
373
- def followers(user=nil)
338
+ desc 'followers [USER]', 'Returns a list of the people who follow you on Twitter.'
339
+ method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
340
+ method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
341
+ method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
342
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
343
+ method_option 'sort', :aliases => '-s', :type => :string, :enum => %w(favorites followers friends listed screen_name since tweets tweeted), :default => 'screen_name', :desc => 'Specify the order of the results.', :banner => 'ORDER'
344
+ method_option 'unsorted', :aliases => '-u', :type => :boolean, :default => false, :desc => 'Output is not sorted.'
345
+ def followers(user = nil)
374
346
  if user
375
347
  require 't/core_ext/string'
376
- user = if options['id']
377
- user.to_i
378
- else
379
- user.strip_ats
380
- end
348
+ user = options['id'] ? user.to_i : user.strip_ats
381
349
  end
382
350
  follower_ids = client.follower_ids(user).to_a
383
351
  require 'retryable'
@@ -387,24 +355,20 @@ module T
387
355
  print_users(users)
388
356
  end
389
357
 
390
- desc "friends [USER]", "Returns the list of people who you follow and follow you back."
391
- method_option "csv", :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
392
- method_option "id", :aliases => "-i", :type => :boolean, :default => false, :desc => "Specify user via ID instead of screen name."
393
- method_option "long", :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
394
- method_option "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
395
- method_option "sort", :aliases => "-s", :type => :string, :enum => %w(favorites followers friends listed screen_name since tweets tweeted), :default => "screen_name", :desc => "Specify the order of the results.", :banner => "ORDER"
396
- method_option "unsorted", :aliases => "-u", :type => :boolean, :default => false, :desc => "Output is not sorted."
397
- def friends(user=nil)
358
+ desc 'friends [USER]', 'Returns the list of people who you follow and follow you back.'
359
+ method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
360
+ method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
361
+ method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
362
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
363
+ method_option 'sort', :aliases => '-s', :type => :string, :enum => %w(favorites followers friends listed screen_name since tweets tweeted), :default => 'screen_name', :desc => 'Specify the order of the results.', :banner => 'ORDER'
364
+ method_option 'unsorted', :aliases => '-u', :type => :boolean, :default => false, :desc => 'Output is not sorted.'
365
+ def friends(user = nil)
398
366
  user = if user
399
- require 't/core_ext/string'
400
- if options['id']
401
- user.to_i
402
- else
403
- user.strip_ats
404
- end
405
- else
406
- client.verify_credentials.screen_name
407
- end
367
+ require 't/core_ext/string'
368
+ options['id'] ? user.to_i : user.strip_ats
369
+ else
370
+ client.verify_credentials.screen_name
371
+ end
408
372
  following_ids = Thread.new do
409
373
  client.friend_ids(user).to_a
410
374
  end
@@ -419,24 +383,20 @@ module T
419
383
  print_users(users)
420
384
  end
421
385
 
422
- desc "leaders [USER]", "Returns the list of people who you follow but don't follow you back."
423
- method_option "csv", :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
424
- method_option "id", :aliases => "-i", :type => :boolean, :default => false, :desc => "Specify user via ID instead of screen name."
425
- method_option "long", :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
426
- method_option "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
427
- method_option "sort", :aliases => "-s", :type => :string, :enum => %w(favorites followers friends listed screen_name since tweets tweeted), :default => "screen_name", :desc => "Specify the order of the results.", :banner => "ORDER"
428
- method_option "unsorted", :aliases => "-u", :type => :boolean, :default => false, :desc => "Output is not sorted."
429
- def leaders(user=nil)
386
+ desc 'leaders [USER]', "Returns the list of people who you follow but don't follow you back."
387
+ method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
388
+ method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
389
+ method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
390
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
391
+ method_option 'sort', :aliases => '-s', :type => :string, :enum => %w(favorites followers friends listed screen_name since tweets tweeted), :default => 'screen_name', :desc => 'Specify the order of the results.', :banner => 'ORDER'
392
+ method_option 'unsorted', :aliases => '-u', :type => :boolean, :default => false, :desc => 'Output is not sorted.'
393
+ def leaders(user = nil)
430
394
  user = if user
431
- require 't/core_ext/string'
432
- if options['id']
433
- user.to_i
434
- else
435
- user.strip_ats
436
- end
437
- else
438
- client.verify_credentials.screen_name
439
- end
395
+ require 't/core_ext/string'
396
+ options['id'] ? user.to_i : user.strip_ats
397
+ else
398
+ client.verify_credentials.screen_name
399
+ end
440
400
  following_ids = Thread.new do
441
401
  client.friend_ids(user).to_a
442
402
  end
@@ -451,36 +411,32 @@ module T
451
411
  print_users(users)
452
412
  end
453
413
 
454
- desc "lists [USER]", "Returns the lists created by a user."
455
- method_option "csv", :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
456
- method_option "id", :aliases => "-i", :type => :boolean, :default => false, :desc => "Specify user via ID instead of screen name."
457
- method_option "long", :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
458
- method_option "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
459
- method_option "sort", :aliases => "-s", :type => :string, :enum => %w(members mode posted slug subscribers), :default => "slug", :desc => "Specify the order of the results.", :banner => "ORDER"
460
- method_option "unsorted", :aliases => "-u", :type => :boolean, :default => false, :desc => "Output is not sorted."
461
- def lists(user=nil)
414
+ desc 'lists [USER]', 'Returns the lists created by a user.'
415
+ method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
416
+ method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
417
+ method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
418
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
419
+ method_option 'sort', :aliases => '-s', :type => :string, :enum => %w(members mode since slug subscribers), :default => 'slug', :desc => 'Specify the order of the results.', :banner => 'ORDER'
420
+ method_option 'unsorted', :aliases => '-u', :type => :boolean, :default => false, :desc => 'Output is not sorted.'
421
+ def lists(user = nil)
462
422
  lists = if user
463
- require 't/core_ext/string'
464
- user = if options['id']
465
- user.to_i
466
- else
467
- user.strip_ats
468
- end
469
- client.lists(user)
470
- else
471
- client.lists
472
- end
423
+ require 't/core_ext/string'
424
+ user = options['id'] ? user.to_i : user.strip_ats
425
+ client.lists(user)
426
+ else
427
+ client.lists
428
+ end
473
429
  print_lists(lists)
474
430
  end
475
431
 
476
- desc "matrix", "Unfortunately, no one can be told what the Matrix is. You have to see it for yourself."
477
- def_delegator :"T::Stream.new", :matrix
432
+ desc 'matrix', 'Unfortunately, no one can be told what the Matrix is. You have to see it for yourself.'
433
+ def_delegator :"T::Stream.new", :matrix # rubocop:disable SymbolName
478
434
 
479
- desc "mentions", "Returns the #{DEFAULT_NUM_RESULTS} most recent Tweets mentioning you."
480
- method_option "csv", :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
481
- method_option "long", :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
482
- method_option "number", :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => "Limit the number of results."
483
- method_option "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
435
+ desc 'mentions', "Returns the #{DEFAULT_NUM_RESULTS} most recent Tweets mentioning you."
436
+ method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
437
+ method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
438
+ method_option 'number', :aliases => '-n', :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => 'Limit the number of results.'
439
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
484
440
  def mentions
485
441
  count = options['number'] || DEFAULT_NUM_RESULTS
486
442
  tweets = collect_with_count(count) do |count_opts|
@@ -490,10 +446,10 @@ module T
490
446
  end
491
447
  map %w(replies) => :mentions
492
448
 
493
- desc "open USER", "Opens that user's profile in a web browser."
494
- method_option "display-uri", :aliases => "-d", :type => :boolean, :default => false, :desc => "Display the requested URL instead of attempting to open it."
495
- method_option "id", :aliases => "-i", :type => :boolean, :default => false, :desc => "Specify user via ID instead of screen name."
496
- method_option "status", :aliases => "-s", :type => :boolean, :default => false, :desc => "Specify input as a Twitter status ID instead of a screen name."
449
+ desc 'open USER', "Opens that user's profile in a web browser."
450
+ method_option 'display-uri', :aliases => '-d', :type => :boolean, :default => false, :desc => 'Display the requested URL instead of attempting to open it.'
451
+ method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
452
+ method_option 'status', :aliases => '-s', :type => :boolean, :default => false, :desc => 'Specify input as a Twitter status ID instead of a screen name.'
497
453
  def open(user)
498
454
  require 'launchy'
499
455
  if options['id']
@@ -508,9 +464,9 @@ module T
508
464
  end
509
465
  end
510
466
 
511
- desc "reply TWEET_ID MESSAGE", "Post your Tweet as a reply directed at another person."
512
- method_option "all", :aliases => "-a", :type => :boolean, :default => false, :desc => "Reply to all users mentioned in the Tweet."
513
- method_option "location", :aliases => "-l", :type => :string, :default => "location", :desc => "Add location information. If the optional 'latitude,longitude' parameter is not supplied, looks up location by IP address."
467
+ desc 'reply TWEET_ID MESSAGE', 'Post your Tweet as a reply directed at another person.'
468
+ method_option 'all', :aliases => '-a', :type => :boolean, :default => false, :desc => 'Reply to all users mentioned in the Tweet.'
469
+ method_option 'location', :aliases => '-l', :type => :string, :default => 'location', :desc => "Add location information. If the optional 'latitude,longitude' parameter is not supplied, looks up location by IP address."
514
470
  def reply(status_id, message)
515
471
  status = client.status(status_id.to_i, :include_my_retweet => false)
516
472
  users = Array(status.user.screen_name)
@@ -525,20 +481,20 @@ module T
525
481
  reply = client.update("#{users.join(' ')} #{message}", opts)
526
482
  say "Reply posted by @#{@rcfile.active_profile[0]} to #{users.join(' ')}."
527
483
  say
528
- say "Run `#{File.basename($0)} delete status #{reply.id}` to delete."
484
+ say "Run `#{File.basename($PROGRAM_NAME)} delete status #{reply.id}` to delete."
529
485
  end
530
486
 
531
- desc "report_spam USER [USER...]", "Report users for spam."
532
- method_option "id", :aliases => "-i", :type => :boolean, :default => false, :desc => "Specify input as Twitter user IDs instead of screen names."
487
+ desc 'report_spam USER [USER...]', 'Report users for spam.'
488
+ method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify input as Twitter user IDs instead of screen names.'
533
489
  def report_spam(user, *users)
534
- users, number = fetch_users(users.unshift(user), options) do |users|
535
- client.report_spam(users)
490
+ _, number = fetch_users(users.unshift(user), options) do |users_to_report|
491
+ client.report_spam(users_to_report)
536
492
  end
537
493
  say "@#{@rcfile.active_profile[0]} reported #{pluralize(number, 'user')}."
538
494
  end
539
495
  map %w(report reportspam spam) => :report_spam
540
496
 
541
- desc "retweet TWEET_ID [TWEET_ID...]", "Sends Tweets to your followers."
497
+ desc 'retweet TWEET_ID [TWEET_ID...]', 'Sends Tweets to your followers.'
542
498
  def retweet(status_id, *status_ids)
543
499
  status_ids.unshift(status_id)
544
500
  status_ids.map!(&:to_i)
@@ -549,99 +505,95 @@ module T
549
505
  number = retweets.length
550
506
  say "@#{@rcfile.active_profile[0]} retweeted #{pluralize(number, 'tweet')}."
551
507
  say
552
- say "Run `#{File.basename($0)} delete status #{retweets.map{|tweet| tweet.retweeted_status.id}.join(' ')}` to undo."
508
+ say "Run `#{File.basename($PROGRAM_NAME)} delete status #{retweets.map { |tweet| tweet.retweeted_status.id }.join(' ')}` to undo."
553
509
  end
554
510
  map %w(rt) => :retweet
555
511
 
556
- desc "retweets [USER]", "Returns the #{DEFAULT_NUM_RESULTS} most recent Retweets by a user."
557
- method_option "csv", :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
558
- method_option "id", :aliases => "-i", :type => :boolean, :default => false, :desc => "Specify user via ID instead of screen name."
559
- method_option "long", :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
560
- method_option "number", :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => "Limit the number of results."
561
- method_option "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
562
- def retweets(user=nil)
512
+ desc 'retweets [USER]', "Returns the #{DEFAULT_NUM_RESULTS} most recent Retweets by a user."
513
+ method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
514
+ method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
515
+ method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
516
+ method_option 'number', :aliases => '-n', :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => 'Limit the number of results.'
517
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
518
+ def retweets(user = nil)
563
519
  count = options['number'] || DEFAULT_NUM_RESULTS
564
520
  tweets = if user
565
- require 't/core_ext/string'
566
- user = if options['id']
567
- user.to_i
568
- else
569
- user.strip_ats
570
- end
571
- collect_with_count(count) do |count_opts|
572
- client.retweeted_by_user(user, count_opts)
573
- end
574
- else
575
- collect_with_count(count) do |count_opts|
576
- client.retweeted_by_me(count_opts)
577
- end
578
- end
521
+ require 't/core_ext/string'
522
+ user = options['id'] ? user.to_i : user.strip_ats
523
+ collect_with_count(count) do |count_opts|
524
+ client.retweeted_by_user(user, count_opts)
525
+ end
526
+ else
527
+ collect_with_count(count) do |count_opts|
528
+ client.retweeted_by_me(count_opts)
529
+ end
530
+ end
579
531
  print_tweets(tweets)
580
532
  end
581
533
  map %w(rts) => :retweets
582
534
 
583
- desc "ruler", "Prints a 140-character ruler"
584
- method_option "indent", :aliases => "-i", :type => :numeric, :default => 0, :desc => "The number of space to print before the ruler."
535
+ desc 'ruler', 'Prints a 140-character ruler'
536
+ method_option 'indent', :aliases => '-i', :type => :numeric, :default => 0, :desc => 'The number of space to print before the ruler.'
585
537
  def ruler
586
538
  markings = '----|'.chars.cycle.take(140).join
587
539
  say "#{' ' * options['indent'].to_i}#{markings}"
588
540
  end
589
541
 
590
- desc "status TWEET_ID", "Retrieves detailed information about a Tweet."
591
- method_option "csv", :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
592
- method_option "long", :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
593
- def status(status_id)
542
+ desc 'status TWEET_ID', 'Retrieves detailed information about a Tweet.'
543
+ method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
544
+ method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
545
+ def status(status_id) # rubocop:disable CyclomaticComplexity
594
546
  status = client.status(status_id.to_i, :include_my_retweet => false)
595
547
  location = if status.place?
596
- if status.place.name && status.place.attributes && status.place.attributes[:street_address] && status.place.attributes[:locality] && status.place.attributes[:region] && status.place.country
597
- [status.place.name, status.place.attributes[:street_address], status.place.attributes[:locality], status.place.attributes[:region], status.place.country].join(", ")
598
- elsif status.place.name && status.place.attributes && status.place.attributes[:locality] && status.place.attributes[:region] && status.place.country
599
- [status.place.name, status.place.attributes[:locality], status.place.attributes[:region], status.place.country].join(", ")
600
- elsif status.place.full_name && status.place.attributes && status.place.attributes[:region] && status.place.country
601
- [status.place.full_name, status.place.attributes[:region], status.place.country].join(", ")
602
- elsif status.place.full_name && status.place.country
603
- [status.place.full_name, status.place.country].join(", ")
604
- elsif status.place.full_name
605
- status.place.full_name
606
- else
607
- status.place.name
608
- end
609
- elsif status.geo?
610
- reverse_geocode(status.geo)
611
- end
612
- status_headings = ["ID", "Posted at", "Screen name", "Text", "Retweets", "Favorites", "Source", "Location"]
548
+ if status.place.name && status.place.attributes && status.place.attributes[:street_address] && status.place.attributes[:locality] && status.place.attributes[:region] && status.place.country
549
+ [status.place.name, status.place.attributes[:street_address], status.place.attributes[:locality], status.place.attributes[:region], status.place.country].join(', ')
550
+ elsif status.place.name && status.place.attributes && status.place.attributes[:locality] && status.place.attributes[:region] && status.place.country
551
+ [status.place.name, status.place.attributes[:locality], status.place.attributes[:region], status.place.country].join(', ')
552
+ elsif status.place.full_name && status.place.attributes && status.place.attributes[:region] && status.place.country
553
+ [status.place.full_name, status.place.attributes[:region], status.place.country].join(', ')
554
+ elsif status.place.full_name && status.place.country
555
+ [status.place.full_name, status.place.country].join(', ')
556
+ elsif status.place.full_name
557
+ status.place.full_name
558
+ else
559
+ status.place.name
560
+ end
561
+ elsif status.geo?
562
+ reverse_geocode(status.geo)
563
+ end
564
+ status_headings = ['ID', 'Posted at', 'Screen name', 'Text', 'Retweets', 'Favorites', 'Source', 'Location']
613
565
  if options['csv']
614
566
  require 'csv'
615
567
  say status_headings.to_csv
616
568
  say [status.id, csv_formatted_time(status), status.user.screen_name, decode_full_text(status), status.retweet_count, status.favorite_count, strip_tags(status.source), location].to_csv
617
569
  elsif options['long']
618
570
  array = [status.id, ls_formatted_time(status), "@#{status.user.screen_name}", decode_full_text(status).gsub(/\n+/, ' '), status.retweet_count, status.favorite_count, strip_tags(status.source), location]
619
- format = options['format'] || status_headings.size.times.map{"%s"}
571
+ format = options['format'] || status_headings.size.times.map { '%s' }
620
572
  print_table_with_headings([array], status_headings, format)
621
573
  else
622
574
  array = []
623
- array << ["ID", status.id.to_s]
624
- array << ["Text", decode_full_text(status).gsub(/\n+/, ' ')]
625
- array << ["Screen name", "@#{status.user.screen_name}"]
626
- array << ["Posted at", "#{ls_formatted_time(status)} (#{time_ago_in_words(status.created_at)} ago)"]
627
- array << ["Retweets", number_with_delimiter(status.retweet_count)]
628
- array << ["Favorites", number_with_delimiter(status.favorite_count)]
629
- array << ["Source", strip_tags(status.source)]
630
- array << ["Location", location] unless location.nil?
575
+ array << ['ID', status.id.to_s]
576
+ array << ['Text', decode_full_text(status).gsub(/\n+/, ' ')]
577
+ array << ['Screen name', "@#{status.user.screen_name}"]
578
+ array << ['Posted at', "#{ls_formatted_time(status)} (#{time_ago_in_words(status.created_at)} ago)"]
579
+ array << ['Retweets', number_with_delimiter(status.retweet_count)]
580
+ array << ['Favorites', number_with_delimiter(status.favorite_count)]
581
+ array << ['Source', strip_tags(status.source)]
582
+ array << ['Location', location] unless location.nil?
631
583
  print_table(array)
632
584
  end
633
585
  end
634
586
 
635
- desc "timeline [USER]", "Returns the #{DEFAULT_NUM_RESULTS} most recent Tweets posted by a user."
636
- method_option "csv", :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
637
- method_option "exclude", :aliases => "-e", :type => :string, :enum => %w(replies retweets), :desc => "Exclude certain types of Tweets from the results.", :banner => "TYPE"
638
- method_option "id", :aliases => "-i", :type => :boolean, :default => false, :desc => "Specify user via ID instead of screen name."
639
- method_option "long", :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
640
- method_option "max_id", :aliases => "-m", :type => :numeric, :desc => "Returns only the results with an ID less than the specified ID."
641
- method_option "number", :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => "Limit the number of results."
642
- method_option "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
643
- method_option "since_id", :aliases => "-s", :type => :numeric, :desc => "Returns only the results with an ID greater than the specified ID."
644
- def timeline(user=nil)
587
+ desc 'timeline [USER]', "Returns the #{DEFAULT_NUM_RESULTS} most recent Tweets posted by a user."
588
+ method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
589
+ method_option 'exclude', :aliases => '-e', :type => :string, :enum => %w(replies retweets), :desc => 'Exclude certain types of Tweets from the results.', :banner => 'TYPE'
590
+ method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
591
+ method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
592
+ method_option 'max_id', :aliases => '-m', :type => :numeric, :desc => 'Returns only the results with an ID less than the specified ID.'
593
+ method_option 'number', :aliases => '-n', :type => :numeric, :default => DEFAULT_NUM_RESULTS, :desc => 'Limit the number of results.'
594
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
595
+ method_option 'since_id', :aliases => '-s', :type => :numeric, :desc => 'Returns only the results with an ID greater than the specified ID.'
596
+ def timeline(user = nil)
645
597
  count = options['number'] || DEFAULT_NUM_RESULTS
646
598
  opts = {}
647
599
  opts[:exclude_replies] = true if options['exclude'] == 'replies'
@@ -650,11 +602,7 @@ module T
650
602
  opts[:since_id] = options['since_id'] if options['since_id']
651
603
  if user
652
604
  require 't/core_ext/string'
653
- user = if options['id']
654
- user.to_i
655
- else
656
- user.strip_ats
657
- end
605
+ user = options['id'] ? user.to_i : user.strip_ats
658
606
  tweets = collect_with_count(count) do |count_opts|
659
607
  client.user_timeline(user, count_opts.merge(opts))
660
608
  end
@@ -667,35 +615,35 @@ module T
667
615
  end
668
616
  map %w(tl) => :timeline
669
617
 
670
- desc "trends [WOEID]", "Returns the top 10 trending topics."
671
- method_option "exclude-hashtags", :aliases => "-x", :type => :boolean, :default => false, :desc => "Remove all hashtags from the trends list."
672
- def trends(woe_id=1)
618
+ desc 'trends [WOEID]', 'Returns the top 10 trending topics.'
619
+ method_option 'exclude-hashtags', :aliases => '-x', :type => :boolean, :default => false, :desc => 'Remove all hashtags from the trends list.'
620
+ def trends(woe_id = 1)
673
621
  opts = {}
674
- opts.merge!(:exclude => "hashtags") if options['exclude-hashtags']
622
+ opts.merge!(:exclude => 'hashtags') if options['exclude-hashtags']
675
623
  trends = client.trends(woe_id, opts)
676
624
  print_attribute(trends, :name)
677
625
  end
678
626
 
679
- desc "trend_locations", "Returns the locations for which Twitter has trending topic information."
680
- method_option "csv", :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
681
- method_option "long", :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
682
- method_option "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
683
- method_option "sort", :aliases => "-s", :type => :string, :enum => %w(country name parent type woeid), :default => "name", :desc => "Specify the order of the results.", :banner => "ORDER"
684
- method_option "unsorted", :aliases => "-u", :type => :boolean, :default => false, :desc => "Output is not sorted."
627
+ desc 'trend_locations', 'Returns the locations for which Twitter has trending topic information.'
628
+ method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
629
+ method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
630
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
631
+ method_option 'sort', :aliases => '-s', :type => :string, :enum => %w(country name parent type woeid), :default => 'name', :desc => 'Specify the order of the results.', :banner => 'ORDER'
632
+ method_option 'unsorted', :aliases => '-u', :type => :boolean, :default => false, :desc => 'Output is not sorted.'
685
633
  def trend_locations
686
634
  places = client.trend_locations
687
635
  places = case options['sort']
688
- when 'country'
689
- places.sort_by{|places| places.country.downcase}
690
- when 'parent'
691
- places.sort_by{|places| places.parent_id.to_i}
692
- when 'type'
693
- places.sort_by{|places| places.place_type.downcase}
694
- when 'woeid'
695
- places.sort_by{|places| places.woeid.to_i}
696
- else
697
- places.sort_by{|places| places.name.downcase}
698
- end unless options['unsorted']
636
+ when 'country'
637
+ places.sort_by { |place| place.country.downcase }
638
+ when 'parent'
639
+ places.sort_by { |place| place.parent_id.to_i }
640
+ when 'type'
641
+ places.sort_by { |place| place.place_type.downcase }
642
+ when 'woeid'
643
+ places.sort_by { |place| place.woeid.to_i }
644
+ else
645
+ places.sort_by { |place| place.name.downcase }
646
+ end unless options['unsorted']
699
647
  places.reverse! if options['reverse']
700
648
  if options['csv']
701
649
  require 'csv'
@@ -707,7 +655,7 @@ module T
707
655
  array = places.map do |place|
708
656
  [place.woeid, place.parent_id, place.place_type, place.name, place.country]
709
657
  end
710
- format = options['format'] || TREND_HEADINGS.size.times.map{"%s"}
658
+ format = options['format'] || TREND_HEADINGS.size.times.map { '%s' }
711
659
  print_table_with_headings(array, TREND_HEADINGS, format)
712
660
  else
713
661
  print_attribute(places, :name)
@@ -715,110 +663,102 @@ module T
715
663
  end
716
664
  map %w(locations trendlocations) => :trend_locations
717
665
 
718
- desc "unfollow USER [USER...]", "Allows you to stop following users."
719
- method_option "id", :aliases => "-i", :type => :boolean, :default => false, :desc => "Specify input as Twitter user IDs instead of screen names."
666
+ desc 'unfollow USER [USER...]', 'Allows you to stop following users.'
667
+ method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify input as Twitter user IDs instead of screen names.'
720
668
  def unfollow(user, *users)
721
- users, number = fetch_users(users.unshift(user), options) do |users|
722
- client.unfollow(users)
669
+ unfollowed_users, number = fetch_users(users.unshift(user), options) do |users_to_unfollow|
670
+ client.unfollow(users_to_unfollow)
723
671
  end
724
672
  say "@#{@rcfile.active_profile[0]} is no longer following #{pluralize(number, 'user')}."
725
673
  say
726
- say "Run `#{File.basename($0)} follow #{users.map{|user| "@#{user.screen_name}"}.join(' ')}` to follow again."
674
+ say "Run `#{File.basename($PROGRAM_NAME)} follow #{unfollowed_users.map { |unfollowed_user| "@#{unfollowed_user.screen_name}" }.join(' ')}` to follow again."
727
675
  end
728
676
 
729
- desc "update [MESSAGE]", "Post a Tweet."
730
- method_option "location", :aliases => "-l", :type => :string, :default => "location", :desc => "Add location information. If the optional 'latitude,longitude' parameter is not supplied, looks up location by IP address."
731
- method_option "file", :aliases => "-f", :type => :string, :desc => "The path to an image to attach to your tweet."
732
- def update(message=nil)
677
+ desc 'update [MESSAGE]', 'Post a Tweet.'
678
+ method_option 'location', :aliases => '-l', :type => :string, :default => 'location', :desc => "Add location information. If the optional 'latitude,longitude' parameter is not supplied, looks up location by IP address."
679
+ method_option 'file', :aliases => '-f', :type => :string, :desc => 'The path to an image to attach to your tweet.'
680
+ def update(message = nil)
733
681
  message = T::Editor.gets if message.nil? || message.empty?
734
682
  opts = {:trim_user => true}
735
683
  add_location!(options, opts)
736
684
  status = if options['file']
737
- client.update_with_media(message, File.new(File.expand_path(options['file'])), opts)
738
- else
739
- client.update(message, opts)
740
- end
685
+ client.update_with_media(message, File.new(File.expand_path(options['file'])), opts)
686
+ else
687
+ client.update(message, opts)
688
+ end
741
689
  say "Tweet posted by @#{@rcfile.active_profile[0]}."
742
690
  say
743
- say "Run `#{File.basename($0)} delete status #{status.id}` to delete."
691
+ say "Run `#{File.basename($PROGRAM_NAME)} delete status #{status.id}` to delete."
744
692
  end
745
693
  map %w(post tweet) => :update
746
694
 
747
- desc "users USER [USER...]", "Returns a list of users you specify."
748
- method_option "csv", :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
749
- method_option "id", :aliases => "-i", :type => :boolean, :default => false, :desc => "Specify input as Twitter user IDs instead of screen names."
750
- method_option "long", :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
751
- method_option "reverse", :aliases => "-r", :type => :boolean, :default => false, :desc => "Reverse the order of the sort."
752
- method_option "sort", :aliases => "-s", :type => :string, :enum => %w(favorites followers friends listed screen_name since tweets tweeted), :default => "screen_name", :desc => "Specify the order of the results.", :banner => "ORDER"
753
- method_option "unsorted", :aliases => "-u", :type => :boolean, :default => false, :desc => "Output is not sorted."
695
+ desc 'users USER [USER...]', 'Returns a list of users you specify.'
696
+ method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
697
+ method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify input as Twitter user IDs instead of screen names.'
698
+ method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
699
+ method_option 'reverse', :aliases => '-r', :type => :boolean, :default => false, :desc => 'Reverse the order of the sort.'
700
+ method_option 'sort', :aliases => '-s', :type => :string, :enum => %w(favorites followers friends listed screen_name since tweets tweeted), :default => 'screen_name', :desc => 'Specify the order of the results.', :banner => 'ORDER'
701
+ method_option 'unsorted', :aliases => '-u', :type => :boolean, :default => false, :desc => 'Output is not sorted.'
754
702
  def users(user, *users)
755
703
  users.unshift(user)
756
704
  require 't/core_ext/string'
757
- if options['id']
758
- users.map!(&:to_i)
759
- else
760
- users.map!(&:strip_ats)
761
- end
705
+ options['id'] ? users.map!(&:to_i) : users.map!(&:strip_ats)
762
706
  users = client.users(users)
763
707
  print_users(users)
764
708
  end
765
709
  map %w(stats) => :users
766
710
 
767
- desc "version", "Show version."
711
+ desc 'version', 'Show version.'
768
712
  def version
769
713
  require 't/version'
770
714
  say T::Version
771
715
  end
772
716
  map %w(-v --version) => :version
773
717
 
774
- desc "whois USER", "Retrieves profile information for the user."
775
- method_option "csv", :aliases => "-c", :type => :boolean, :default => false, :desc => "Output in CSV format."
776
- method_option "id", :aliases => "-i", :type => :boolean, :default => false, :desc => "Specify user via ID instead of screen name."
777
- method_option "long", :aliases => "-l", :type => :boolean, :default => false, :desc => "Output in long format."
718
+ desc 'whois USER', 'Retrieves profile information for the user.'
719
+ method_option 'csv', :aliases => '-c', :type => :boolean, :default => false, :desc => 'Output in CSV format.'
720
+ method_option 'id', :aliases => '-i', :type => :boolean, :default => false, :desc => 'Specify user via ID instead of screen name.'
721
+ method_option 'long', :aliases => '-l', :type => :boolean, :default => false, :desc => 'Output in long format.'
778
722
  def whois(user)
779
723
  require 't/core_ext/string'
780
- user = if options['id']
781
- user.to_i
782
- else
783
- user.strip_ats
784
- end
724
+ user = options['id'] ? user.to_i : user.strip_ats
785
725
  user = client.user(user)
786
726
  require 'htmlentities'
787
727
  if options['csv'] || options['long']
788
728
  print_users([user])
789
729
  else
790
730
  array = []
791
- array << ["ID", user.id.to_s]
792
- array << ["Since", "#{ls_formatted_time(user)} (#{time_ago_in_words(user.created_at)} ago)"]
793
- array << ["Last update", "#{decode_full_text(user.status).gsub(/\n+/, ' ')} (#{time_ago_in_words(user.status.created_at)} ago)"] unless user.status.nil?
794
- array << ["Screen name", "@#{user.screen_name}"]
795
- array << [user.verified ? "Name (Verified)" : "Name", user.name] unless user.name.nil?
796
- array << ["Tweets", number_with_delimiter(user.statuses_count)]
797
- array << ["Favorites", number_with_delimiter(user.favorites_count)]
798
- array << ["Listed", number_with_delimiter(user.listed_count)]
799
- array << ["Following", number_with_delimiter(user.friends_count)]
800
- array << ["Followers", number_with_delimiter(user.followers_count)]
801
- array << ["Bio", user.description.gsub(/\n+/, ' ')] unless user.description.nil?
802
- array << ["Location", user.location] unless user.location.nil?
803
- array << ["URL", user.website] unless user.website.nil?
731
+ array << ['ID', user.id.to_s]
732
+ array << ['Since', "#{ls_formatted_time(user)} (#{time_ago_in_words(user.created_at)} ago)"]
733
+ array << ['Last update', "#{decode_full_text(user.status).gsub(/\n+/, ' ')} (#{time_ago_in_words(user.status.created_at)} ago)"] unless user.status.nil?
734
+ array << ['Screen name', "@#{user.screen_name}"]
735
+ array << [user.verified ? 'Name (Verified)' : 'Name', user.name] unless user.name.nil?
736
+ array << ['Tweets', number_with_delimiter(user.statuses_count)]
737
+ array << ['Favorites', number_with_delimiter(user.favorites_count)]
738
+ array << ['Listed', number_with_delimiter(user.listed_count)]
739
+ array << ['Following', number_with_delimiter(user.friends_count)]
740
+ array << ['Followers', number_with_delimiter(user.followers_count)]
741
+ array << ['Bio', user.description.gsub(/\n+/, ' ')] unless user.description.nil?
742
+ array << ['Location', user.location] unless user.location.nil?
743
+ array << ['URL', user.website] unless user.website.nil?
804
744
  print_table(array)
805
745
  end
806
746
  end
807
747
  map %w(user) => :whois
808
748
 
809
- desc "delete SUBCOMMAND ...ARGS", "Delete Tweets, Direct Messages, etc."
749
+ desc 'delete SUBCOMMAND ...ARGS', 'Delete Tweets, Direct Messages, etc.'
810
750
  subcommand 'delete', T::Delete
811
751
 
812
- desc "list SUBCOMMAND ...ARGS", "Do various things with lists."
752
+ desc 'list SUBCOMMAND ...ARGS', 'Do various things with lists.'
813
753
  subcommand 'list', T::List
814
754
 
815
- desc "search SUBCOMMAND ...ARGS", "Search through Tweets."
755
+ desc 'search SUBCOMMAND ...ARGS', 'Search through Tweets.'
816
756
  subcommand 'search', T::Search
817
757
 
818
- desc "set SUBCOMMAND ...ARGS", "Change various account settings."
758
+ desc 'set SUBCOMMAND ...ARGS', 'Change various account settings.'
819
759
  subcommand 'set', T::Set
820
760
 
821
- desc "stream SUBCOMMAND ...ARGS", "Commands for streaming Tweets."
761
+ desc 'stream SUBCOMMAND ...ARGS', 'Commands for streaming Tweets.'
822
762
  subcommand 'stream', T::Stream
823
763
 
824
764
  private
@@ -844,7 +784,7 @@ module T
844
784
  params = request['Authorization'].sub(/^OAuth\s+/, '').split(/,\s+/).map do |param|
845
785
  key, value = param.split('=')
846
786
  value =~ /"(.*?)"/
847
- "#{key}=#{CGI::escape($1)}"
787
+ "#{key}=#{CGI.escape(Regexp.last_match[1])}"
848
788
  end.join('&')
849
789
  "#{Twitter::REST::Client::ENDPOINT}#{request.path}?#{params}"
850
790
  end
@@ -864,7 +804,7 @@ module T
864
804
  return @location if @location
865
805
  require 'geokit'
866
806
  require 'open-uri'
867
- ip_address = Kernel::open("http://checkip.dyndns.org/") do |body|
807
+ ip_address = Kernel.open('http://checkip.dyndns.org/') do |body|
868
808
  /(?:\d{1,3}\.){3}\d{1,3}/.match(body.read)[0]
869
809
  end
870
810
  @location = Geokit::Geocoders::MultiGeocoder.geocode(ip_address)
@@ -874,13 +814,12 @@ module T
874
814
  require 'geokit'
875
815
  geoloc = Geokit::Geocoders::MultiGeocoder.reverse_geocode(geo.coordinates)
876
816
  if geoloc.city && geoloc.state && geoloc.country
877
- [geoloc.city, geoloc.state, geoloc.country].join(", ")
817
+ [geoloc.city, geoloc.state, geoloc.country].join(', ')
878
818
  elsif geoloc.state && geoloc.country
879
- [geoloc.state, geoloc.country].join(", ")
819
+ [geoloc.state, geoloc.country].join(', ')
880
820
  else
881
821
  geoloc.country
882
822
  end
883
823
  end
884
-
885
824
  end
886
825
  end