twitter 5.17.0 → 7.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +37 -10
  3. data/LICENSE.md +1 -1
  4. data/README.md +78 -407
  5. data/lib/twitter/base.rb +5 -19
  6. data/lib/twitter/basic_user.rb +0 -3
  7. data/lib/twitter/client.rb +9 -23
  8. data/lib/twitter/configuration.rb +4 -4
  9. data/lib/twitter/creatable.rb +5 -1
  10. data/lib/twitter/cursor.rb +13 -4
  11. data/lib/twitter/direct_message.rb +2 -0
  12. data/lib/twitter/direct_message_event.rb +44 -0
  13. data/lib/twitter/direct_messages/welcome_message.rb +17 -0
  14. data/lib/twitter/direct_messages/welcome_message_rule.rb +12 -0
  15. data/lib/twitter/direct_messages/welcome_message_rule_wrapper.rb +36 -0
  16. data/lib/twitter/direct_messages/welcome_message_wrapper.rb +42 -0
  17. data/lib/twitter/entity/uri.rb +0 -4
  18. data/lib/twitter/enumerable.rb +14 -3
  19. data/lib/twitter/error.rb +122 -95
  20. data/lib/twitter/geo_results.rb +0 -1
  21. data/lib/twitter/headers.rb +11 -15
  22. data/lib/twitter/media/photo.rb +5 -2
  23. data/lib/twitter/media/video.rb +5 -2
  24. data/lib/twitter/media/video_info.rb +1 -1
  25. data/lib/twitter/null_object.rb +20 -7
  26. data/lib/twitter/premium_search_results.rb +67 -0
  27. data/lib/twitter/profile.rb +5 -4
  28. data/lib/twitter/profile_banner.rb +1 -2
  29. data/lib/twitter/rate_limit.rb +3 -3
  30. data/lib/twitter/rest/account_activity.rb +99 -0
  31. data/lib/twitter/rest/api.rb +6 -2
  32. data/lib/twitter/rest/client.rb +0 -78
  33. data/lib/twitter/rest/direct_messages/welcome_messages.rb +90 -0
  34. data/lib/twitter/rest/direct_messages.rb +133 -44
  35. data/lib/twitter/rest/favorites.rb +29 -8
  36. data/lib/twitter/rest/friends_and_followers.rb +1 -3
  37. data/lib/twitter/rest/lists.rb +20 -30
  38. data/lib/twitter/rest/oauth.rb +15 -15
  39. data/lib/twitter/rest/premium_search.rb +34 -0
  40. data/lib/twitter/rest/request.rb +133 -18
  41. data/lib/twitter/rest/saved_searches.rb +1 -3
  42. data/lib/twitter/rest/search.rb +6 -3
  43. data/lib/twitter/rest/timelines.rb +1 -0
  44. data/lib/twitter/rest/trends.rb +1 -0
  45. data/lib/twitter/rest/tweets.rb +54 -18
  46. data/lib/twitter/rest/undocumented.rb +3 -4
  47. data/lib/twitter/rest/upload_utils.rb +68 -0
  48. data/lib/twitter/rest/users.rb +23 -37
  49. data/lib/twitter/rest/utils.rb +38 -28
  50. data/lib/twitter/search_results.rb +4 -4
  51. data/lib/twitter/streaming/client.rb +23 -25
  52. data/lib/twitter/streaming/connection.rb +37 -11
  53. data/lib/twitter/streaming/deleted_tweet.rb +0 -1
  54. data/lib/twitter/streaming/event.rb +6 -6
  55. data/lib/twitter/streaming/message_parser.rb +1 -1
  56. data/lib/twitter/streaming/response.rb +7 -3
  57. data/lib/twitter/trend_results.rb +1 -2
  58. data/lib/twitter/tweet.rb +11 -6
  59. data/lib/twitter/user.rb +2 -4
  60. data/lib/twitter/utils.rb +5 -18
  61. data/lib/twitter/version.rb +6 -6
  62. data/lib/twitter.rb +5 -0
  63. data/twitter.gemspec +10 -11
  64. metadata +31 -42
  65. data/lib/twitter/rest/media.rb +0 -30
  66. data/lib/twitter/rest/request/multipart_with_file.rb +0 -47
  67. data/lib/twitter/rest/response/parse_error_json.rb +0 -13
  68. data/lib/twitter/rest/response/parse_json.rb +0 -31
  69. data/lib/twitter/rest/response/raise_error.rb +0 -32
  70. data/lib/twitter/token.rb +0 -20
