t 4.1.1 → 5.0.0

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/lib/t/stream.rb CHANGED
@@ -17,6 +17,8 @@ module T
17
17
  "%s", # Last element does not need special formatting
18
18
  ].freeze
19
19
 
20
+ STREAM_FIELDS = "tweet.fields=author_id,created_at,entities,text&expansions=author_id&user.fields=username,name".freeze
21
+
20
22
  check_unknown_options!
21
23
 
22
24
  def initialize(*)
@@ -29,31 +31,8 @@ module T
29
31
  method_option "decode_uris", aliases: "-d", type: :boolean, desc: "Decodes t.co URLs into their original form."
30
32
  method_option "long", aliases: "-l", type: :boolean, desc: "Output in long format."
31
33
  def all
32
- streaming_client.before_request do
33
- if options["csv"]
34
- require "csv"
35
- say TWEET_HEADINGS.to_csv
36
- elsif options["long"] && STDOUT.tty?
37
- headings = Array.new(TWEET_HEADINGS.size) do |index|
38
- TWEET_HEADINGS_FORMATTING[index] % TWEET_HEADINGS[index]
39
- end
40
- print_table([headings])
41
- end
42
- end
43
- streaming_client.sample do |tweet|
44
- next unless tweet.is_a?(Twitter::Tweet)
45
-
46
- if options["csv"]
47
- print_csv_tweet(tweet)
48
- elsif options["long"]
49
- array = build_long_tweet(tweet).each_with_index.collect do |element, index|
50
- TWEET_HEADINGS_FORMATTING[index] % element
51
- end
52
- print_table([array], truncate: STDOUT.tty?)
53
- else
54
- print_message(tweet.user.screen_name, tweet.text)
55
- end
56
- end
34
+ print_stream_headings
35
+ stream_tweets("tweets/sample/stream") { |tweet| print_stream_tweet(tweet) }
57
36
  end
58
37
 
59
38
  desc "list [USER/]LIST", "Stream a timeline for members of the specified list (Control-C to stop)"
@@ -65,43 +44,29 @@ module T
65
44
  def list(user_list)
66
45
  owner, list_name = extract_owner(user_list, options)
67
46
  require "t/list"
68
- streaming_client.before_request do
69
- list = T::List.new
70
- list.options = list.options.merge(options)
71
- list.options = list.options.merge(reverse: true)
72
- list.options = list.options.merge(format: TWEET_HEADINGS_FORMATTING)
73
- list.timeline(user_list)
74
- end
75
- user_ids = client.list_members(owner, list_name).collect(&:id)
76
- streaming_client.filter(follow: user_ids.join(",")) do |tweet|
77
- next unless tweet.is_a?(Twitter::Tweet)
78
-
79
- if options["csv"]
80
- print_csv_tweet(tweet)
81
- elsif options["long"]
82
- array = build_long_tweet(tweet).each_with_index.collect do |element, index|
83
- TWEET_HEADINGS_FORMATTING[index] % element
84
- end
85
- print_table([array], truncate: STDOUT.tty?)
86
- else
87
- print_message(tweet.user.screen_name, tweet.text)
88
- end
89
- end
47
+ list_obj = T::List.new
48
+ list_obj.options = list_obj.options.merge(options)
49
+ list_obj.options = list_obj.options.merge(reverse: true)
50
+ list_obj.options = list_obj.options.merge(format: TWEET_HEADINGS_FORMATTING)
51
+ list_obj.timeline(user_list)
52
+ members = fetch_list_members_v1(owner, list_name)
53
+ user_ids = members.collect { |member| member["id"] }
54
+ rule_ids = setup_stream_rules([{value: user_ids.map { |id| "from:#{id}" }.join(" OR ")}])
55
+ stream_tweets("tweets/search/stream") { |tweet| print_stream_tweet(tweet) }
56
+ ensure
57
+ remove_stream_rules(rule_ids || [])
90
58
  end
91
59
  map %w[tl] => :timeline
92
60
 
93
61
  desc "matrix", "Unfortunately, no one can be told what the Matrix is. You have to see it for yourself."
94
62
  def matrix
