twitter 4.8.1 → 5.0.0.rc.1

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.
Files changed (197) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG.md +30 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +386 -266
  5. data/lib/twitter.rb +4 -39
  6. data/lib/twitter/arguments.rb +11 -0
  7. data/lib/twitter/base.rb +89 -68
  8. data/lib/twitter/client.rb +69 -110
  9. data/lib/twitter/configuration.rb +7 -3
  10. data/lib/twitter/creatable.rb +2 -4
  11. data/lib/twitter/cursor.rb +50 -42
  12. data/lib/twitter/direct_message.rb +2 -11
  13. data/lib/twitter/entity/uri.rb +13 -0
  14. data/lib/twitter/enumerable.rb +15 -0
  15. data/lib/twitter/error.rb +55 -7
  16. data/lib/twitter/error/already_favorited.rb +1 -1
  17. data/lib/twitter/error/already_posted.rb +10 -0
  18. data/lib/twitter/error/already_retweeted.rb +1 -1
  19. data/lib/twitter/error/bad_gateway.rb +2 -3
  20. data/lib/twitter/error/bad_request.rb +2 -2
  21. data/lib/twitter/error/forbidden.rb +2 -2
  22. data/lib/twitter/error/gateway_timeout.rb +2 -3
  23. data/lib/twitter/error/internal_server_error.rb +2 -3
  24. data/lib/twitter/error/not_acceptable.rb +2 -2
  25. data/lib/twitter/error/not_found.rb +2 -2
  26. data/lib/twitter/error/service_unavailable.rb +2 -3
  27. data/lib/twitter/error/too_many_requests.rb +2 -2
  28. data/lib/twitter/error/unauthorized.rb +2 -2
  29. data/lib/twitter/error/unprocessable_entity.rb +2 -2
  30. data/lib/twitter/factory.rb +2 -8
  31. data/lib/twitter/geo_factory.rb +2 -2
  32. data/lib/twitter/geo_results.rb +36 -0
  33. data/lib/twitter/identity.rb +0 -22
  34. data/lib/twitter/list.rb +18 -4
  35. data/lib/twitter/media/photo.rb +3 -3
  36. data/lib/twitter/media_factory.rb +2 -2
  37. data/lib/twitter/null_object.rb +24 -0
  38. data/lib/twitter/oembed.rb +3 -2
  39. data/lib/twitter/place.rb +15 -9
  40. data/lib/twitter/profile_banner.rb +5 -3
  41. data/lib/twitter/rate_limit.rb +1 -17
  42. data/lib/twitter/relationship.rb +2 -10
  43. data/lib/twitter/rest/api/direct_messages.rb +135 -0
  44. data/lib/twitter/rest/api/favorites.rb +120 -0
  45. data/lib/twitter/rest/api/friends_and_followers.rb +290 -0
  46. data/lib/twitter/rest/api/help.rb +58 -0
  47. data/lib/twitter/rest/api/lists.rb +491 -0
  48. data/lib/twitter/rest/api/oauth.rb +45 -0
  49. data/lib/twitter/rest/api/places_and_geo.rb +104 -0
  50. data/lib/twitter/rest/api/saved_searches.rb +91 -0
  51. data/lib/twitter/rest/api/search.rb +37 -0
  52. data/lib/twitter/rest/api/spam_reporting.rb +29 -0
  53. data/lib/twitter/rest/api/suggested_users.rb +51 -0
  54. data/lib/twitter/rest/api/timelines.rb +202 -0
  55. data/lib/twitter/rest/api/trends.rb +58 -0
  56. data/lib/twitter/rest/api/tweets.rb +293 -0
  57. data/lib/twitter/rest/api/undocumented.rb +52 -0
  58. data/lib/twitter/rest/api/users.rb +383 -0
  59. data/lib/twitter/rest/api/utils.rb +219 -0
  60. data/lib/twitter/rest/client.rb +193 -0
  61. data/lib/twitter/rest/request/multipart_with_file.rb +36 -0
  62. data/lib/twitter/rest/response/parse_json.rb +27 -0
  63. data/lib/twitter/{response → rest/response}/raise_error.rb +8 -11
  64. data/lib/twitter/search_results.rb +33 -21
  65. data/lib/twitter/settings.rb +1 -6
  66. data/lib/twitter/size.rb +1 -1
  67. data/lib/twitter/streaming/client.rb +77 -0
  68. data/lib/twitter/streaming/connection.rb +22 -0
  69. data/lib/twitter/streaming/response.rb +30 -0
  70. data/lib/twitter/suggestion.rb +4 -2
  71. data/lib/twitter/token.rb +8 -0
  72. data/lib/twitter/trend.rb +2 -1
  73. data/lib/twitter/trend_results.rb +59 -0
  74. data/lib/twitter/tweet.rb +41 -85
  75. data/lib/twitter/user.rb +51 -41
  76. data/lib/twitter/version.rb +4 -4
  77. data/spec/fixtures/already_posted.json +1 -0
  78. data/spec/fixtures/ids_list.json +1 -1
  79. data/spec/fixtures/ids_list2.json +1 -1
  80. data/spec/fixtures/search.json +1 -1
  81. data/spec/fixtures/search_malformed.json +1 -1
  82. data/spec/fixtures/track_streaming.json +3 -0
  83. data/spec/helper.rb +8 -13
  84. data/spec/twitter/base_spec.rb +25 -99
  85. data/spec/twitter/configuration_spec.rb +1 -1
  86. data/spec/twitter/cursor_spec.rb +13 -31
  87. data/spec/twitter/direct_message_spec.rb +41 -8
  88. data/spec/twitter/entity/uri_spec.rb +74 -0
  89. data/spec/twitter/error_spec.rb +59 -11
  90. data/spec/twitter/geo/point_spec.rb +1 -1
  91. data/spec/twitter/geo_factory_spec.rb +3 -3
  92. data/spec/twitter/geo_results_spec.rb +35 -0
  93. data/spec/twitter/identifiable_spec.rb +0 -21
  94. data/spec/twitter/list_spec.rb +51 -8
  95. data/spec/twitter/media/photo_spec.rb +118 -3
  96. data/spec/twitter/media_factory_spec.rb +2 -2
  97. data/spec/twitter/null_object_spec.rb +26 -0
  98. data/spec/twitter/oembed_spec.rb +69 -45
  99. data/spec/twitter/place_spec.rb +68 -12
  100. data/spec/twitter/profile_banner_spec.rb +1 -1
  101. data/spec/twitter/rate_limit_spec.rb +12 -12
  102. data/spec/twitter/relationship_spec.rb +31 -9
  103. data/spec/twitter/{api → rest/api}/direct_messages_spec.rb +22 -9
  104. data/spec/twitter/{api → rest/api}/favorites_spec.rb +80 -7
  105. data/spec/twitter/{api → rest/api}/friends_and_followers_spec.rb +104 -65
  106. data/spec/twitter/{api → rest/api}/geo_spec.rb +10 -10
  107. data/spec/twitter/{api → rest/api}/help_spec.rb +6 -6
  108. data/spec/twitter/{api → rest/api}/lists_spec.rb +77 -56
  109. data/spec/twitter/{api → rest/api}/oauth_spec.rb +6 -6
  110. data/spec/twitter/{api → rest/api}/saved_searches_spec.rb +7 -7
  111. data/spec/twitter/{api → rest/api}/search_spec.rb +8 -9
  112. data/spec/twitter/{api → rest/api}/spam_reporting_spec.rb +3 -3
  113. data/spec/twitter/{api → rest/api}/suggested_users_spec.rb +5 -5
  114. data/spec/twitter/{api → rest/api}/timelines_spec.rb +9 -9
  115. data/spec/twitter/{api → rest/api}/trends_spec.rb +6 -6
  116. data/spec/twitter/rest/api/tweets_spec.rb +503 -0
  117. data/spec/twitter/{api → rest/api}/undocumented_spec.rb +19 -45
  118. data/spec/twitter/{api → rest/api}/users_spec.rb +60 -35
  119. data/spec/twitter/rest/client_spec.rb +193 -0
  120. data/spec/twitter/saved_search_spec.rb +11 -0
  121. data/spec/twitter/search_results_spec.rb +29 -42
  122. data/spec/twitter/settings_spec.rb +17 -6
  123. data/spec/twitter/streaming/client_spec.rb +75 -0
  124. data/spec/twitter/token_spec.rb +16 -0
  125. data/spec/twitter/trend_results_spec.rb +89 -0
  126. data/spec/twitter/trend_spec.rb +23 -0
  127. data/spec/twitter/tweet_spec.rb +122 -115
  128. data/spec/twitter/user_spec.rb +136 -77
  129. data/spec/twitter_spec.rb +0 -119
  130. data/twitter.gemspec +8 -5
  131. metadata +148 -141
  132. metadata.gz.sig +0 -0
  133. data/lib/twitter/action/favorite.rb +0 -19
  134. data/lib/twitter/action/follow.rb +0 -30
  135. data/lib/twitter/action/list_member_added.rb +0 -39
  136. data/lib/twitter/action/mention.rb +0 -46
  137. data/lib/twitter/action/reply.rb +0 -27
  138. data/lib/twitter/action/retweet.rb +0 -27
  139. data/lib/twitter/action/tweet.rb +0 -20
  140. data/lib/twitter/action_factory.rb +0 -22
  141. data/lib/twitter/api/arguments.rb +0 -13
  142. data/lib/twitter/api/direct_messages.rb +0 -148
  143. data/lib/twitter/api/favorites.rb +0 -126
  144. data/lib/twitter/api/friends_and_followers.rb +0 -334
  145. data/lib/twitter/api/help.rb +0 -64
  146. data/lib/twitter/api/lists.rb +0 -618
  147. data/lib/twitter/api/oauth.rb +0 -44
  148. data/lib/twitter/api/places_and_geo.rb +0 -121
  149. data/lib/twitter/api/saved_searches.rb +0 -99
  150. data/lib/twitter/api/search.rb +0 -37
  151. data/lib/twitter/api/spam_reporting.rb +0 -30
  152. data/lib/twitter/api/suggested_users.rb +0 -55
  153. data/lib/twitter/api/timelines.rb +0 -214
  154. data/lib/twitter/api/trends.rb +0 -63
  155. data/lib/twitter/api/tweets.rb +0 -304
  156. data/lib/twitter/api/undocumented.rb +0 -97
  157. data/lib/twitter/api/users.rb +0 -439
  158. data/lib/twitter/api/utils.rb +0 -187
  159. data/lib/twitter/configurable.rb +0 -96
  160. data/lib/twitter/default.rb +0 -102
  161. data/lib/twitter/entity/url.rb +0 -9
  162. data/lib/twitter/error/client_error.rb +0 -35
  163. data/lib/twitter/error/decode_error.rb +0 -9
  164. data/lib/twitter/error/identity_map_key_error.rb +0 -9
  165. data/lib/twitter/error/server_error.rb +0 -28
  166. data/lib/twitter/exceptable.rb +0 -36
  167. data/lib/twitter/identity_map.rb +0 -22
  168. data/lib/twitter/request/multipart_with_file.rb +0 -34
  169. data/lib/twitter/response/parse_json.rb +0 -25
  170. data/spec/fixtures/about_me.json +0 -1
  171. data/spec/fixtures/activity_summary.json +0 -1
  172. data/spec/fixtures/bad_gateway.json +0 -1
  173. data/spec/fixtures/bad_request.json +0 -1
  174. data/spec/fixtures/by_friends.json +0 -1
  175. data/spec/fixtures/end_session.json +0 -1
  176. data/spec/fixtures/forbidden.json +0 -1
  177. data/spec/fixtures/internal_server_error.json +0 -1
  178. data/spec/fixtures/not_acceptable.json +0 -1
  179. data/spec/fixtures/phoenix_search.phoenix +0 -1
  180. data/spec/fixtures/resolve.json +0 -1
  181. data/spec/fixtures/service_unavailable.json +0 -1
  182. data/spec/fixtures/totals.json +0 -1
  183. data/spec/fixtures/trends.json +0 -1
  184. data/spec/fixtures/unauthorized.json +0 -1
  185. data/spec/fixtures/video_facets.json +0 -1
  186. data/spec/twitter/action/favorite_spec.rb +0 -29
  187. data/spec/twitter/action/follow_spec.rb +0 -29
  188. data/spec/twitter/action/list_member_added_spec.rb +0 -41
  189. data/spec/twitter/action/mention_spec.rb +0 -52
  190. data/spec/twitter/action/reply_spec.rb +0 -41
  191. data/spec/twitter/action/retweet_spec.rb +0 -41
  192. data/spec/twitter/action_factory_spec.rb +0 -35
  193. data/spec/twitter/action_spec.rb +0 -16
  194. data/spec/twitter/api/tweets_spec.rb +0 -285
  195. data/spec/twitter/client_spec.rb +0 -223
  196. data/spec/twitter/error/client_error_spec.rb +0 -23
  197. data/spec/twitter/error/server_error_spec.rb +0 -20