data/lib/twitter/base.rb CHANGED
@@ -13,7 +13,6 @@ module Twitter
13
13
  attr_reader :attrs
14
14
  alias to_h attrs
15
15
  alias to_hash to_h
16
- deprecate_alias :to_hsh, :to_hash
17
16
 
18
17
  class << self
19
18
  # Define methods that retrieve the value from attributes
@@ -29,7 +28,6 @@ module Twitter
29
28
  def predicate_attr_reader(*attrs)
30
29
  attrs.each do |attr|
31
30
  define_predicate_method(attr)
32
- deprecate_attribute_method(attr)
33
31
  end
34
32
  end
35
33
 
@@ -72,7 +70,7 @@ module Twitter
72
70
  # @param key1 [Symbol]
73
71
  # @param key2 [Symbol]
74
72
  def define_uri_method(key1, key2)
75
- define_method(key1) do ||
73
+ define_method(key1) do
76
74
  Addressable::URI.parse(@attrs[key2].chomp('#')) unless @attrs[key2].nil?
77
75
  end
78
76
  memoize(key1)
@@ -84,34 +82,22 @@ module Twitter
84
82
  # @param klass [Symbol]
85
83
  # @param key2 [Symbol]
86
84
  def define_attribute_method(key1, klass = nil, key2 = nil)
87
- define_method(key1) do ||
85
+ define_method(key1) do
88
86
  if attr_falsey_or_empty?(key1)
89
87
  NullObject.new
90
- elsif klass.nil?
91
- @attrs[key1]
92
88
  else
93
- attrs = attrs_for_object(key1, key2)
94
- Twitter.const_get(klass).new(attrs)
89
+ klass.nil? ? @attrs[key1] : Twitter.const_get(klass).new(attrs_for_object(key1, key2))
95
90
  end
96
91
  end
97
92
  memoize(key1)
98
93
  end
99
94
 
100
- # @param key [Symbol]
101
- def deprecate_attribute_method(key)
102
- define_method(key) do ||
103
- warn "#{Kernel.caller.first}: [DEPRECATION] ##{key} is deprecated. Use ##{key}? instead."
104
- @attrs[key]
105
- end
106
- memoize(key)
107
- end
108
-
109
95
  # Dynamically define a predicate method for an attribute
110
96
  #
111
97
  # @param key1 [Symbol]
112
98
  # @param key2 [Symbol]
113
99
  def define_predicate_method(key1, key2 = key1)
114
- define_method(:"#{key1}?") do ||
100
+ define_method(:"#{key1}?") do
115
101
  !attr_falsey_or_empty?(key2)
116
102
  end
117
103
  memoize(:"#{key1}?")
@@ -139,7 +125,7 @@ module Twitter
139
125
  private
140
126
 
141
127
  def attr_falsey_or_empty?(key)
142
- @attrs[key].nil? || @attrs[key] == false || @attrs[key].respond_to?(:empty?) && @attrs[key].empty?
128
+ !@attrs[key] || @attrs[key].respond_to?(:empty?) && @attrs[key].empty?
143
129
  end
144
130
 
145
131
  def attrs_for_object(key1, key2 = nil)
@@ -5,9 +5,6 @@ module Twitter
5
5
  class BasicUser < Twitter::Identity
6
6
  # @return [String]
7
7
  attr_reader :screen_name
8
- deprecate_alias :handle, :screen_name
9
- deprecate_alias :username, :screen_name
10
- deprecate_alias :user_name, :screen_name
11
8
  predicate_attr_reader :following
12
9
  end
13
10
  end
@@ -5,12 +5,8 @@ require 'twitter/version'
5
5
  module Twitter
6
6
  class Client
7
7
  include Twitter::Utils
8
- attr_accessor :access_token, :access_token_secret, :consumer_key, :consumer_secret, :proxy
8
+ attr_accessor :access_token, :access_token_secret, :consumer_key, :consumer_secret, :proxy, :timeouts, :dev_environment
9
9
  attr_writer :user_agent