95
- require "t/cli"
96
- streaming_client.before_request do
97
- cli = T::CLI.new
98
- cli.matrix
99
- end
100
- streaming_client.sample(language: "ja") do |tweet|
101
- next unless tweet.is_a?(Twitter::Tweet)
102
-
103
- say(tweet.text.gsub(/[^\u3000\u3040-\u309f]/, "").reverse, %i[bold green on_black], false)
63
+ rule_ids = setup_stream_rules([{value: "の lang:ja"}])
64
+ stream_tweets("tweets/search/stream") do |tweet|
65
+ text = (tweet["text"] || tweet["full_text"] || "").gsub(/[^\u3000\u3040-\u309f]/, "").reverse
66
+ say(text, %i[bold green on_black], false) unless text.empty?
104
67
  end
68
+ ensure
69
+ remove_stream_rules(rule_ids || [])
105
70
  end
106
71
 
107
72
  desc "search KEYWORD [KEYWORD...]", "Stream Tweets that contain specified keywords, joined with logical ORs (Control-C to stop)"
@@ -111,27 +76,15 @@ module T
111
76
  def search(keyword, *keywords)
112
77
  keywords.unshift(keyword)
113
78
  require "t/search"
114
- streaming_client.before_request do
115
- search = T::Search.new
116
- search.options = search.options.merge(options)
117
- search.options = search.options.merge(reverse: true)
118
- search.options = search.options.merge(format: TWEET_HEADINGS_FORMATTING)
119
- search.all(keywords.join(" OR "))
120
- end
121
- streaming_client.filter(track: keywords.join(",")) do |tweet|
122
- next unless tweet.is_a?(Twitter::Tweet)
123
-
124
- if options["csv"]
125
- print_csv_tweet(tweet)
126
- elsif options["long"]
127
- array = build_long_tweet(tweet).each_with_index.collect do |element, index|
128
- TWEET_HEADINGS_FORMATTING[index] % element
129
- end
130
- print_table([array], truncate: STDOUT.tty?)
131
- else
132
- print_message(tweet.user.screen_name, tweet.text)
133
- end
134
- end
79
+ search_obj = T::Search.new
80
+ search_obj.options = search_obj.options.merge(options)
81
+ search_obj.options = search_obj.options.merge(reverse: true)
82
+ search_obj.options = search_obj.options.merge(format: TWEET_HEADINGS_FORMATTING)
83
+ search_obj.all(keywords.join(" OR "))
84
+ rule_ids = setup_stream_rules([{value: keywords.join(" OR ")}])
85
+ stream_tweets("tweets/search/stream") { |tweet| print_stream_tweet(tweet) }
86
+ ensure
87
+ remove_stream_rules(rule_ids || [])
135
88
  end
136
89
 
137
90
  desc "timeline", "Stream your timeline (Control-C to stop)"
@@ -140,27 +93,16 @@ module T
140
93
  method_option "long", aliases: "-l", type: :boolean, desc: "Output in long format."
141
94
  def timeline
142
95
  require "t/cli"
143
- streaming_client.before_request do
144
- cli = T::CLI.new
145
- cli.options = cli.options.merge(options)
146
- cli.options = cli.options.merge(reverse: true)
147
- cli.options = cli.options.merge(format: TWEET_HEADINGS_FORMATTING)
148
- cli.timeline
149
- end
150
- streaming_client.user do |tweet|
151
- next unless tweet.is_a?(Twitter::Tweet)
152
-
153
- if options["csv"]
154
- print_csv_tweet(tweet)
155
- elsif options["long"]
156
- array = build_long_tweet(tweet).each_with_index.collect do |element, index|
157
- TWEET_HEADINGS_FORMATTING[index] % element
158
- end
159
- print_table([array], truncate: STDOUT.tty?)
160
- else
161
- print_message(tweet.user.screen_name, tweet.text)
162
- end
163
- end
96
+ cli = T::CLI.new
97
+ cli.options = cli.options.merge(options)
98
+ cli.options = cli.options.merge(reverse: true)
99
+ cli.options = cli.options.merge(format: TWEET_HEADINGS_FORMATTING)
100
+ cli.timeline
101
+ username = @rcfile.active_profile[0]
102
+ rule_ids = setup_stream_rules([{value: "from:#{username} OR to:#{username}"}])
103
+ stream_tweets("tweets/search/stream") { |tweet| print_stream_tweet(tweet) }
104
+ ensure
105
+ remove_stream_rules(rule_ids || [])
164
106
  end