@@ -12,20 +12,17 @@ require 'twitter/error/unauthorized'
12
12
  require 'twitter/error/unprocessable_entity'
13
13
 
14
14
  module Twitter
15
- module Response
16
- class RaiseError < Faraday::Response::Middleware
15
+ module REST
16
+ module Response
17
+ class RaiseError < Faraday::Response::Middleware
17
18
 
18
- def on_complete(env)
19
- status_code = env[:status].to_i
20
- error_class = @klass.errors[status_code]
21
- raise error_class.from_response(env) if error_class
22
- end
19
+ def on_complete(env)
20
+ status_code = env[:status].to_i
21
+ error_class = Twitter::Error.errors[status_code]
22
+ raise error_class.from_response(env) if error_class
23
+ end
23
24
 
24
- def initialize(app, klass)
25
- @klass = klass
26
- super(app)
27
25
  end
28
-
29
26
  end
30
27
  end
31
28
  end
@@ -1,55 +1,67 @@
1
- require 'twitter/base'
1
+ require 'twitter/enumerable'
2
2
 
3
3
  module Twitter
4
- class SearchResults < Twitter::Base
4
+ class SearchResults
5
+ include Twitter::Enumerable
6
+ attr_reader :attrs
7
+ alias to_h attrs
8
+ alias to_hash attrs
9
+ alias to_hsh attrs
10
+
11
+ # Construct a new SearchResults object from a response hash
12
+ #
13
+ # @param response [Hash]
14
+ # @return [Twitter::Base]
15
+ def self.from_response(response={})
16
+ new(response[:body])
17
+ end
5
18
 
