t 2.9.0 → 2.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: abfdf14a94b1051279ded1673b41f3ac9bebf0b9
4
- data.tar.gz: b698c0a8e8f02fee6a8731cc92f215ba4889e1c0
3
+ metadata.gz: a26d91bbbf1248998297b1ca780c2b60c18749cc
4
+ data.tar.gz: b525d7aebabfa57f79f05af951d3eca545daee8c
5
5
  SHA512:
6
- metadata.gz: 1d72e7b4becf49eb70f035a7b942ccf3b0e31d128f8a1ca8c807c019b23afcb2aefa4e0743b63d02cde3b2dd1549d67ddc3581b60b30d104fc88c71a4edb822e
7
- data.tar.gz: 9d064b925bd0ca951cce9c94350f456ff20beef4386b4575e900384127f90145e0164a62153fa40c9c4f059f937a56112bd5a783ab83fb72235be9cbec93a570
6
+ metadata.gz: f7ccdf367adc9c47042a52f822e6f7b5f12d22fb4dffece434f70cc1d968d6d842dffcab8fe5807e0288cb7310aa54840fa3037978c067ba158d0fe4375960e4
7
+ data.tar.gz: 6d4fd9b61299729e4bbfc2889ae3cd6817b17c0588f86f8b091abd633e058abedf1aaf68ae2dcb57285d8f06217eef71a748423da8dc9b89dfcde28224bf8af0
data/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011-2015 Erik Michaels-Ober
1
+ Copyright (c) 2011-2016 Erik Michaels-Ober
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -2,14 +2,14 @@
2
2
  [icon]: https://github.com/sferik/t/raw/master/icon/t.png
3
3
 
4
4
  # Twitter CLI
