t 3.1.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/t/printable.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module T
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
2
+ module Printable # rubocop:disable Metrics/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
@@ -12,73 +12,75 @@ module T
12
12
  end
13
13
 
14
14
  def build_long_tweet(tweet)
15
- [tweet.id, ls_formatted_time(tweet), "@#{tweet.user.screen_name}", decode_full_text(tweet, options['decode_uris']).gsub(/\n+/, ' ')]
15
+ [tweet.id, ls_formatted_time(tweet), "@#{tweet.user.screen_name}", decode_full_text(tweet, options["decode_uris"]).gsub(/\n+/, " ")]
16
16
  end
17
17
 
18
18
  def build_long_user(user)
19
- [user.id, ls_formatted_time(user), ls_formatted_time(user.status), user.statuses_count, user.favorites_count, user.listed_count, user.friends_count, user.followers_count, "@#{user.screen_name}", user.name, user.verified? ? 'Yes' : 'No', user.protected? ? 'Yes' : 'No', user.description.gsub(/\n+/, ' '), user.status? ? decode_full_text(user.status, options['decode_uris']).gsub(/\n+/, ' ') : nil, user.location, user.website.to_s]
19
+ [user.id, ls_formatted_time(user), ls_formatted_time(user.status), user.statuses_count, user.favorites_count, user.listed_count, user.friends_count, user.followers_count, "@#{user.screen_name}", user.name, user.verified? ? "Yes" : "No", user.protected? ? "Yes" : "No", user.description.gsub(/\n+/, " "), user.status? ? decode_full_text(user.status, options["decode_uris"]).gsub(/\n+/, " ") : nil, user.location, user.website.to_s]
20
20
  end
21
21
 
22
22
  def csv_formatted_time(object, key = :created_at)
23
23
  return nil if object.nil?
24
+
24
25
  time = object.send(key.to_sym).dup
25
- time.utc.strftime('%Y-%m-%d %H:%M:%S %z')
26
+ time.utc.strftime("%Y-%m-%d %H:%M:%S %z")
26
27
  end
27
28
 
28
29
  def ls_formatted_time(object, key = :created_at, allow_relative = true)
29
- return '' if object.nil?
30
+ return "" if object.nil?
31
+
30
32
  time = T.local_time(object.send(key.to_sym))
31
- if allow_relative && options['relative_dates']
32
- distance_of_time_in_words(time) + ' ago'
33
- elsif time > Time.now - MONTH_IN_SECONDS * 6
34
- time.strftime('%b %e %H:%M')
33
+ if allow_relative && options["relative_dates"]
34
+ "#{distance_of_time_in_words(time)} ago"
35
+ elsif time > Time.now - (MONTH_IN_SECONDS * 6)
36
+ time.strftime("%b %e %H:%M")
35
37
  else
36
- time.strftime('%b %e %Y')
38
+ time.strftime("%b %e %Y")
37
39
  end
38
40
  end
39
41
 
40
42
  def print_csv_list(list)
41
- require 'csv'
43
+ require "csv"
42
44
  say [list.id, csv_formatted_time(list), list.user.screen_name, list.slug, list.member_count, list.subscriber_count, list.mode, list.description].to_csv
43
45
  end
44
46
 
45
47
  def print_csv_tweet(tweet)
46
- require 'csv'
47
- say [tweet.id, csv_formatted_time(tweet), tweet.user.screen_name, decode_full_text(tweet, options['decode_uris'])].to_csv
48
+ require "csv"
49
+ say [tweet.id, csv_formatted_time(tweet), tweet.user.screen_name, decode_full_text(tweet, options["decode_uris"])].to_csv
48
50
  end
49
51
 
50
52
  def print_csv_user(user)
51
- require 'csv'
53
+ require "csv"
52
54
  say [user.id, csv_formatted_time(user), csv_formatted_time(user.status), user.statuses_count, user.favorites_count, user.listed_count, user.friends_count, user.followers_count, user.screen_name, user.name, user.verified?, user.protected?, user.description, user.status? ? user.status.full_text : nil, user.location, user.website].to_csv
53
55
  end
54
56
 
55
57
  def print_lists(lists)
56
- unless options['unsorted']
57
- lists = case options['sort']
58
- when 'members'
58
+ unless options["unsorted"]
59
+ lists = case options["sort"]
60
+ when "members"
59
61
  lists.sort_by(&:member_count)