6
- # @return [Array<Twitter::Tweet>]
7
- def statuses
8
- @results ||= Array(@attrs[:statuses]).map do |tweet|
9
- Twitter::Tweet.fetch_or_new(tweet)
19
+ # Initializes a new SearchResults object
20
+ #
21
+ # @param attrs [Hash]
22
+ # @return [Twitter::SearchResults]
23
+ def initialize(attrs={})
24
+ @attrs = attrs
25
+ @collection = Array(@attrs[:statuses]).map do |tweet|
26
+ Twitter::Tweet.new(tweet)
10
27
  end
11
28
  end
12
- alias collection statuses
13
- alias results statuses
14
29
 
15
30
  # @return [Float]
16
31
  def completed_in
17
- @attrs[:search_metadata][:completed_in] if search_metadata?
32
+ @attrs[:search_metadata][:completed_in] if @attrs[:search_metadata]
18
33
  end
19
34
 
20
35
  # @return [Integer]
21
36
  def max_id
22
- @attrs[:search_metadata][:max_id] if search_metadata?
37
+ @attrs[:search_metadata][:max_id] if @attrs[:search_metadata]
23
38
  end
24
39
 
25
40
  # @return [Integer]
26
41
  def page
27
- @attrs[:search_metadata][:page] if search_metadata?
42
+ @attrs[:search_metadata][:page] if @attrs[:search_metadata]
28
43
  end