5
- [![Gem Version](http://img.shields.io/gem/v/t.svg)][gem]
6
- [![Build Status](http://img.shields.io/travis/sferik/t.svg)][travis]
7
- [![Dependency Status](http://img.shields.io/gemnasium/sferik/t.svg)][gemnasium]
8
- [![Coverage Status](http://img.shields.io/coveralls/sferik/t.svg)][coveralls]
5
+ [![Gem Version](https://img.shields.io/gem/v/t.svg)][gem]
6
+ [![Build Status](https://img.shields.io/travis/sferik/t.svg)][travis]
7
+ [![Dependency Status](https://img.shields.io/gemnasium/sferik/t.svg)][gemnasium]
8
+ [![Coverage Status](https://img.shields.io/coveralls/sferik/t.svg)][coveralls]
9
9
  [![tip for next commit](https://tip4commit.com/projects/102.svg)](https://tip4commit.com/github/sferik/t)
10
10
 
11
11
  [gem]: https://rubygems.org/gems/t
12
- [travis]: http://travis-ci.org/sferik/t
12
+ [travis]: https://travis-ci.org/sferik/t
13
13
  [gemnasium]: https://gemnasium.com/sferik/t
14
14
  [coveralls]: https://coveralls.io/r/sferik/t
15
15
 
@@ -19,7 +19,7 @@ offers vastly more commands and capabilities than are available via SMS.
19
19
 
20
20
  [sms]: https://support.twitter.com/articles/14020-twitter-sms-command
21
21
 
22
- ## Installation
22
+ ## Dependencies
23
23
  First, make sure you have Ruby installed.
24
24
 
25
25
  **On a Mac**, open `/Applications/Utilities/Terminal.app` and type:
@@ -31,7 +31,7 @@ If the output looks something like this, you're in good shape:
31
31
  ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-darwin13.0.0]
32
32
 
33
33
  If the output looks more like this, you need to [install Ruby][ruby]:
34
- [ruby]: http://www.ruby-lang.org/en/downloads/
34
+ [ruby]: https://www.ruby-lang.org/en/downloads/
35
35
 
36
36
  ruby: command not found
37
37
 
@@ -48,6 +48,7 @@ or for Red Hat-based distros like Fedora and CentOS, type:
48
48
  **On Windows**, you can install Ruby with [RubyInstaller][].
49
49
  [rubyinstaller]: http://rubyinstaller.org/downloads/
50
50
 
51
+ ## Installation
51
52
  Once you've verified that Ruby is installed:
52
53
 
53
54
  gem install t
@@ -56,9 +57,9 @@ Once you've verified that Ruby is installed:
56
57
  Twitter API v1.1 requires OAuth for all of its functionality, so you'll need a
57
58
  registered Twitter application. If you've never registered a Twitter
58
59
  application before, it's easy! Just sign-in using your Twitter account and then
59
- fill out the short form at <http://dev.twitter.com/apps/new>. If you've
60
+ fill out the short form at <https://apps.twitter.com/app/new>. If you've
60
61
  previously registered a Twitter application, it should be listed at
61
- <http://dev.twitter.com/apps>. Once you've registered an application, make sure
62
+ <https://apps.twitter.com/>. Once you've registered an application, make sure
62
63
  to set your application's Access Level to "Read, Write and Access direct
63
64
  messages", otherwise you'll receive an error that looks like this:
64
65
 
@@ -77,6 +78,8 @@ terminal. If you type the PIN correctly, you should now be authorized to use
77
78
  `t` as that user. To authorize multiple accounts, simply repeat the last step,
78
79
  signing into Twitter as a different user.
79
80
 
81
+ **NOTE**: If you have problems authorizing multiple accounts, open a new window in your browser in incognito/private-browsing mode and repeat the `t authorize` steps. This is apparently due to a bug in twitter's cookie handling.
82
+
80
83
  You can see a list of all the accounts you've authorized by typing the command:
81
84
 
82
85
  t accounts
@@ -212,7 +215,7 @@ example, here's how to send a user a direct message only if they already follow
212
215
  by adding the `--csv` flag.
213
216
  * 95% C0 Code Coverage: Well tested, with a 2.5:1 test-to-code ratio.
214
217
 
215
- [search]: https://dev.twitter.com/docs/using-search
218
+ [search]: https://dev.twitter.com/rest/public/search
216
219
 
217
220
  ## Using T for Backup
218
221
  [@jphpsf][jphpsf] wrote a [blog post][blog] explaining how to use `t` to backup
@@ -225,9 +228,9 @@ your Twitter account.
225
228
 
226
229
  `t` was also discussed on [an episode of the Ruby Rogues podcast][rubyrogues].
227
230
 
228
- [ruby5]: http://ruby5.envylabs.com/episodes/273-episode-269-may-4th-2012/stories/2400-t-command-line-power-tool-for-twitter
231
+ [ruby5]: https://ruby5.codeschool.com/episodes/273-episode-269-may-4th-2012/stories/2400-t-command-line-power-tool-for-twitter
229
232
 
230
- [rubyrogues]: http://rubyrogues.com/127-rr-erik-michaels-ober/
233
+ [rubyrogues]: https://devchat.tv/ruby-rogues/127-rr-erik-michaels-ober
231
234
 
232
235
  If you discuss `t` in a blog post or podcast, [let me know][email] and I'll
233
236
  link it here.
@@ -308,8 +311,8 @@ If you are running t on a remote computer you can use the flag --display-uri dur
308
311
  t authorize --display-uri
309
312
 
310
313
  ## Copyright
311
- Copyright (c) 2011-2015 Erik Michaels-Ober. See [LICENSE][] for details.
314
+ Copyright (c) 2011-2016 Erik Michaels-Ober. See [LICENSE][] for details.
312
315
  Application icon by [@nvk][nvk].
313
316
 
314
317
  [license]: https://github.com/sferik/t/blob/master/LICENSE.md
315
- [nvk]: http://rodolfonovak.com
318
+ [nvk]: http://www.rnvk.org
data/bin/t CHANGED
@@ -23,12 +23,9 @@ rescue Interrupt
23
23
  rescue OAuth::Unauthorized
24
24
  pute 'Authorization failed'
25
25
  rescue Twitter::Error::TooManyRequests => error
26
- pute error.message,
27
- "The rate limit for this request will reset in #{error.rate_limit.reset_in} #{error.rate_limit.reset_in == 1 ? 'second' : 'seconds'}.",
28
- 'While you wait, consider making a polite request for Twitter to increase the API rate limit at https://twittercommunity.com/t/discussing-api-v1-1/10180'
26
+ pute error.message, "The rate limit for this request will reset in #{error.rate_limit.reset_in} #{error.rate_limit.reset_in == 1 ? 'second' : 'seconds'}."
29
27
  rescue Twitter::Error::BadRequest => error
30
- pute error.message,
31
- 'Run `t authorize` to authorize.'
28
+ pute error.message, 'Run `t authorize` to authorize.'
32
29
  rescue Twitter::Error::Forbidden, Twitter::Error::Unauthorized => error
33
30
  if error.message == 'Error processing your OAuth request: Read-only application cannot POST' ||
34
31
  error.message == 'This application is not allowed to access or delete your direct messages'
@@ -24,9 +24,9 @@ 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']
27
+ DIRECT_MESSAGE_HEADINGS = ['ID', 'Posted at', 'Screen name', 'Text'].freeze
28
28
  MAX_SEARCH_RESULTS = 100
29
- TREND_HEADINGS = ['WOEID', 'Parent ID', 'Type', 'Name', 'Country']
29
+ TREND_HEADINGS = ['WOEID', 'Parent ID', 'Type', 'Name', 'Country'].freeze
30
30
 
31
31
  check_unknown_options!
32
32
 
@@ -62,21 +62,19 @@ module T
62
62
  say ' Note: Your application must have a unique name.'
63
63
  say ' 3. Go to the Permissions 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 API Keys tab to view the consumer key and secret,'
66
- say " which you'll need to copy and paste below when prompted."
67
- say
68
- ask 'Press [Enter] to open the Twitter Developer site.'
69
- say
65
+ say ' 4. Go to the Keys and Access Tokens tab to view the consumer key'
66
+ say " and secret which you'll need to copy and paste below when"
67
+ say ' prompted.'
70
68
  else
71
69
  say "It looks like you've already registered an application with Twitter."
72
70
  say 'To authorize a new account, just follow the steps below:'
73
71
  say ' 1. Sign in to the Twitter Developer site.'
74
72
  say " 2. Select the application for which you'd like to authorize an account."
75
73
  say ' 3. Copy and paste the consumer key and secret below when prompted.'
76
- say
77
- ask 'Press [Enter] to open the Twitter Developer site.'
78
- say
79
74
  end
75
+ say
76
+ ask 'Press [Enter] to open the Twitter Developer site.'
77
+ say
80
78
  require 'launchy'
81
79
  open_or_print('https://apps.twitter.com', dry_run: options['display-uri'])
82
80
  key = ask 'Enter your API key:'
@@ -147,7 +145,7 @@ module T
147
145
  array = direct_messages.collect do |direct_message|
148
146
  [direct_message.id, ls_formatted_time(direct_message), "@#{direct_message.sender.screen_name}", decode_full_text(direct_message, options['decode_uris']).gsub(/\n+/, ' ')]
149
147
  end
150
- format = options['format'] || DIRECT_MESSAGE_HEADINGS.size.times.collect { '%s' }
148
+ format = options['format'] || Array.new(DIRECT_MESSAGE_HEADINGS.size) { '%s' }
151
149
  print_table_with_headings(array, DIRECT_MESSAGE_HEADINGS, format)
152
150
  else
153
151
  direct_messages.each do |direct_message|
@@ -182,7 +180,7 @@ module T
182
180
  array = direct_messages.collect do |direct_message|
183
181
  [direct_message.id, ls_formatted_time(direct_message), "@#{direct_message.recipient.screen_name}", decode_full_text(direct_message, options['decode_uris']).gsub(/\n+/, ' ')]
184
182
  end
185
- format = options['format'] || DIRECT_MESSAGE_HEADINGS.size.times.collect { '%s' }
183
+ format = options['format'] || Array.new(DIRECT_MESSAGE_HEADINGS.size) { '%s' }
186
184
  print_table_with_headings(array, DIRECT_MESSAGE_HEADINGS, format)
187
185
  else
188
186
  direct_messages.each do |direct_message|
@@ -223,7 +221,7 @@ module T
223
221
  desc 'does_follow USER [USER]', 'Find out whether one user follows another.'
224
222
  method_option 'id', aliases: '-i', type: :boolean, desc: 'Specify user via ID instead of screen name.'
225
223
  def does_follow(user1, user2 = nil)
226
- abort 'No, you are not following yourself.' if user2.nil? && user1 == @rcfile.active_profile[0].downcase
224
+ abort 'No, you are not following yourself.' if user2.nil? && @rcfile.active_profile[0].casecmp(user1).zero?
227
225
  abort "No, @#{user1} is not following themself." if user1 == user2
228
226
  require 't/core_ext/string'
229
227
  thread1 = if options['id']
@@ -233,14 +231,13 @@ module T
233
231
  end
234
232
  thread2 = if user2.nil?
235
233
  Thread.new { @rcfile.active_profile[0] }
234
+ elsif options['id']
235
+ Thread.new { client.user(user2.to_i).screen_name }
236
236
  else
237
- if options['id']
238
- Thread.new { client.user(user2.to_i).screen_name }
239
- else
240
- Thread.new { user2.strip_ats }
241
- end
237
+ Thread.new { user2.strip_ats }
242
238
  end
243
- user1, user2 = thread1.value, thread2.value
239
+ user1 = thread1.value
240
+ user2 = thread2.value
244
241
  if client.friendship?(user1, user2)
245
242
  say "Yes, @#{user1} follows @#{user2}."
246
243
  else
@@ -431,7 +428,7 @@ module T
431
428
  method_option 'relative_dates', aliases: '-a', type: :boolean, desc: 'Show relative dates.'
432
429
  method_option 'reverse', aliases: '-r', type: :boolean, desc: 'Reverse the order of the sort.'
433
430
  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'
434
- method_option 'type', aliases: '-t', type: :string, enum: %w(followers followings), default: 'followings', desc: 'Specify the typo of intersection.'
431
+ method_option 'type', aliases: '-t', type: :string, enum: %w(followers followings), default: 'followings', desc: 'Specify the type of intersection.'
435
432
  method_option 'unsorted', aliases: '-u', type: :boolean, desc: 'Output is not sorted.'
436
433
  def intersection(first_user, *users)
437
434
  users.push(first_user)
@@ -594,11 +591,12 @@ module T
594
591
  say number_with_delimiter(reach.size)
595
592
  end
596
593
 
597
- desc 'reply TWEET_ID MESSAGE', 'Post your Tweet as a reply directed at another person.'
594
+ desc 'reply TWEET_ID [MESSAGE]', 'Post your Tweet as a reply directed at another person.'
598
595
  method_option 'all', aliases: '-a', type: :boolean, desc: 'Reply to all users mentioned in the Tweet.'
599
596
  method_option 'location', aliases: '-l', type: :string, default: nil, desc: "Add location information. If the optional 'latitude,longitude' parameter is not supplied, looks up location by IP address."
600
597
  method_option 'file', aliases: '-f', type: :string, desc: 'The path to an image to attach to your tweet.'
601
- def reply(status_id, message)
598
+ def reply(status_id, message = nil)
599
+ message = T::Editor.gets if message.to_s.empty?
602
600
  status = client.status(status_id.to_i, include_my_retweet: false)
603
601
  users = Array(status.user.screen_name)
604
602
  if options['all']
@@ -730,7 +728,7 @@ module T
730
728
  say [status.id, csv_formatted_time(status), status.user.screen_name, decode_full_text(status, options['decode_uris']), status.retweet_count, status.favorite_count, strip_tags(status.source), location].to_csv
731
729
  elsif options['long']
732
730
  array = [status.id, ls_formatted_time(status), "@#{status.user.screen_name}", decode_full_text(status, options['decode_uris']).gsub(/\n+/, ' '), status.retweet_count, status.favorite_count, strip_tags(status.source), location]
733
- format = options['format'] || status_headings.size.times.collect { '%s' }
731
+ format = options['format'] || Array.new(status_headings.size) { '%s' }
734
732
  print_table_with_headings([array], status_headings, format)
735
733
  else
736
734
  array = []
@@ -784,7 +782,7 @@ module T
784
782
  method_option 'exclude-hashtags', aliases: '-x', type: :boolean, desc: 'Remove all hashtags from the trends list.'
785
783
  def trends(woe_id = 1)
786
784
  opts = {}
787
- opts.merge!(exclude: 'hashtags') if options['exclude-hashtags']
785
+ opts[:exclude] = 'hashtags' if options['exclude-hashtags']
788
786
  trends = client.trends(woe_id, opts)
789
787
  print_attribute(trends, :name)
790
788
  end
@@ -821,7 +819,7 @@ module T
821
819
  array = places.collect do |place|
822
820
  [place.woeid, place.parent_id, place.place_type, place.name, place.country]
823
821
  end
824
- format = options['format'] || TREND_HEADINGS.size.times.collect { '%s' }
822
+ format = options['format'] || Array.new(TREND_HEADINGS.size) { '%s' }
825
823
  print_table_with_headings(array, TREND_HEADINGS, format)
826
824
  else
827
825
  print_attribute(places, :name)
@@ -844,7 +842,7 @@ module T
844
842
  method_option 'location', aliases: '-l', type: :string, default: nil, desc: "Add location information. If the optional 'latitude,longitude' parameter is not supplied, looks up location by IP address."
845
843
  method_option 'file', aliases: '-f', type: :string, desc: 'The path to an image to attach to your tweet.'
846
844
  def update(message = nil)
847
- message = T::Editor.gets if message.nil? || message.empty?
845
+ message = T::Editor.gets if message.to_s.empty?
848
846
  opts = {trim_user: true}
849
847
  add_location!(options, opts)
850
848
  status = if options['file']
@@ -891,7 +889,7 @@ module T
891
889
  method_option 'id', aliases: '-i', type: :boolean, desc: 'Specify user via ID instead of screen name.'
892
890
  method_option 'long', aliases: '-l', type: :boolean, desc: 'Output in long format.'
893
891
  method_option 'relative_dates', aliases: '-a', type: :boolean, desc: 'Show relative dates.'
894
- def whois(user) # rubocop:disable CyclomaticComplexity
892
+ def whois(user)
895
893
  require 't/core_ext/string'
896
894
  opts = {}
897
895
  opts[:include_entities] = !!options['decode_uris']
@@ -30,9 +30,9 @@ module T
30
30
  end.flatten.compact
31
31
  end
32
32
 
33
- def collect_with_page(collection = ::Set.new, page = 1, previous = nil, &block) # rubocop:disable ParameterLists
33
+ def collect_with_page(collection = ::Set.new, page = 1, previous = nil, &block)
34
34
  tweets = Retryable.retryable(tries: 3, on: Twitter::Error, sleep: 0) do
35
- block.call(page)
35
+ yield page
36
36
  end
37
37
  return collection if tweets.nil? || tweets == previous || page >= MAX_PAGE
38
38
  collection += tweets
@@ -7,7 +7,7 @@ class String
7
7
  tr('@', '')
8
8
  end
9
9
 
10
- alias_method :old_to_i, :to_i
10
+ alias old_to_i to_i
11
11
 
12
12
  def to_i(base = 10)
13
13
  tr(',', '').old_to_i(base)
@@ -42,7 +42,7 @@ module T
42
42
  else
43
43
  direct_message_ids.each do |direct_message_id_to_delete|
44
44
  direct_message = client.direct_message(direct_message_id_to_delete)
45
- return unless yes? "Are you sure you want to permanently delete the direct message to @#{direct_message.recipient.screen_name}: \"#{direct_message.text}\"? [y/N]"
45
+ next unless yes? "Are you sure you want to permanently delete the direct message to @#{direct_message.recipient.screen_name}: \"#{direct_message.text}\"? [y/N]"
46
46
  client.destroy_direct_message(direct_message_id_to_delete)
47
47
  say "@#{@rcfile.active_profile[0]} deleted the direct message sent to @#{direct_message.recipient.screen_name}: \"#{direct_message.text}\""
48
48
  end
@@ -64,7 +64,7 @@ module T
64
64
  else
65
65
  status_ids.each do |status_id_to_unfavorite|
66
66
  status = client.status(status_id_to_unfavorite, include_my_retweet: false)
67
- return unless yes? "Are you sure you want to remove @#{status.user.screen_name}'s status: \"#{status.full_text}\" from your favorites? [y/N]"
67
+ next unless yes? "Are you sure you want to remove @#{status.user.screen_name}'s status: \"#{status.full_text}\" from your favorites? [y/N]"
68
68
  client.unfavorite(status_id_to_unfavorite)
69
69
  say "@#{@rcfile.active_profile[0]} unfavorited @#{status.user.screen_name}'s status: \"#{status.full_text}\""
70
70
  end
@@ -102,11 +102,8 @@ module T
102
102
 
103
103
  desc 'account SCREEN_NAME [CONSUMER_KEY]', 'delete account or consumer key from t'
104
104
  def account(account, key = nil)
105
- if key && @rcfile.profiles[account].keys.length == 1
106
- continue = ask 'There is only one API key associated with this account, removing it will disable all functionality, are you sure you want to delete it? [y/N]'
107
- return if continue.downcase != 'y'
108
- elsif key
109
- return @rcfile.delete_key(account, key)
105
+ if key && @rcfile.profiles[account].keys.size > 1
106
+ @rcfile.delete_key(account, key)
110
107
  else
111
108
  @rcfile.delete_profile(account)
112
109
  end
@@ -126,7 +123,7 @@ module T
126
123
  else
127
124
  status_ids.each do |status_id_to_delete|
128
125
  status = client.status(status_id_to_delete, include_my_retweet: false)
129
- return unless yes? "Are you sure you want to permanently delete @#{status.user.screen_name}'s status: \"#{status.full_text}\"? [y/N]"
126
+ next unless yes? "Are you sure you want to permanently delete @#{status.user.screen_name}'s status: \"#{status.full_text}\"? [y/N]"
130
127
  client.destroy_status(status_id_to_delete, trim_user: true)
131
128
  say "@#{@rcfile.active_profile[0]} deleted the Tweet: \"#{status.full_text}\""
132
129
  end
@@ -8,7 +8,7 @@ module T
8
8
 
9
9
  def initialize(number)
10
10
  # Bottom six bits
11
- @bits = number & 0x3f
11
+ @bits = number & 0x3f
12
12
 
13
13
  # Next highest eight bits
14
14
  @fcolor = (number >> 6) & 0xff
@@ -42,7 +42,7 @@ module T
42
42
  method_option 'private', aliases: '-p', type: :boolean
43
43
  def create(list_name, description = nil)
44
44
  opts = description ? {description: description} : {}
45
- opts.merge!(mode: 'private') if options['private']
45
+ opts[:mode] = 'private' if options['private']
46
46
  client.create_list(list_name, opts)
47
47
  say "@#{@rcfile.active_profile[0]} created the list \"#{list_name}\"."
48
48
  end
@@ -1,8 +1,8 @@
1
1
  module T
2
- module Printable
3
- LIST_HEADINGS = ['ID', 'Created at', 'Screen name', 'Slug', 'Members', 'Subscribers', 'Mode', 'Description']
4
- TWEET_HEADINGS = ['ID', 'Posted at', 'Screen name', 'Text']
5
- USER_HEADINGS = ['ID', 'Since', 'Last tweeted at', 'Tweets', 'Favorites', 'Listed', 'Following', 'Followers', 'Screen name', 'Name', 'Verified', 'Protected', 'Bio', 'Status', 'Location', 'URL']
2
+ module Printable # rubocop:disable ModuleLength
3
+ LIST_HEADINGS = ['ID', 'Created at', 'Screen name', 'Slug', 'Members', 'Subscribers', 'Mode', 'Description'].freeze
4
+ TWEET_HEADINGS = ['ID', 'Posted at', 'Screen name', 'Text'].freeze
5
+ USER_HEADINGS = ['ID', 'Since', 'Last tweeted at', 'Tweets', 'Favorites', 'Listed', 'Following', 'Followers', 'Screen name', 'Name', 'Verified', 'Protected', 'Bio', 'Status', 'Location', 'URL'].freeze
6
6
  MONTH_IN_SECONDS = 2_592_000
7
7
 
8
8
  private
@@ -76,7 +76,7 @@ module T
76
76
  array = lists.collect do |list|
77
77
  build_long_list(list)
78
78
  end
79
- format = options['format'] || LIST_HEADINGS.size.times.collect { '%s' }
79
+ format = options['format'] || Array.new(LIST_HEADINGS.size) { '%s' }
80
80
  print_table_with_headings(array, LIST_HEADINGS, format)
81
81
  else
82
82
  print_attribute(lists, :full_name)
@@ -118,16 +118,14 @@ module T
118
118
  when 'icon'
119
119
  print_identicon(from_user, message)
120
120
  say
121
- say
122
121
  when 'auto'
123
122
  say(" @#{from_user}", [:bold, :yellow])
124
123
  print_wrapped(HTMLEntities.new.decode(message), indent: 3)
125
- say
126
124
  else
127
125
  say(" @#{from_user}")
128
126
  print_wrapped(HTMLEntities.new.decode(message), indent: 3)
129
- say
130
127
  end
128
+ say
131
129
  end
132
130
 
133
131
  def print_identicon(from_user, message)
@@ -138,7 +136,7 @@ module T
138
136
  # Save 6 chars for icon, ensure at least 3 lines long
139
137
  lines = wrapped(HTMLEntities.new.decode(message), indent: 2, width: terminal_width - (6 + 5))
140
138
  lines.unshift(set_color(" @#{from_user}", :bold, :yellow))
141
- lines.push(*(3 - lines.length).times.map { '' })
139
+ lines.push(*Array.new([3 - lines.length, 0].max) { '' })
142
140
 
143
141
  $stdout.puts lines.zip(icon.lines).map { |x, i| " #{i || ' '}#{x}" }
144
142
  end
@@ -173,7 +171,7 @@ module T
173
171
  array = tweets.collect do |tweet|
174
172
  build_long_tweet(tweet)
175
173
  end
176
- format = options['format'] || TWEET_HEADINGS.size.times.collect { '%s' }
174
+ format = options['format'] || Array.new(TWEET_HEADINGS.size) { '%s' }
177
175
  print_table_with_headings(array, TWEET_HEADINGS, format)
178
176
  else
179
177
  tweets.each do |tweet|
@@ -212,7 +210,7 @@ module T
212
210
  array = users.collect do |user|
213
211
  build_long_user(user)
214
212
  end
215
- format = options['format'] || USER_HEADINGS.size.times.collect { '%s' }
213
+ format = options['format'] || Array.new(USER_HEADINGS.size) { '%s' }
216
214
  print_table_with_headings(array, USER_HEADINGS, format)
217
215
  else
218
216
  print_attribute(users, :screen_name)
@@ -4,7 +4,7 @@ module T
4
4
  class RCFile
5
5
  include Singleton
6
6
  attr_reader :path
7
- FILE_NAME = '.trc'
7
+ FILE_NAME = '.trc'.freeze
8
8
 
9
9
  def initialize
10
10
  @path = File.join(File.expand_path('~'), FILE_NAME)
@@ -25,11 +25,11 @@ module T
25
25
  end
26
26
 
27
27
  def find_case_insensitive_match(username)
28
- profiles.keys.detect { |u| username.downcase == u.downcase }
28
+ profiles.keys.detect { |u| username.casecmp(u).zero? }
29
29
  end
30
30
 
31
31
  def find_case_insensitive_possibilities(username)
32
- profiles.keys.select { |u| username.downcase == u.downcase[0, username.length] }
32
+ profiles.keys.select { |u| username.casecmp(u[0, username.length]).zero? }
33
33
  end
34
34
 
35
35
  def []=(username, profile)
@@ -46,7 +46,7 @@ module T
46
46
  array = tweets.collect do |tweet|
47
47
  [tweet.id, ls_formatted_time(tweet), "@#{tweet.user.screen_name}", decode_full_text(tweet, options['decode_uris']).gsub(/\n+/, ' ')]
48
48
  end
49
- format = options['format'] || TWEET_HEADINGS.size.times.collect { '%s' }
49
+ format = options['format'] || Array.new(TWEET_HEADINGS.size) { '%s' }
50
50
  print_table_with_headings(array, TWEET_HEADINGS, format)
51
51
  else
52
52
  say unless tweets.empty?
@@ -15,7 +15,7 @@ module T
15
15
  '%-12s', # Add padding to length of a timestamp formatted with ls_formatted_time
16
16
  '%-20s', # Add padding to maximum length of a Twitter screen name
17
17
  '%s', # Last element does not need special formatting
18
- ]
18
+ ].freeze
19
19
 
20
20
  check_unknown_options!
21
21
 
@@ -34,7 +34,7 @@ module T
34
34
  require 'csv'
35
35
  say TWEET_HEADINGS.to_csv
36
36
  elsif options['long'] && STDOUT.tty?
37
- headings = TWEET_HEADINGS.size.times.collect do |index|
37
+ headings = Array.new(TWEET_HEADINGS.size) do |index|
38
38
  TWEET_HEADINGS_FORMATTING[index] % TWEET_HEADINGS[index]
39
39
  end
40
40
  print_table([headings])
@@ -170,7 +170,7 @@ module T
170
170
  require 'csv'
171
171
  say TWEET_HEADINGS.to_csv
172
172
  elsif options['long'] && STDOUT.tty?
173
- headings = TWEET_HEADINGS.size.times.collect do |index|
173
+ headings = Array.new(TWEET_HEADINGS.size) do |index|
174
174
  TWEET_HEADINGS_FORMATTING[index] % TWEET_HEADINGS[index]
175
175
  end
176
176
  print_table([headings])
@@ -44,8 +44,8 @@ module T
44
44
  format('%d years', (minutes.to_f / 525_600.0).round)
45
45
  end
46
46
  end
47
- alias_method :time_ago_in_words, :distance_of_time_in_words
48
- alias_method :time_from_now_in_words, :distance_of_time_in_words
47
+ alias time_ago_in_words distance_of_time_in_words
48
+ alias time_from_now_in_words distance_of_time_in_words
49
49
 
50
50
  def fetch_users(users, options)
51
51
  format_users!(users, options)
@@ -1,7 +1,7 @@
1
1
  module T
2
2
  class Version
3
3
  MAJOR = 2
4
- MINOR = 9
4
+ MINOR = 10
5
5
  PATCH = 0
6
6
  PRE = nil
7
7
 
data/t.gemspec CHANGED
@@ -5,12 +5,12 @@ require 't/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.add_dependency 'launchy', '~> 2.4'
8
- spec.add_dependency 'geokit', ['>= 1.8.3', '< 2']
8
+ spec.add_dependency 'geokit', '~> 1.9'
9
9
  spec.add_dependency 'htmlentities', '~> 4.3'
10
10
  spec.add_dependency 'oauth', '~> 0.4.7'
11
11
  spec.add_dependency 'retryable', '~> 2.0'
12
12
  spec.add_dependency 'thor', ['>= 0.19.1', '< 2']
13
- spec.add_dependency 'twitter', '~> 5.13'
13
+ spec.add_dependency 'twitter', '~> 5.16'
14
14
  spec.add_development_dependency 'bundler', '~> 1.0'
15
15
  spec.author = 'Erik Michaels-Ober'
16
16
  spec.description = 'A command-line power tool for Twitter.'
@@ -22,7 +22,6 @@ Gem::Specification.new do |spec|
22
22
  spec.name = 't'
23
23
  spec.require_paths = %w(lib)
24
24
  spec.required_ruby_version = '>= 1.9.3'
25
- spec.required_rubygems_version = '>= 1.3.5'
26
25
  spec.summary = 'CLI for Twitter'
27
26
  spec.version = T::Version
28
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: t
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.9.0
4
+ version: 2.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erik Michaels-Ober
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-20 00:00:00.000000000 Z
11
+ date: 2016-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: launchy
@@ -28,22 +28,16 @@ dependencies:
28
28
  name: geokit
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: 1.8.3
34
- - - "<"
31
+ - - "~>"
35
32
  - !ruby/object:Gem::Version
36
- version: '2'
33
+ version: '1.9'
37
34
  type: :runtime
38
35
  prerelease: false
39
36
  version_requirements: !ruby/object:Gem::Requirement
40
37
  requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- version: 1.8.3
44
- - - "<"
38
+ - - "~>"
45
39
  - !ruby/object:Gem::Version
46
- version: '2'
40
+ version: '1.9'
47
41
  - !ruby/object:Gem::Dependency
48
42
  name: htmlentities
49
43
  requirement: !ruby/object:Gem::Requirement
@@ -112,14 +106,14 @@ dependencies:
112
106
  requirements:
113
107
  - - "~>"
114
108
  - !ruby/object:Gem::Version
115
- version: '5.13'
109
+ version: '5.16'
116
110
  type: :runtime
117
111
  prerelease: false
118
112
  version_requirements: !ruby/object:Gem::Requirement
119
113
  requirements:
120
114
  - - "~>"
121
115
  - !ruby/object:Gem::Version
122
- version: '5.13'
116
+ version: '5.16'
123
117
  - !ruby/object:Gem::Dependency
124
118
  name: bundler
125
119
  requirement: !ruby/object:Gem::Requirement
@@ -180,10 +174,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
180
174
  requirements:
181
175
  - - ">="
182
176
  - !ruby/object:Gem::Version
183
- version: 1.3.5
177
+ version: '0'
184
178
  requirements: []
185
179
  rubyforge_project:
186
- rubygems_version: 2.4.5
180
+ rubygems_version: 2.5.1
187
181
  signing_key:
188
182
  specification_version: 4
189
183
  summary: CLI for Twitter