t 2.0.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data.tar.gz.sig 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