29
44
 
30
45
  # @return [String]
31
46
  def query
32
- @attrs[:search_metadata][:query] if search_metadata?
47
+ @attrs[:search_metadata][:query] if @attrs[:search_metadata]
33
48
  end
34
49
 
35
50
  # @return [Integer]
36
51
  def results_per_page
37
- @attrs[:search_metadata][:results_per_page] if search_metadata?
52
+ @attrs[:search_metadata][:count] if @attrs[:search_metadata]
38
53
  end
39
54
  alias rpp results_per_page
40
-
41
- def search_metadata?
42
- !@attrs[:search_metadata].nil?
43
- end
55
+ alias count results_per_page
44
56
 
45
57
  # @return [Integer]
46
58
  def since_id
47
- @attrs[:search_metadata][:since_id] if search_metadata?
59
+ @attrs[:search_metadata][:since_id] if @attrs[:search_metadata]
48
60
  end
49
61
 
50
62
  # @return [Boolean]
51
63
  def next_results?
52
- !@attrs[:search_metadata][:next_results].nil? if search_metadata?
64
+ !@attrs[:search_metadata][:next_results].nil? if @attrs[:search_metadata]
53
65
  end
54
66
  alias next_page? next_results?
55
67
 
@@ -69,11 +81,11 @@ module Twitter
69
81
  #