165
107
 
166
108
  desc "users USER_ID [USER_ID...]", "Stream Tweets either from or in reply to specified users (Control-C to stop)"
@@ -170,45 +112,63 @@ module T
170
112
  def users(user_id, *user_ids)
171
113
  user_ids.unshift(user_id)
172
114
  user_ids.collect!(&:to_i)
173
- streaming_client.before_request do
174
- if options["csv"]
175
- require "csv"
176
- say TWEET_HEADINGS.to_csv
177
- elsif options["long"] && STDOUT.tty?
178
- headings = Array.new(TWEET_HEADINGS.size) do |index|
179
- TWEET_HEADINGS_FORMATTING[index] % TWEET_HEADINGS[index]
180
- end
181
- print_table([headings])
182
- end
183
- end
184
- streaming_client.filter(follow: user_ids.join(",")) do |tweet|
185
- next unless tweet.is_a?(Twitter::Tweet)
186
-
187
- if options["csv"]
188
- print_csv_tweet(tweet)
189
- elsif options["long"]
190
- array = build_long_tweet(tweet).each_with_index.collect do |element, index|
191
- TWEET_HEADINGS_FORMATTING[index] % element
192
- end
193
- print_table([array], truncate: STDOUT.tty?)
194
- else
195
- print_message(tweet.user.screen_name, tweet.text)
196
- end
197
- end
115
+ print_stream_headings
116
+ rule_ids = setup_stream_rules([{value: user_ids.map { |id| "from:#{id}" }.join(" OR ")}])
117
+ stream_tweets("tweets/search/stream") { |tweet| print_stream_tweet(tweet) }
118
+ ensure
119
+ remove_stream_rules(rule_ids || [])
198
120
  end
199
121
 
200
122
  private
201
123
 
202
- def streaming_client
203
- return @streaming_client if @streaming_client
124
+ def stream_tweets(endpoint)
125
+ bearer_client.stream("#{endpoint}?#{STREAM_FIELDS}") do |json|
126
+ tweet = extract_tweets(json).first
127
+ yield tweet if tweet
128
+ end
129
+ end
204
130
 
205
- @rcfile.path = options["profile"] if options["profile"]
206
- @streaming_client = Twitter::Streaming::Client.new do |config|
207
- config.consumer_key = @rcfile.active_consumer_key
208
- config.consumer_secret = @rcfile.active_consumer_secret
209
- config.access_token = @rcfile.active_token
210
- config.access_token_secret = @rcfile.active_secret
131
+ def setup_stream_rules(rules)
132
+ response = t_post_bearer_json("tweets/search/stream/rules", add: rules)
133
+ (response["data"] || []).filter_map { |rule| rule["id"] }
134
+ end
135
+
136
+ def remove_stream_rules(rule_ids)
137
+ return if rule_ids.empty?
138
+
139
+ t_post_bearer_json("tweets/search/stream/rules", delete: {ids: rule_ids})
140
+ end
141
+
142
+ def print_stream_headings
143
+ if options["csv"]
144
+ require "csv"
145
+ say TWEET_HEADINGS.to_csv
146
+ elsif options["long"] && $stdout.tty?
147
+ headings = Array.new(TWEET_HEADINGS.size) do |index|
148
+ TWEET_HEADINGS_FORMATTING[index] % TWEET_HEADINGS[index]
149
+ end
150
+ print_table([headings])
151
+ end
152
+ end
153
+
154
+ def print_stream_tweet(tweet)
155
+ if options["csv"]
156
+ print_csv_tweet(tweet)
157
+ elsif options["long"]
158
+ array = build_long_tweet(tweet).each_with_index.collect do |element, index|
159
+ TWEET_HEADINGS_FORMATTING[index] % element
160
+ end
161
+ print_table([array], truncate: $stdout.tty?)
162
+ else
163
+ print_message(tweet["user"]["screen_name"], tweet["text"])
211
164
  end