10
- deprecate_alias :oauth_token, :access_token
11
- deprecate_alias :oauth_token=, :access_token=
12
- deprecate_alias :oauth_token_secret, :access_token_secret
13
- deprecate_alias :oauth_token_secret=, :access_token_secret=
14
10
 
15
11
  # Initializes a new Client object
16
12
  #
@@ -21,12 +17,11 @@ module Twitter
21
17
  instance_variable_set("@#{key}", value)
22
18
  end
23
19
  yield(self) if block_given?
24
- validate_credentials!
25
20
  end
26
21
 
27
22
  # @return [Boolean]
28
23
  def user_token?
29
- !!(access_token && access_token_secret)
24
+ !(blank_string?(access_token) || blank_string?(access_token_secret))
30
25
  end
31
26
 
32
27
  # @return [String]
@@ -37,31 +32,22 @@ module Twitter
37
32
  # @return [Hash]
38
33
  def credentials
39
34
  {
40
- :consumer_key => consumer_key,
41
- :consumer_secret => consumer_secret,
42
- :token => access_token,
43
- :token_secret => access_token_secret,
44
- :ignore_extra_keys => true,
35
+ consumer_key: consumer_key,
36
+ consumer_secret: consumer_secret,
37
+ token: access_token,
38
+ token_secret: access_token_secret,
45
39
  }
46
40
  end
47
41
 
48
42
  # @return [Boolean]
49
43
  def credentials?
50
- credentials.values.all?
44
+ credentials.values.none? { |v| blank_string?(v) }
51
45
  end
52
46
 
53
47
  private
54
48
 
55
- # Ensures that all credentials set during configuration are of a
56
- # valid type. Valid types are String and Boolean.
57
- #
58
- # @raise [Twitter::Error::ConfigurationError] Error is raised when
59
- # supplied twitter credentials are not a String or Boolean.
60
- def validate_credentials!
61
- credentials.each do |credential, value|
62
- next if value.nil? || value == true || value == false || value.is_a?(String)
63
- raise(Twitter::Error::ConfigurationError.new("Invalid #{credential} specified: #{value.inspect} must be a String."))
64
- end
49
+ def blank_string?(string)
50
+ string.respond_to?(:empty?) ? string.empty? : !string
65
51
  end
66
52
  end
67
53
  end
@@ -8,8 +8,9 @@ module Twitter
8
8
  # @return [Array<String>]
9
9
  attr_reader :non_username_paths
10
10
  # @return [Integer]
11
- attr_reader :characters_reserved_per_media, :max_media_per_upload,
12
- :photo_size_limit, :short_url_length, :short_url_length_https
11
+ attr_reader :characters_reserved_per_media, :dm_text_character_limit,
12
+ :max_media_per_upload, :photo_size_limit, :short_url_length,
13
+ :short_url_length_https
13
14
  alias short_uri_length short_url_length
14
15
  alias short_uri_length_https short_url_length_https
15
16
 
@@ -17,9 +18,8 @@ module Twitter
17
18
  #
18
19
  # @return [Array<Twitter::Size>]
19
20
  def photo_sizes
20
- @attrs.fetch(:photo_sizes, []).inject({}) do |object, (key, value)|
21
+ @attrs.fetch(:photo_sizes, []).each_with_object({}) do |(key, value), object|
21
22
  object[key] = Size.new(value)
22
- object
23
23
  end
24
24
  end
25
25
  memoize :photo_sizes
@@ -9,7 +9,11 @@ module Twitter
9
9
  #
10
10
  # @return [Time]
11
11
  def created_at
12
- Time.parse(@attrs[:created_at]) unless @attrs[:created_at].nil?
12
+ time = @attrs[:created_at]
13
+ return if time.nil?
14
+
15
+ time = Time.parse(time) unless time.is_a?(Time)
16
+ time.utc
13
17
  end
14
18
  memoize :created_at
15
19
 
@@ -10,15 +10,15 @@ module Twitter
10
10
  attr_reader :attrs
11
11
  alias to_h attrs
12
12
  alias to_hash to_h
13
- deprecate_alias :to_hsh, :to_hash
14
13
 
15
14
  # Initializes a new Cursor
16
15
  #
17
16
  # @param key [String, Symbol] The key to fetch the data from the response
18
17
  # @param klass [Class] The class to instantiate objects in the response