70
82
  # @note Returned Hash can be merged into the previous search options list to easily access the refresh page.
71
83
  # @return [Hash] The parameters needed to refresh the page.
72
- def refresh_url
84
+ def refresh_results
73
85
  query_string = strip_first_character(@attrs[:search_metadata][:refresh_url])
74
86
  query_string_to_hash(query_string)
75
87
  end
76
- alias refresh_page refresh_url
88
+ alias refresh_page refresh_results
77
89
 
78
90
  private
79
91
 
@@ -5,11 +5,6 @@ module Twitter
5
5
  attr_reader :always_use_https, :discoverable_by_email, :geo_enabled,
6
6
  :language, :protected, :screen_name, :show_all_inline_media, :sleep_time,
7
7
  :time_zone
8
-
9
- # @return [Twitter::Place]
10
- def trend_location
11
- @trend_location ||= Twitter::Place.fetch_or_new(Array(@attrs[:trend_location]).first)
12
- end
13
-
8
+ object_attr_reader :Place, :trend_location
14
9
  end
15
10
  end
@@ -12,7 +12,7 @@ module Twitter
12
12
  super || size_equal(other) || attrs_equal(other)
13
13
  end
14
14
 
15
- protected
15
+ private
16
16
 
17
17
  # @param other [Twitter::Size]
18
18
  # @return [Boolean]
@@ -0,0 +1,77 @@
1
+ require 'http/request'
2
+ require 'twitter/arguments'
3
+ require 'twitter/client'
4
+ require 'twitter/streaming/connection'
5
+ require 'twitter/streaming/response'
6
+
7
+ module Twitter
8
+ module Streaming
9
+ class Client < Twitter::Client
10
+ attr_writer :connection
11
+
12
+ def initialize(options={}, &block)
13
+ super
14
+ @connection = Twitter::Streaming::Connection.new
15
+ end
16
+
17
+ def filter(options={}, &block)
18
+ request(:get, 'https://stream.twitter.com:443/1.1/statuses/filter.json', options, &block)
19
+ end
20
+
21
+ def firehose(options={}, &block)
22
+ request(:get, 'https://stream.twitter.com:443/1.1/statuses/firehose.json', options, &block)
23
+ end
24
+
25
+ def sample(options={}, &block)
26
+ request(:get, 'https://stream.twitter.com:443/1.1/statuses/sample.json', options, &block)
27
+ end
28
+
29
+ def site(*args, &block)
30
+ arguments = Twitter::Arguments.new(args)
31
+ request(:get, 'https://sitestream.twitter.com:443/1.1/site.json', arguments.options.merge(:follow => arguments.join(',')), &block)
32
+ end
33
+
34
+ def user(options={}, &block)
35
+ request(:get, 'https://userstream.twitter.com:443/1.1/user.json', options, &block)
36
+ end
37
+
38
+ # Set a Proc to be run when connection established.
39
+ def on_request(&block)
40
+ if block_given?
41
+ @on_request = block
42
+ self
43
+ elsif instance_variable_defined?(:@on_request)
44
+ @on_request
45
+ else
46
+ Proc.new {}
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def request(method, uri, params, &block)
53
+ on_request.call
54
+ headers = default_headers.merge(:authorization => oauth_auth_header(method, uri, params).to_s)
55
+ request = HTTP::Request.new(method, uri + '?' + to_url_params(params), headers)
56
+ response = Twitter::Streaming::Response.new do |data|
57
+ yield(Tweet.new(data)) if data[:id]
58
+ end
59
+ @connection.stream(request, response)
60
+ end
61
+
62
+ def to_url_params(params)
63
+ params.map do |param, value|
64
+ [param, URI.encode(value)].join("=")
65
+ end.sort.join('&')
66
+ end
67
+
68
+ def default_headers
69
+ @default_headers ||= {
70
+ :accept => '*/*',
71
+ :user_agent => user_agent,
72
+ }
73
+ end
74
+
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,22 @@
1
+ require 'http/parser'
2
+ require 'openssl'
3
+ require 'resolv'
4
+
5
+ module Twitter
6
+ module Streaming
7
+ class Connection
8
+
9
+ def stream(request, response)
10
+ client_context = OpenSSL::SSL::SSLContext.new
11
+ client = TCPSocket.new(Resolv.getaddress(request.uri.host), request.uri.port)
12
+ ssl_client = OpenSSL::SSL::SSLSocket.new(client, client_context)
13
+ ssl_client.connect
14
+ request.stream(ssl_client)
15
+ while body = ssl_client.readpartial(1024)
16
+ response << body
17
+ end
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,30 @@
1
+ require 'buftok'
2
+
3
+ module Twitter
4
+ module Streaming
5
+ class Response
6
+ def initialize(&block)
7
+ @block = block
8
+ @parser = Http::Parser.new(self)
9
+ @tokenizer = BufferedTokenizer.new("\r\n")
10
+ end
11
+
12
+ def <<(data)
13
+ @parser << data
14
+ end
15
+
16
+ def on_headers_complete(headers)
17
+ # TODO: handle response codes
18
+ p(:status_code => @parser.status_code, :header => headers) unless @parser.status_code == 200
19
+ end
20
+
21
+ def on_body(data)
22
+ @tokenizer.extract(data).each do |line|
23
+ next if line.empty?
24
+ @block.call(JSON.parse(line, :symbolize_names => true))
25
+ end
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -12,8 +12,10 @@ module Twitter
12
12
 