212
165
  end
166
+
167
+ def fetch_list_members_v1(owner, slug)
168
+ client # ensure v1_client is initialized
169
+ params = URI.encode_www_form(cursor: -1, owner_screen_name: owner, slug: slug)
170
+ response = v1_client.get("lists/members.json?#{params}")
171
+ response["users"] || []
172
+ end
213
173
  end
214
174
  end
data/lib/t/utils.rb CHANGED
@@ -1,48 +1,36 @@
1
1
  module T
2
2
  module Utils
3
+ # https://github.com/rails/rails/blob/bd8a970/actionpack/lib/action_view/helpers/date_helper.rb
4
+ DISTANCE_THRESHOLDS = [
5
+ [2, "a minute"],
6
+ [60, ->(m) { format("%<minutes>d minutes", minutes: m) }],
7
+ [120, "an hour"],
8
+ [1410, ->(m) { format("%<hours>d hours", hours: (m.to_f / 60.0).round) }],
9
+ [2880, "a day"],
10
+ [42_480, ->(m) { format("%<days>d days", days: (m.to_f / 1440.0).round) }],
11
+ [86_400, "a month"],
12
+ [503_700, ->(m) { format("%<months>d months", months: (m.to_f / 43_800.0).round) }],
13
+ [1_051_200, "a year"],
14
+ ].freeze
15
+
3
16
  private
4
17
 
5
- # https://github.com/rails/rails/blob/bd8a970/actionpack/lib/action_view/helpers/date_helper.rb
6
- def distance_of_time_in_words(from_time, to_time = Time.now) # rubocop:disable Metrics/CyclomaticComplexity
18
+ def distance_of_time_in_words(from_time, to_time = Time.now)
7
19
  seconds = (to_time - from_time).abs
8
20
  minutes = seconds / 60
9
- case minutes
10
- when 0...1
11
- case seconds
12
- when 0...1
13
- "a split second"
14
- when 1...2
15
- "a second"
16
- when 2...60
17
- format("%<seconds>d seconds", seconds:)
18
- end
19
- when 1...2
20
- "a minute"
21
- when 2...60
22
- format("%<minutes>d minutes", minutes:)
23
- when 60...120
24
- "an hour"
25
- # 120 minutes up to 23.5 hours
26
- when 120...1410
27
- format("%<hours>d hours", hours: (minutes.to_f / 60.0).round)
28
- # 23.5 hours up to 48 hours
29
- when 1410...2880
30
- "a day"
31
- # 48 hours up to 29.5 days
32
- when 2880...42_480
33
- format("%<days>d days", days: (minutes.to_f / 1440.0).round)
34
- # 29.5 days up to 60 days
35
- when 42_480...86_400
36
- "a month"
37
- # 60 days up to 11.5 months
38
- when 86_400...503_700
39
- format("%<months>d months", months: (minutes.to_f / 43_800.0).round)
40
- # 11.5 months up to 2 years
41
- when 503_700...1_051_200
42
- "a year"
43
- else
44
- format("%<years>d years", years: (minutes.to_f / 525_600.0).round)
21
+ return distance_in_seconds(seconds) if minutes < 1
22
+
23
+ DISTANCE_THRESHOLDS.each do |threshold, result|
24
+ return (result.is_a?(Proc) ? result.call(minutes) : result) if minutes < threshold
45
25
  end
26
+ format("%<years>d years", years: (minutes.to_f / 525_600.0).round)
27
+ end
28
+
29
+ def distance_in_seconds(seconds)
30
+ return "a split second" if seconds < 1
31
+ return "a second" if seconds < 2
32
+
33
+ format("%<seconds>d seconds", seconds:)
46
34
  end
47
35
  alias time_ago_in_words distance_of_time_in_words
48
36
  alias time_from_now_in_words distance_of_time_in_words
@@ -50,15 +38,14 @@ module T
50
38
  def fetch_users(users, options)
51
39
  format_users!(users, options)