60
- when 'mode'
62
+ when "mode"
61
63
  lists.sort_by(&:mode)
62
- when 'since'
64
+ when "since"
63
65
  lists.sort_by(&:created_at)
64
- when 'subscribers'
66
+ when "subscribers"
65
67
  lists.sort_by(&:subscriber_count)
66
68
  else
67
69
  lists.sort_by { |list| list.slug.downcase }
68
70
  end
69
71
  end
70
- lists.reverse! if options['reverse']
71
- if options['csv']
72
- require 'csv'
72
+ lists.reverse! if options["reverse"]
73
+ if options["csv"]
74
+ require "csv"
73
75
  say LIST_HEADINGS.to_csv unless lists.empty?
74
76
  lists.each do |list|
75
77
  print_csv_list(list)
76
78
  end
77
- elsif options['long']
79
+ elsif options["long"]
78
80
  array = lists.collect do |list|
79
81
  build_long_list(list)
80
82
  end
81
- format = options['format'] || Array.new(LIST_HEADINGS.size) { '%s' }
83
+ format = options["format"] || Array.new(LIST_HEADINGS.size) { "%s" }
82
84
  print_table_with_headings(array, LIST_HEADINGS, format)
83
85
  else
84
86
  print_attribute(lists, :full_name)
@@ -97,12 +99,14 @@ module T
97
99
 
98
100
  def print_table_with_headings(array, headings, format)
99
101
  return if array.flatten.empty?
102
+
100
103
  if STDOUT.tty?
101
104
  array.unshift(headings)
102
- require 't/core_ext/kernel'
105
+ require "t/core_ext/kernel"
103
106
  array.collect! do |row|
104
107
  row.each_with_index.collect do |element, index|
105
108
  next if element.nil?
109
+
106
110
  Kernel.send(element.class.name.to_sym, format[index] % element)
107
111
  end
108
112
  end
@@ -114,14 +118,14 @@ module T
114
118
  end
115
119
 
116
120
  def print_message(from_user, message)
117
- require 'htmlentities'
121
+ require "htmlentities"
118
122
 
119
- case options['color']
120
- when 'icon'
123
+ case options["color"]
124
+ when "icon"
121
125
  print_identicon(from_user, message)
122
126
  say
123
- when 'auto'
124
- say(" @#{from_user}", [:bold, :yellow])
127
+ when "auto"
128
+ say(" @#{from_user}", %i[bold yellow])
125
129
  print_wrapped(HTMLEntities.new.decode(message), indent: 3)
126
130
  else
127
131
  say(" @#{from_user}")
@@ -131,30 +135,30 @@ module T
131
135
  end
132
136
 
133
137
  def print_identicon(from_user, message)
134
- require 'htmlentities'
135
- require 't/identicon'
138
+ require "htmlentities"
139
+ require "t/identicon"
136
140
  icon = Identicon.for_user_name(from_user)
137
141
 
138
142
  # Save 6 chars for icon, ensure at least 3 lines long
139
143
  lines = wrapped(HTMLEntities.new.decode(message), indent: 2, width: terminal_width - (6 + 5))
140
144
  lines.unshift(set_color(" @#{from_user}", :bold, :yellow))
141
- lines.concat(Array.new([3 - lines.length, 0].max) { '' })
145
+ lines.concat(Array.new([3 - lines.length, 0].max) { "" })
142
146
 
143
- $stdout.puts lines.zip(icon.lines).map { |x, i| " #{i || ' '}#{x}" }
147
+ $stdout.puts(lines.zip(icon.lines).map { |x, i| " #{i || ' '}#{x}" })
144
148
  end
145
149
 
146
150
  def wrapped(message, options = {})
147
151
  indent = options[:indent] || 0
148
- width = options[:width] || terminal_width - indent
152
+ width = options[:width] || (terminal_width - indent)
149
153
  paras = message.split("\n\n")
150
154
 
151
155
  paras.map! do |unwrapped|