13
13
  # @return [Array<Twitter::User>]
14
14
  def users
15
- @users ||= Array(@attrs[:users]).map do |user|
16
- Twitter::User.fetch_or_new(user)
15
+ memoize(:users) do
16
+ Array(@attrs[:users]).map do |user|
17
+ Twitter::User.new(user)
18
+ end
17
19
  end
18
20
  end
19
21
 
@@ -3,5 +3,13 @@ require 'twitter/base'
3
3
  module Twitter
4
4
  class Token < Twitter::Base
5
5
  attr_reader :token_type, :access_token
6
+
7
+ BEARER_TYPE = "bearer"
8
+
9
+ # @return [Boolean]
10
+ def bearer?
11
+ @attrs[:token_type] == BEARER_TYPE
12
+ end
13
+
6
14
  end
7
15
  end
@@ -2,7 +2,8 @@ require 'twitter/base'
2
2
 
3
3
  module Twitter
4
4
  class Trend < Twitter::Base
5
- attr_reader :events, :name, :promoted_content, :query, :url
5
+ attr_reader :events, :name, :promoted_content, :query
6
+ uri_attr_reader :uri
6
7
 
7
8
  # @param other [Twitter::Trend]
8
9
  # @return [Boolean]
@@ -0,0 +1,59 @@
1
+ require 'twitter/creatable'
2
+ require 'twitter/enumerable'
3
+ require 'twitter/null_object'
4
+
5
+ module Twitter
6
+ class TrendResults
7
+ include Twitter::Creatable
8
+ include Twitter::Enumerable
9
+ attr_reader :attrs
10
+ alias to_h attrs
11
+ alias to_hash attrs
12
+ alias to_hsh attrs
13
+
14
+ # Construct a new SearchResults object from a response hash
15
+ #
16
+ # @param response [Hash]
17
+ # @return [Twitter::Base]
18
+ def self.from_response(response={})
19
+ new(response[:body].first)
20
+ end
21
+
22
+ # Initializes a new SearchResults object
23
+ #
24
+ # @param attrs [Hash]
25
+ # @return [Twitter::TrendResults]
26
+ def initialize(attrs={})
27
+ @attrs = attrs
28
+ @collection = Array(@attrs[:trends]).map do |trend|
29
+ Twitter::Trend.new(trend)
30
+ end
31
+ end
32
+
33
+ # Time when the object was created on Twitter
34
+ #
35
+ # @return [Time]
36
+ def as_of
37
+ @as_of ||= Time.parse(@attrs[:as_of]) if @attrs[:as_of]
38
+ end
39
+
40
+ def as_of?
41
+ !!@attrs[:as_of]
42
+ end
43
+
44
+ # @return [Twitter::Place, NullObject]
45
+ def location
46
+ @location ||= if location?
47
+ Twitter::Place.new(@attrs[:locations].first)
48
+ else
49
+ Twitter::NullObject.instance
50
+ end
51
+ end
52
+
53
+ # @return [Boolean]
54
+ def location?
55
+ !@attrs[:locations].nil? && !@attrs[:locations].first.nil?
56
+ end
57
+
58
+ end
59
+ end
@@ -1,44 +1,35 @@
1
- require 'forwardable'
2
1
  require 'twitter/creatable'