52
40
  require "retryable"
53
- users = Retryable.retryable(tries: 3, on: Twitter::Error, sleep: 0) do
41
+ users = Retryable.retryable(tries: 3, on: X::Error, sleep: 0) do
54
42
  yield users
55
43
  end
56
44
  [users, users.length]
57
45
  end
58
46
 
59
47
  def format_users!(users, options)
60
- require "t/core_ext/string"
61
- options["id"] ? users.collect!(&:to_i) : users.collect!(&:strip_ats)
48
+ options["id"] ? users.collect!(&:to_i) : users.collect! { |u| u.tr("@", "") }
62
49
  end
63
50
 
64
51
  def extract_owner(user_list, options)
@@ -67,8 +54,7 @@ module T
67
54
  list_name = owner
68
55
  owner = @rcfile.active_profile[0]
69
56
  else
70
- require "t/core_ext/string"
71
- owner = options["id"] ? owner.to_i : owner.strip_ats
57
+ owner = options["id"] ? owner.to_i : owner.tr("@", "")
72
58
  end
73
59
  [owner, list_name]
74
60
  end
@@ -78,32 +64,49 @@ module T
78
64
  end
79
65
 
80
66
  def number_with_delimiter(number, delimiter = ",")
81
- digits = number.to_s.chars
82
- groups = digits.reverse.each_slice(3).collect(&:join)
83
- groups.join(delimiter).reverse
67
+ number.to_s.chars.reverse.each_slice(3).collect(&:join).join(delimiter).reverse
84
68
  end
85
69
 
86
70
  def pluralize(count, singular, plural = nil)
87
- "#{count || 0} " + (count == 1 || count =~ /^1(\.0+)?$/ ? singular : (plural || "#{singular}s"))
71
+ "#{count || 0} " + (count == 1 || count.to_s =~ /^1(\.0+)?$/ ? singular : (plural || "#{singular}s"))
88
72
  end
89
73
 
90
- def decode_full_text(message, decode_full_uris = false)
74
+ def decode_full_text(message, decode_full_uris: false)
91
75
  require "htmlentities"
92
- text = HTMLEntities.new.decode(message.full_text)
93
- text = decode_uris(text, message.uris) if decode_full_uris
94
- text
76
+ text = HTMLEntities.new.decode(message["full_text"])
77
+ decode_full_uris ? decode_uris(text, message["uris"]) : text
95
78
  end
96
79
 
97
80
  def decode_uris(full_text, uri_entities)
98
81
  return full_text if uri_entities.nil?
99
82
 
100
83
  uri_entities.each do |uri_entity|
101
- full_text = full_text.gsub(uri_entity.uri.to_s, uri_entity.expanded_uri.to_s)
84
+ uri, expanded_uri = extract_uri_pair(uri_entity)
85
+ full_text = full_text.gsub(uri.to_s, expanded_uri.to_s)
102
86
  end
103
87
 
104
88
  full_text
105
89
  end
106
90
 
91
+ def extract_uri_pair(uri_entity)
92
+ uri = uri_entity["url"] || uri_entity[:url]
93
+ expanded = uri_entity["expanded_url"] || uri_entity[:expanded_url] || uri
94
+ [uri, expanded]
95
+ end
96
+
97
+ def build_timeline_opts
98
+ {include_entities: !!options["decode_uris"]}.tap do |opts|
99
+ opts[:exclude_replies] = true if options["exclude"] == "replies"
100
+ opts[:include_rts] = false if options["exclude"] == "retweets"
101
+ opts[:max_id] = options["max_id"] if options["max_id"]
102
+ opts[:since_id] = options["since_id"] if options["since_id"]
103
+ end
104
+ end
105
+
106
+ def resolve_user_input(user)
107
+ options["id"] ? user.to_i : user.tr("@", "")
108
+ end
109
+
107
110
  def open_or_print(uri, options)
108
111
  Launchy.open(uri, options) do
109
112
  say "Open: #{uri}"
data/lib/t/version.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module T
2
2
  class Version