152
- unwrapped.strip.squeeze(' ').gsub(/.{1,#{width}}(?:\s|\Z)/) { ($& + 5.chr).gsub(/\n\005/, "\n").gsub(/\005/, "\n") }
156
+ unwrapped.strip.squeeze(" ").gsub(/.{1,#{width}}(?:\s|\Z)/) { (::Regexp.last_match(0) + 5.chr).gsub(/\n\005/, "\n").gsub(/\005/, "\n") }
153
157
  end
154
158
 
155
159
  lines = paras.inject([]) do |memo, para|
156
- memo.concat(para.split("\n").map { |line| line.insert(0, ' ' * indent) })
157
- memo.push ''
160
+ memo.concat(para.split("\n").map { |line| line.insert(0, " " * indent) })
161
+ memo.push ""
158
162
  end
159
163
 
160
164
  lines.pop
@@ -162,59 +166,59 @@ module T
162
166
  end
163
167
 
164
168
  def print_tweets(tweets)
165
- tweets.reverse! if options['reverse']
166
- if options['csv']
167
- require 'csv'
169
+ tweets.reverse! if options["reverse"]
170
+ if options["csv"]
171
+ require "csv"
168
172
  say TWEET_HEADINGS.to_csv unless tweets.empty?
169
173
  tweets.each do |tweet|
170
174
  print_csv_tweet(tweet)
171
175
  end
172
- elsif options['long']
176
+ elsif options["long"]
173
177
  array = tweets.collect do |tweet|
174
178
  build_long_tweet(tweet)
175
179
  end
176
- format = options['format'] || Array.new(TWEET_HEADINGS.size) { '%s' }
180
+ format = options["format"] || Array.new(TWEET_HEADINGS.size) { "%s" }
177
181
  print_table_with_headings(array, TWEET_HEADINGS, format)
178
182
  else
179
183
  tweets.each do |tweet|
180
- print_message(tweet.user.screen_name, decode_uris(tweet.full_text, options['decode_uris'] ? tweet.uris : nil))
184
+ print_message(tweet.user.screen_name, decode_uris(tweet.full_text, options["decode_uris"] ? tweet.uris : nil))
181
185
  end
182
186
  end
183
187
  end
184
188
 
185
- def print_users(users) # rubocop:disable CyclomaticComplexity
186
- unless options['unsorted']
187
- users = case options['sort']
188
- when 'favorites'
189
+ def print_users(users) # rubocop:disable Metrics/CyclomaticComplexity
190
+ unless options["unsorted"]
191
+ users = case options["sort"]
192
+ when "favorites"
189
193
  users.sort_by { |user| user.favorites_count.to_i }
190
- when 'followers'
194
+ when "followers"
191
195
  users.sort_by { |user| user.followers_count.to_i }
192
- when 'friends'
196
+ when "friends"
193
197
  users.sort_by { |user| user.friends_count.to_i }
194
- when 'listed'
198
+ when "listed"
195
199
  users.sort_by { |user| user.listed_count.to_i }
196
- when 'since'
200
+ when "since"
197
201
  users.sort_by(&:created_at)
198
- when 'tweets'
202
+ when "tweets"
199
203
  users.sort_by { |user| user.statuses_count.to_i }
200
- when 'tweeted'
201
- users.sort_by { |user| user.status? ? user.status.created_at : Time.at(0) } # rubocop:disable BlockNesting
204
+ when "tweeted"
205
+ users.sort_by { |user| user.status? ? user.status.created_at : Time.at(0) } # rubocop:disable Metrics/BlockNesting
202
206
  else
203
207
  users.sort_by { |user| user.screen_name.downcase }
204
208
  end
205
209
  end
206
- users.reverse! if options['reverse']
207
- if options['csv']
208
- require 'csv'
210
+ users.reverse! if options["reverse"]
211
+ if options["csv"]
212
+ require "csv"
209
213
  say USER_HEADINGS.to_csv unless users.empty?
210
214
  users.each do |user|
211
215
  print_csv_user(user)
212
216
  end
213
- elsif options['long']
217
+ elsif options["long"]
214
218
  array = users.collect do |user|
215
219
  build_long_user(user)
216
220
  end
217
- format = options['format'] || Array.new(USER_HEADINGS.size) { '%s' }
221
+ format = options["format"] || Array.new(USER_HEADINGS.size) { "%s" }
218
222
  print_table_with_headings(array, USER_HEADINGS, format)
219
223
  else
220
224
  print_attribute(users, :screen_name)
data/lib/t/rcfile.rb CHANGED
@@ -1,13 +1,14 @@
1
- require 'singleton'
1
+ require "singleton"
2
2
 
3
3
  module T
4
4
  class RCFile
5
5
  include Singleton
6
6
  attr_reader :path
7
- FILE_NAME = '.trc'.freeze
7
+
8
+ FILE_NAME = ".trc".freeze
8
9
 
9
10
  def initialize
10
- @path = File.join(File.expand_path('~'), FILE_NAME)
11
+ @path = File.join(File.expand_path("~"), FILE_NAME)
11
12
  @data = load_file
12
13
  end
13
14
 
@@ -17,7 +18,8 @@ module T
17
18
 
18
19
  def find(username)
19
20
  possibilities = Array(find_case_insensitive_match(username) || find_case_insensitive_possibilities(username))
20
- raise(ArgumentError.new("Username #{username} is #{possibilities.empty? ? 'not found.' : 'ambiguous, matching ' + possibilities.join(', ')}")) unless possibilities.size == 1
21
+ raise(ArgumentError.new("Username #{username} is #{possibilities.empty? ? 'not found.' : "ambiguous, matching #{possibilities.join(', ')}"}")) unless possibilities.size == 1
22
+
21
23
  possibilities.first
22
24
  end
23
25
 
@@ -36,36 +38,36 @@ module T
36
38
  end
37
39
 
38
40
  def configuration
39
- @data['configuration']
41
+ @data["configuration"]
40
42
  end
41
43
 
42
44
  def active_consumer_key
43
- profiles[active_profile[0]][active_profile[1]]['consumer_key'] if active_profile?
45
+ profiles[active_profile[0]][active_profile[1]]["consumer_key"] if active_profile?
44
46
  end
45
47
 
46
48
  def active_consumer_secret
47
- profiles[active_profile[0]][active_profile[1]]['consumer_secret'] if active_profile?
49
+ profiles[active_profile[0]][active_profile[1]]["consumer_secret"] if active_profile?
48
50
  end
49
51
 
50
52
  def active_profile
51
- configuration['default_profile']
53
+ configuration["default_profile"]
52
54
  end
53
55
 
54
56
  def active_profile=(profile)
55
- configuration['default_profile'] = [profile['username'], profile['consumer_key']]
57
+ configuration["default_profile"] = [profile["username"], profile["consumer_key"]]
56
58
  write
57
59
  end
58
60
 
59
61
  def active_secret
60
- profiles[active_profile[0]][active_profile[1]]['secret'] if active_profile?
62
+ profiles[active_profile[0]][active_profile[1]]["secret"] if active_profile?
61
63
  end
62
64
 
63
65
  def active_token
64
- profiles[active_profile[0]][active_profile[1]]['token'] if active_profile?
66
+ profiles[active_profile[0]][active_profile[1]]["token"] if active_profile?
65
67
  end
66
68
 
67
69
  def delete
68
- File.delete(@path) if File.exist?(@path)
70
+ FileUtils.rm_f(@path)
69
71
  end
70
72
 
71
73
  def empty?
@@ -73,7 +75,7 @@ module T
73
75
  end
74
76
 
75
77
  def load_file
76
- require 'yaml'
78
+ require "yaml"
77
79
  YAML.load_file(@path)
78
80
  rescue Errno::ENOENT
79
81
  default_structure
@@ -82,11 +84,10 @@ module T
82
84
  def path=(path)
83
85
  @path = path
84
86
  @data = load_file
85
- @path
86
87
  end
87
88
 
88
89
  def profiles
89
- @data['profiles']
90
+ @data["profiles"]
90
91
  end
91
92
 
92
93
  def reset
@@ -110,11 +111,11 @@ module T
110
111
  end
111
112
 
112
113
  def default_structure
113
- {'configuration' => {}, 'profiles' => {}}
114
+ {"configuration" => {}, "profiles" => {}}
114
115
  end
115
116
 
116
117
  def write
117
- require 'yaml'
118
+ require "yaml"
118
119
  File.open(@path, File::RDWR | File::TRUNC | File::CREAT, 0o0600) do |rcfile|
119
120
  rcfile.write @data.to_yaml
120
121
  end
data/lib/t/requestable.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'twitter'
1
+ require "twitter"
2
2
 
3
3
  module T
4
4
  module Requestable
@@ -6,7 +6,8 @@ module T
6
6
 
7
7
  def client
8
8
  return @client if @client
9
- @rcfile.path = options['profile'] if options['profile']
9
+
10
+ @rcfile.path = options["profile"] if options["profile"]
10
11
  @client = Twitter::REST::Client.new do |config|
11
12
  config.consumer_key = @rcfile.active_consumer_key
12
13
  config.consumer_secret = @rcfile.active_consumer_secret