3
- require 'twitter/exceptable'
4
- require 'twitter/identity'
5
2
 
6
3
  module Twitter
7
4
  class Tweet < Twitter::Identity
8
- extend Forwardable
9
5
  include Twitter::Creatable
10
- include Twitter::Exceptable
11
- attr_reader :favorite_count, :favorited, :favoriters, :from_user_id,
12
- :from_user_name, :in_reply_to_screen_name, :in_reply_to_attrs_id,
13
- :in_reply_to_status_id, :in_reply_to_user_id, :lang, :repliers,
14
- :retweeted, :retweeters, :source, :text, :to_user, :to_user_id,
15
- :to_user_name, :truncated
16
- alias in_reply_to_tweet_id in_reply_to_status_id
6
+ attr_reader :favorite_count, :favorited, :in_reply_to_screen_name,
7
+ :in_reply_to_attrs_id, :in_reply_to_status_id, :in_reply_to_user_id,
8
+ :lang, :retweet_count, :retweeted, :source, :text, :truncated
17
9
  alias favorites_count favorite_count
18
10
  alias favourite_count favorite_count
19
11
  alias favourites_count favorite_count
12
+ alias favoriters_count favorite_count
20
13
  alias favouriters_count favorite_count
21
14
  alias favourited favorited
22
15
  alias favourited? favorited?
23
- alias favouriters favoriters
24
- def_delegators :user, :profile_image_url, :profile_image_url_https
16
+ alias in_reply_to_tweet_id in_reply_to_status_id
17
+ alias retweeters_count retweet_count
18
+ object_attr_reader :GeoFactory, :geo
19
+ object_attr_reader :Metadata, :metadata
20
+ object_attr_reader :Place, :place
21
+ object_attr_reader :Tweet, :retweeted_status
22
+ alias retweet retweeted_status
23
+ alias retweeted_tweet retweeted_status
24
+ alias retweet? retweeted_status?
25
+ alias retweeted_tweet? retweeted_status?
26
+ object_attr_reader :User, :user, :status
25
27
 
26
28
  # @return [Boolean]
27
29
  def entities?
28
30
  !@attrs[:entities].nil?
29
31
  end
30
32
 
31
- # @return [Integer]
32
- def favoriters_count
33
- favoriters_count = @attrs[:favoriters_count]
34
- favoriters_count.to_i if favoriters_count
35
- end
36
-
37
- # @return [String]
38
- def from_user
39
- @attrs[:from_user] || user && user.screen_name
40
- end
41
-
42
33
  def filter_level
43
34
  @attrs[:filter_level] || "none"
44
35
  end
@@ -46,7 +37,7 @@ module Twitter
46
37
  # @return [String]
47
38
  # @note May be > 140 characters.
48
39
  def full_text
49
- if retweeted_status
40
+ if retweeted_status?
50
41
  prefix = text[/\A(RT @[a-z0-9_]{1,20}: )/i, 1]
51
42
  [prefix, retweeted_status.text].compact.join
52
43
  else
@@ -54,91 +45,56 @@ module Twitter
54
45
  end
55
46
  end
56
47
 
57
- # @return [Twitter::Geo]
58
- def geo
59
- @geo ||= Twitter::GeoFactory.fetch_or_new(@attrs[:geo])
60
- end
61
-
62
48
  # @note Must include entities in your request for this method to work
63
49
  # @return [Array<Twitter::Entity::Hashtag>]
64
50
  def hashtags