3
- MAJOR = 4
4
- MINOR = 1
5
- PATCH = 1
3
+ MAJOR = 5
4
+ MINOR = 0
5
+ PATCH = 0
6
6
  PRE = nil
7
7
 
8
8
  class << self
data/t.gemspec CHANGED
@@ -5,24 +5,36 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require "t/version"
6
6
 
7
7
  Gem::Specification.new do |spec|
8
+ spec.add_dependency "cgi", ">= 0.2"
8
9
  spec.add_dependency "geokit", "~> 1.14"
9
10
  spec.add_dependency "htmlentities", "~> 4.3"
10
11
  spec.add_dependency "launchy", "~> 3.0"
11
12
  spec.add_dependency "oauth", "~> 1.1"
12
13
  spec.add_dependency "retryable", "~> 3.0"
13
14
  spec.add_dependency "thor", "~> 1.3"
14
- spec.add_dependency "twitter", "~> 8.1"
15
+ spec.add_dependency "x", "~> 0.19"
15
16
  spec.author = "Erik Berlin"
16
17
  spec.description = "A command-line power tool for Twitter."
17
18
  spec.email = "sferik@gmail.com"
18
19
  spec.executables = Dir["bin/*"].map { |f| File.basename(f) }
19
- spec.files = %w[CONTRIBUTING.md LICENSE.md README.md t.gemspec] + Dir["bin/*"] + Dir["lib/**/*.rb"]
20
+ spec.files = %w[CHANGELOG.md CONTRIBUTING.md LICENSE.md README.md t.gemspec] + Dir["bin/*"] + Dir["lib/**/*.rb"]
20
21
  spec.homepage = "http://sferik.github.com/t/"
21
22
  spec.licenses = %w[MIT]
22
- spec.metadata["rubygems_mfa_required"] = "true"
23
+
24
+ spec.metadata = {
25
+ "allowed_push_host" => "https://rubygems.org",
26
+ "bug_tracker_uri" => "https://github.com/sferik/t-ruby/issues",
27
+ "changelog_uri" => "https://github.com/sferik/t-ruby/blob/master/CHANGELOG.md",
28
+ "documentation_uri" => "https://rubydoc.info/gems/t/",
29
+ "funding_uri" => "https://github.com/sponsors/sferik/",
30
+ "homepage_uri" => spec.homepage,
31
+ "rubygems_mfa_required" => "true",
32
+ "source_code_uri" => "https://github.com/sferik/t-ruby",
33
+ }
34
+
23
35
  spec.name = "t"
24
36
  spec.require_paths = %w[lib]
25
- spec.required_ruby_version = ">= 3.1.4"
37
+ spec.required_ruby_version = ">= 3.2"
26
38
  spec.summary = "CLI for Twitter"
27
39
  spec.version = T::Version
28
40
  end
metadata CHANGED
@@ -1,15 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: t
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.1
4
+ version: 5.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erik Berlin
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-04-30 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: cgi
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0.2'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0.2'
13
26
  - !ruby/object:Gem::Dependency
14
27
  name: geokit
15
28
  requirement: !ruby/object:Gem::Requirement
@@ -95,19 +108,19 @@ dependencies:
95
108
  - !ruby/object:Gem::Version
96
109
  version: '1.3'
97
110
  - !ruby/object:Gem::Dependency
98
- name: twitter
111
+ name: x
99
112
  requirement: !ruby/object:Gem::Requirement
100
113
  requirements:
101
114
  - - "~>"
102
115
  - !ruby/object:Gem::Version
103
- version: '8.1'
116
+ version: '0.19'
104
117
  type: :runtime
105
118
  prerelease: false
106
119
  version_requirements: !ruby/object:Gem::Requirement
107
120
  requirements:
108
121
  - - "~>"
109
122
  - !ruby/object:Gem::Version
110
- version: '8.1'
123
+ version: '0.19'
111
124
  description: A command-line power tool for Twitter.
112
125
  email: sferik@gmail.com
113
126
  executables:
@@ -115,6 +128,7 @@ executables:
115
128
  extensions: []
116
129
  extra_rdoc_files: []
117
130
  files:
131
+ - CHANGELOG.md
118
132
  - CONTRIBUTING.md