19
18
  # @param request [Twitter::REST::Request]
19
+ # @param limit [Integer] After reaching the limit, we stop fetching next page
20
20
  # @return [Twitter::Cursor]
21
- def initialize(key, klass, request)
21
+ def initialize(key, klass, request, limit = nil)
22
22
  @key = key.to_sym
23
23
  @klass = klass
24
24
  @client = request.client
@@ -26,6 +26,7 @@ module Twitter
26
26
  @path = request.path
27
27
  @options = request.options
28
28
  @collection = []
29
+ @limit = limit
29
30
  self.attrs = request.perform
30
31
  end
31
32
 
@@ -33,18 +34,26 @@ module Twitter
33
34
 
34
35
  # @return [Integer]
35
36
  def next_cursor
36
- @attrs[:next_cursor] || -1
37
+ @attrs[:next_cursor]
37
38
  end
38
39
  alias next next_cursor
39
40
 
40
41
  # @return [Boolean]
41
42
  def last?
43
+ return false if next_cursor.is_a?(String)
44
+ return true if next_cursor.nil?
45
+
42
46
  next_cursor.zero?
43
47
  end
44
48
 
49
+ # @return [Boolean]
50
+ def reached_limit?
51
+ @limit && @limit <= attrs[@key].count
52
+ end
53
+
45
54
  # @return [Hash]
46
55
  def fetch_next_page
47
- response = Twitter::REST::Request.new(@client, @request_method, @path, @options.merge(:cursor => next_cursor)).perform
56
+ response = Twitter::REST::Request.new(@client, @request_method, @path, @options.merge(cursor: next_cursor)).perform
48
57
  self.attrs = response
49
58
  end
50
59
 
@@ -8,6 +8,8 @@ module Twitter
8
8
  include Twitter::Entities
9
9
  # @return [String]
10
10
  attr_reader :text
11
+ attr_reader :sender_id
12
+ attr_reader :recipient_id
11
13
  alias full_text text
12
14
  object_attr_reader :User, :recipient
13
15
  object_attr_reader :User, :sender