65
- @hashtags ||= entities(Twitter::Entity::Hashtag, :hashtags)
51
+ memoize(:hashtags) do
52
+ entities(Twitter::Entity::Hashtag, :hashtags)
53
+ end
66
54
  end
67
55
 
68
56
  # @note Must include entities in your request for this method to work
69
57
  # @return [Array<Twitter::Media>]
70
58
  def media
71
- @media ||= entities(Twitter::MediaFactory, :media)
72
- end
73
-
74
- # @return [Twitter::Metadata]
75
- def metadata
76
- @metadata ||= Twitter::Metadata.fetch_or_new(@attrs[:metadata])
77
- end
78
-
79
- # @return [Twitter::Place]
80
- def place
81
- @place ||= Twitter::Place.fetch_or_new(@attrs[:place])
82
- end
83
-
84
- # @return [Integer]
85
- def repliers_count
86
- repliers_count = @attrs[:repliers_count]
87
- repliers_count.to_i if repliers_count
59
+ memoize(:media) do
60
+ entities(Twitter::MediaFactory, :media)
61
+ end
88
62
  end
89
- alias reply_count repliers_count
90
63
 
91
64
  # @return [Boolean]
92
65
  def reply?
93
- !!in_reply_to_status_id
94
- end
95
-
96
- # @return [Boolean]
97
- def retweet?
98
- !!retweeted_status
99
- end
100
-
101
- # If this Tweet is a retweet, the original Tweet is available here.
102
- #
103
- # @return [Twitter::Tweet]
104
- def retweeted_status
105
- @retweeted_status ||= self.class.fetch_or_new(@attrs[:retweeted_status])
106
- end
107
- alias retweeted_tweet retweeted_status
108
- alias retweet retweeted_status
109
-
110
- # @return [String]
111
- def retweeters_count
112
- retweeters_count = (@attrs[:retweet_count] || @attrs[:retweeters_count])
113
- retweeters_count.to_i if retweeters_count
66
+ !!@attrs[:in_reply_to_status_id]
114
67
  end
115
- alias retweet_count retweeters_count
116
68
 
117
69
  # @note Must include entities in your request for this method to work
118
70
  # @return [Array<Twitter::Entity::Symbol>]
119
71
  def symbols
120
- @symbols ||= entities(Twitter::Entity::Symbol, :symbols)
72
+ memoize(:symbols) do
73
+ entities(Twitter::Entity::Symbol, :symbols)
74
+ end
121
75
  end
122
76
 
123
- # @note Must include entities in your request for this method to work
124
- # @return [Array<Twitter::Entity::Url>]
125
- def urls
126
- @urls ||= entities(Twitter::Entity::Url, :urls)
77
+ # @return [String] The URL to the tweet.
78
+ def uri
79
+ @uri ||= ::URI.parse("https://twitter.com/#{user.screen_name}/status/#{id}")
127
80
  end
81
+ alias url uri
128
82
 
129
- # @return [Twitter::User]
130
- def user
131
- @user ||= fetch_or_new_without_self(Twitter::User, @attrs, :user, :status)
83
+ # @note Must include entities in your request for this method to work
84
+ # @return [Array<Twitter::Entity::URI>]
85
+ def uris
86
+ memoize(:uris) do
87
+ entities(Twitter::Entity::URI, :urls)
88
+ end
132
89
  end
90
+ alias urls uris
133
91
 
134
92
  # @note Must include entities in your request for this method to work
135
93
  # @return [Array<Twitter::Entity::UserMention>]
136
94
  def user_mentions
137
- @user_mentions ||= entities(Twitter::Entity::UserMention, :user_mentions)
138
- end
139
-
140
- def user?
141
- !@attrs[:user].nil?
95
+ memoize(:user_mentions) do
96
+ entities(Twitter::Entity::UserMention, :user_mentions)
97
+ end
142
98
  end
143
99
 
144
100
  private
@@ -148,7 +104,7 @@ module Twitter
148
104
  def entities(klass, key)
149
105
  if entities?
150
106
  Array(@attrs[:entities][key.to_sym]).map do |entity|
151
- klass.fetch_or_new(entity)
107
+ klass.new(entity)
152
108
  end
153
109
  else
154
110
  warn "#{Kernel.caller.first}: To get #{key.to_s.tr('_', ' ')}, you must pass `:include_entities => true` when requesting the #{self.class.name}."