119
133
  - LICENSE.md
120
134
  - README.md
@@ -122,15 +136,30 @@ files:
122
136
  - lib/t.rb
123
137
  - lib/t/cli.rb
124
138
  - lib/t/collectable.rb
125
- - lib/t/core_ext/kernel.rb
126
- - lib/t/core_ext/string.rb
127
139
  - lib/t/delete.rb
128
140
  - lib/t/editor.rb
129
141
  - lib/t/identicon.rb
130
142
  - lib/t/list.rb
131
143
  - lib/t/printable.rb
144
+ - lib/t/printable/messaging.rb
145
+ - lib/t/printable/rendering.rb
132
146
  - lib/t/rcfile.rb
133
147
  - lib/t/requestable.rb
148
+ - lib/t/requestable_api.rb
149
+ - lib/t/requestable_api/account_endpoints.rb
150
+ - lib/t/requestable_api/dm_endpoints.rb
151
+ - lib/t/requestable_api/dm_helpers.rb
152
+ - lib/t/requestable_api/dm_parsing.rb
153
+ - lib/t/requestable_api/helpers.rb
154
+ - lib/t/requestable_api/http.rb
155
+ - lib/t/requestable_api/list_endpoints.rb
156
+ - lib/t/requestable_api/list_normalization.rb
157
+ - lib/t/requestable_api/mutations.rb
158
+ - lib/t/requestable_api/resolution.rb
159
+ - lib/t/requestable_api/tweet_endpoints.rb
160
+ - lib/t/requestable_api/tweet_normalization.rb
161
+ - lib/t/requestable_api/user_endpoints.rb
162
+ - lib/t/requestable_api/user_normalization.rb
134
163
  - lib/t/search.rb
135
164
  - lib/t/set.rb
136
165
  - lib/t/stream.rb
@@ -141,8 +170,14 @@ homepage: http://sferik.github.com/t/
141
170
  licenses:
142
171
  - MIT
143
172
  metadata:
173
+ allowed_push_host: https://rubygems.org
174
+ bug_tracker_uri: https://github.com/sferik/t-ruby/issues
175
+ changelog_uri: https://github.com/sferik/t-ruby/blob/master/CHANGELOG.md
176
+ documentation_uri: https://rubydoc.info/gems/t/
177
+ funding_uri: https://github.com/sponsors/sferik/
178
+ homepage_uri: http://sferik.github.com/t/
144
179
  rubygems_mfa_required: 'true'
145
- post_install_message:
180
+ source_code_uri: https://github.com/sferik/t-ruby
146
181
  rdoc_options: []
147
182
  require_paths:
148
183
  - lib
@@ -150,15 +185,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
150
185
  requirements:
151
186
  - - ">="
152
187
  - !ruby/object:Gem::Version
153
- version: 3.1.4
188
+ version: '3.2'
154
189
  required_rubygems_version: !ruby/object:Gem::Requirement
155
190
  requirements:
156
191
  - - ">="
157
192
  - !ruby/object:Gem::Version
158
193
  version: '0'
159
194
  requirements: []
160
- rubygems_version: 3.5.9
161
- signing_key:
195
+ rubygems_version: 4.0.6
162
196
  specification_version: 4
163
197
  summary: CLI for Twitter
164
198
  test_files: []
@@ -1,13 +0,0 @@
1
- module Kernel
2
- def Bignum(arg, base = 0) # rubocop:disable Naming/MethodName
3
- Integer(arg, base)
4
- end
5
-
6
- def Fixnum(arg, base = 0) # rubocop:disable Naming/MethodName
7
- Integer(arg, base)
8
- end
9
-
10
- def NilClass(_) # rubocop:disable Naming/MethodName
11
- nil
12
- end
13
- end
@@ -1,15 +0,0 @@
1
- class String
2
- def prepend_at
3
- "@#{self}"
4
- end
5
-
6
- def strip_ats
7
- tr("@", "")
8
- end
9
-
10
- alias old_to_i to_i
11
-
12
- def to_i(base = 10)
13
- tr(",", "").old_to_i(base)
14
- end
15
- end