@@ -0,0 +1,44 @@
1
+ require 'twitter/creatable'
2
+ require 'twitter/entities'
3
+ require 'twitter/identity'
4
+
5
+ module Twitter
6
+ class DirectMessageEvent < Twitter::Identity
7
+ include Twitter::Creatable
8
+ include Twitter::Entities
9
+
10
+ attr_reader :created_timestamp
11
+
12
+ object_attr_reader :DirectMessage, :direct_message
13
+
14
+ def initialize(attrs)
15
+ attrs = read_from_response(attrs)
16
+ text = attrs.dig(:message_create, :message_data, :text)
17
+ urls = attrs.dig(:message_create, :message_data, :entities, :urls)
18
+
19
+ text.gsub!(urls[0][:url], urls[0][:expanded_url]) if urls.any?
20
+
21
+ attrs[:direct_message] = build_direct_message(attrs, text)
22
+ super
23
+ end
24
+
25
+ private
26
+
27
+ # @return [Hash] Normalized hash of attrs
28
+ def read_from_response(attrs)
29
+ attrs[:event].nil? ? attrs : attrs[:event]
30
+ end
31
+
32
+ def build_direct_message(attrs, text)
33
+ recipient_id = attrs[:message_create][:target][:recipient_id].to_i
34
+ sender_id = attrs[:message_create][:sender_id].to_i
35
+ {id: attrs[:id].to_i,
36
+ created_at: Time.at(attrs[:created_timestamp].to_i / 1000.0),
37
+ sender: {id: sender_id},
38
+ sender_id: sender_id,
39
+ recipient: {id: recipient_id},
40
+ recipient_id: recipient_id,
41
+ text: text}
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,17 @@
1
+ require 'twitter/creatable'
2
+ require 'twitter/entities'
3
+ require 'twitter/identity'
4
+
5
+ module Twitter
6
+ module DirectMessages
7
+ class WelcomeMessage < Twitter::Identity
8
+ include Twitter::Creatable
9
+ include Twitter::Entities
10
+ # @return [String]
11
+ attr_reader :text
12
+ # @return [String]
13
+ attr_reader :name
14
+ alias full_text text
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,12 @@
1
+ require 'twitter/creatable'
2
+ require 'twitter/identity'
3
+
4
+ module Twitter
5
+ module DirectMessages
6
+ class WelcomeMessageRule < Twitter::Identity
7
+ include Twitter::Creatable
8
+ # @return [Integer]
9
+ attr_reader :welcome_message_id
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,36 @@
1
+ require 'twitter/creatable'
2
+ require 'twitter/identity'
3
+
4
+ module Twitter
5
+ module DirectMessages
6
+ class WelcomeMessageRuleWrapper < Twitter::Identity
7
+ attr_reader :created_timestamp
8
+
9
+ object_attr_reader 'DirectMessages::WelcomeMessageRule', :welcome_message_rule
10
+
11
+ def initialize(attrs)
12
+ attrs = read_from_response(attrs)
13
+
14
+ attrs[:welcome_message_rule] = build_welcome_message_rule(attrs)
15
+ super
16
+ end
17
+
18
+ private
19
+
20
+ # @return [Hash] Normalized hash of attrs
21
+ def read_from_response(attrs)
22
+ return attrs[:welcome_message_rule] unless attrs[:welcome_message_rule].nil?
23
+
24
+ attrs
25
+ end
26
+
27
+ def build_welcome_message_rule(attrs)
28
+ {
29
+ id: attrs[:id].to_i,
30
+ created_at: Time.at(attrs[:created_timestamp].to_i / 1000.0),
31
+ welcome_message_id: attrs[:welcome_message_id].to_i,
32
+ }
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,42 @@
1
+ require 'twitter/creatable'
2
+ require 'twitter/identity'
3
+
4
+ module Twitter
5
+ module DirectMessages
6
+ class WelcomeMessageWrapper < Twitter::Identity
7
+ attr_reader :created_timestamp
8
+
9
+ object_attr_reader 'DirectMessages::WelcomeMessage', :welcome_message
10
+
11
+ def initialize(attrs)
12
+ attrs = read_from_response(attrs)
13
+ text = attrs.dig(:message_data, :text)
14
+ urls = attrs.dig(:message_data, :entities, :urls)
15
+
16
+ text.gsub!(urls[0][:url], urls[0][:expanded_url]) if urls.any?
17
+
18
+ attrs[:welcome_message] = build_welcome_message(attrs, text)
19
+ super
20
+ end
21
+
22
+ private
23
+
24
+ # @return [Hash] Normalized hash of attrs
25
+ def read_from_response(attrs)
26
+ return attrs[:welcome_message] unless attrs[:welcome_message].nil?
27
+
28
+ attrs
29
+ end
30
+
31
+ def build_welcome_message(attrs, text)
32
+ {
33
+ id: attrs[:id].to_i,
34
+ created_at: Time.at(attrs[:created_timestamp].to_i / 1000.0),
35
+ text: text,
36
+ name: attrs[:name],
37
+ entities: attrs.dig(:message_data, :entities),
38
+ }
39
+ end
40
+ end
41
+ end
42
+ end
@@ -6,9 +6,5 @@ module Twitter
6
6
  display_uri_attr_reader
7
7
  uri_attr_reader :expanded_uri, :uri
8
8
  end
9
-
10
- URL = URI
11
- Uri = URI
12
- Url = URI
13
9
  end
14
10
  end
@@ -3,15 +3,16 @@ module Twitter
3
3
  include ::Enumerable
4
4
 
5
5
  # @return [Enumerator]
6
- def each(start = 0)
6
+ def each(start = 0, &block)
7
7
  return to_enum(:each, start) unless block_given?
8
+
8
9
  Array(@collection[start..-1]).each do |element|
9
10
  yield(element)
10
11
  end
11
- unless last?
12
+ unless finished?
12
13
  start = [@collection.size, start].max
13
14
  fetch_next_page
14
- each(start, &Proc.new)
15
+ each(start, &block)
15
16
  end
16
17
  self
17
18
  end
@@ -22,5 +23,15 @@ module Twitter
22
23
  def last?
23
24
  true
24
25
  end
26
+
27
+ # @return [Boolean]
28
+ def reached_limit?
29
+ false
30
+ end
31
+
32
+ # @return [Boolean]
33
+ def finished?
34
+ last? || reached_limit?
35
+ end
25
36
  end
26
37
  end