twitter 4.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.
Files changed (210) hide show
  1. data/CHANGELOG.md +673 -0
  2. data/LICENSE.md +20 -0
  3. data/README.md +415 -0
  4. data/Rakefile +11 -0
  5. data/lib/twitter.rb +29 -0
  6. data/lib/twitter/action/favorite.rb +19 -0
  7. data/lib/twitter/action/follow.rb +31 -0
  8. data/lib/twitter/action/list_member_added.rb +41 -0
  9. data/lib/twitter/action/mention.rb +48 -0
  10. data/lib/twitter/action/reply.rb +27 -0
  11. data/lib/twitter/action/retweet.rb +27 -0
  12. data/lib/twitter/action/tweet.rb +22 -0
  13. data/lib/twitter/action_factory.rb +22 -0
  14. data/lib/twitter/api.rb +2442 -0
  15. data/lib/twitter/base.rb +119 -0
  16. data/lib/twitter/basic_user.rb +8 -0
  17. data/lib/twitter/client.rb +96 -0
  18. data/lib/twitter/configurable.rb +67 -0
  19. data/lib/twitter/configuration.rb +20 -0
  20. data/lib/twitter/core_ext/array.rb +7 -0
  21. data/lib/twitter/core_ext/enumerable.rb +11 -0
  22. data/lib/twitter/core_ext/hash.rb +100 -0
  23. data/lib/twitter/core_ext/kernel.rb +15 -0
  24. data/lib/twitter/core_ext/string.rb +10 -0
  25. data/lib/twitter/creatable.rb +20 -0
  26. data/lib/twitter/cursor.rb +87 -0
  27. data/lib/twitter/default.rb +101 -0
  28. data/lib/twitter/direct_message.rb +21 -0
  29. data/lib/twitter/entity.rb +7 -0
  30. data/lib/twitter/entity/hashtag.rb +9 -0
  31. data/lib/twitter/entity/url.rb +9 -0
  32. data/lib/twitter/entity/user_mention.rb +9 -0
  33. data/lib/twitter/error.rb +34 -0
  34. data/lib/twitter/error/bad_gateway.rb +11 -0
  35. data/lib/twitter/error/bad_request.rb +10 -0
  36. data/lib/twitter/error/client_error.rb +35 -0
  37. data/lib/twitter/error/decode_error.rb +9 -0
  38. data/lib/twitter/error/forbidden.rb +10 -0
  39. data/lib/twitter/error/gateway_timeout.rb +11 -0
  40. data/lib/twitter/error/identity_map_key_error.rb +9 -0
  41. data/lib/twitter/error/internal_server_error.rb +11 -0
  42. data/lib/twitter/error/not_acceptable.rb +10 -0
  43. data/lib/twitter/error/not_found.rb +10 -0
  44. data/lib/twitter/error/rate_limited.rb +11 -0
  45. data/lib/twitter/error/server_error.rb +28 -0
  46. data/lib/twitter/error/service_unavailable.rb +11 -0
  47. data/lib/twitter/error/unauthorized.rb +10 -0
  48. data/lib/twitter/factory.rb +21 -0
  49. data/lib/twitter/geo.rb +15 -0
  50. data/lib/twitter/geo/point.rb +22 -0
  51. data/lib/twitter/geo/polygon.rb +8 -0
  52. data/lib/twitter/geo_factory.rb +18 -0
  53. data/lib/twitter/identity.rb +50 -0
  54. data/lib/twitter/identity_map.rb +22 -0
  55. data/lib/twitter/language.rb +7 -0
  56. data/lib/twitter/list.rb +18 -0
  57. data/lib/twitter/media/photo.rb +22 -0
  58. data/lib/twitter/media_factory.rb +17 -0
  59. data/lib/twitter/metadata.rb +7 -0
  60. data/lib/twitter/oembed.rb +8 -0
  61. data/lib/twitter/place.rb +34 -0
  62. data/lib/twitter/rate_limit.rb +45 -0
  63. data/lib/twitter/relationship.rb +36 -0
  64. data/lib/twitter/request/multipart_with_file.rb +41 -0
  65. data/lib/twitter/response/parse_json.rb +25 -0
  66. data/lib/twitter/response/raise_error.rb +30 -0
  67. data/lib/twitter/saved_search.rb +9 -0
  68. data/lib/twitter/search_results.rb +48 -0
  69. data/lib/twitter/settings.rb +17 -0
  70. data/lib/twitter/size.rb +24 -0
  71. data/lib/twitter/source_user.rb +15 -0
  72. data/lib/twitter/suggestion.rb +22 -0
  73. data/lib/twitter/target_user.rb +8 -0
  74. data/lib/twitter/trend.rb +14 -0
  75. data/lib/twitter/tweet.rb +145 -0
  76. data/lib/twitter/user.rb +97 -0
  77. data/lib/twitter/version.rb +18 -0
  78. data/spec/fixtures/about_me.json +1 -0
  79. data/spec/fixtures/activity_summary.json +1 -0
  80. data/spec/fixtures/all.json +1 -0
  81. data/spec/fixtures/bad_gateway.json +1 -0
  82. data/spec/fixtures/bad_request.json +1 -0
  83. data/spec/fixtures/by_friends.json +1 -0
  84. data/spec/fixtures/category.json +1 -0
  85. data/spec/fixtures/configuration.json +1 -0
  86. data/spec/fixtures/contributees.json +1 -0
  87. data/spec/fixtures/contributors.json +1 -0
  88. data/spec/fixtures/direct_message.json +1 -0
  89. data/spec/fixtures/direct_messages.json +1 -0
  90. data/spec/fixtures/end_session.json +1 -0
  91. data/spec/fixtures/enhance_your_calm.text +11 -0
  92. data/spec/fixtures/favorites.json +1 -0
  93. data/spec/fixtures/following.json +1 -0
  94. data/spec/fixtures/forbidden.json +1 -0
  95. data/spec/fixtures/friendships.json +1 -0
  96. data/spec/fixtures/ids.json +1 -0
  97. data/spec/fixtures/ids_list.json +1 -0
  98. data/spec/fixtures/ids_list2.json +1 -0
  99. data/spec/fixtures/image_facets.json +1 -0
  100. data/spec/fixtures/internal_server_error.json +1 -0
  101. data/spec/fixtures/languages.json +1 -0
  102. data/spec/fixtures/list.json +1 -0
  103. data/spec/fixtures/lists.json +1 -0
  104. data/spec/fixtures/locations.json +1 -0
  105. data/spec/fixtures/matching_trends.json +1 -0
  106. data/spec/fixtures/me.jpeg +0 -0
  107. data/spec/fixtures/media_timeline.json +1 -0
  108. data/spec/fixtures/members.json +1 -0
  109. data/spec/fixtures/no_user_matches.json +1 -0
  110. data/spec/fixtures/not_acceptable.json +1 -0
  111. data/spec/fixtures/not_following.json +1 -0
  112. data/spec/fixtures/not_found.json +1 -0
  113. data/spec/fixtures/oembed.json +1 -0
  114. data/spec/fixtures/pbjt.gif +0 -0
  115. data/spec/fixtures/pengwynn.json +1 -0
  116. data/spec/fixtures/phoenix_search.phoenix +1 -0
  117. data/spec/fixtures/place.json +1 -0
  118. data/spec/fixtures/places.json +1 -0
  119. data/spec/fixtures/privacy.json +1 -0
  120. data/spec/fixtures/profile_image.text +24 -0
  121. data/spec/fixtures/rate_limit_status.json +1 -0
  122. data/spec/fixtures/recommendations.json +1 -0
  123. data/spec/fixtures/related_results.json +1 -0
  124. data/spec/fixtures/resolve.json +1 -0
  125. data/spec/fixtures/retweet.json +1 -0
  126. data/spec/fixtures/retweeted_status.json +1 -0
  127. data/spec/fixtures/retweeters_of.json +1 -0
  128. data/spec/fixtures/retweets.json +1 -0
  129. data/spec/fixtures/saved_search.json +1 -0
  130. data/spec/fixtures/saved_searches.json +1 -0
  131. data/spec/fixtures/search.json +1 -0
  132. data/spec/fixtures/search_malformed.json +1 -0
  133. data/spec/fixtures/service_unavailable.json +1 -0
  134. data/spec/fixtures/settings.json +1 -0
  135. data/spec/fixtures/sferik.json +1 -0
  136. data/spec/fixtures/status.json +1 -0
  137. data/spec/fixtures/status_with_media.json +104 -0
  138. data/spec/fixtures/statuses.json +1 -0
  139. data/spec/fixtures/suggestions.json +1 -0
  140. data/spec/fixtures/tos.json +1 -0
  141. data/spec/fixtures/totals.json +1 -0
  142. data/spec/fixtures/trends.json +1 -0
  143. data/spec/fixtures/trends_current.json +1 -0
  144. data/spec/fixtures/trends_daily.json +1 -0
  145. data/spec/fixtures/trends_weekly.json +1 -0
  146. data/spec/fixtures/unauthorized.json +1 -0
  147. data/spec/fixtures/user_search.json +1 -0
  148. data/spec/fixtures/user_timeline.json +1 -0
  149. data/spec/fixtures/users.json +1 -0
  150. data/spec/fixtures/users_list.json +1 -0
  151. data/spec/fixtures/video_facets.json +1 -0
  152. data/spec/fixtures/we_concept_bg2.png +0 -0
  153. data/spec/fixtures/wildcomet2.jpe +0 -0
  154. data/spec/helper.rb +53 -0
  155. data/spec/twitter/action/favorite_spec.rb +29 -0
  156. data/spec/twitter/action/follow_spec.rb +29 -0
  157. data/spec/twitter/action/list_member_added_spec.rb +41 -0
  158. data/spec/twitter/action/mention_spec.rb +52 -0
  159. data/spec/twitter/action/reply_spec.rb +41 -0
  160. data/spec/twitter/action/retweet_spec.rb +41 -0
  161. data/spec/twitter/action_factory_spec.rb +37 -0
  162. data/spec/twitter/action_spec.rb +16 -0
  163. data/spec/twitter/api/account_spec.rb +148 -0
  164. data/spec/twitter/api/activity_spec.rb +41 -0
  165. data/spec/twitter/api/blocks_spec.rb +167 -0
  166. data/spec/twitter/api/direct_messages_spec.rb +142 -0
  167. data/spec/twitter/api/friendships_spec.rb +567 -0
  168. data/spec/twitter/api/geo_spec.rb +100 -0
  169. data/spec/twitter/api/help_spec.rb +76 -0
  170. data/spec/twitter/api/lists_spec.rb +900 -0
  171. data/spec/twitter/api/report_spam_spec.rb +29 -0
  172. data/spec/twitter/api/saved_searches_spec.rb +100 -0
  173. data/spec/twitter/api/search_spec.rb +68 -0
  174. data/spec/twitter/api/statuses_spec.rb +559 -0
  175. data/spec/twitter/api/trends_spec.rb +80 -0
  176. data/spec/twitter/api/users_spec.rb +419 -0
  177. data/spec/twitter/base_spec.rb +113 -0
  178. data/spec/twitter/basic_user_spec.rb +23 -0
  179. data/spec/twitter/client_spec.rb +175 -0
  180. data/spec/twitter/configuration_spec.rb +17 -0
  181. data/spec/twitter/cursor_spec.rb +102 -0
  182. data/spec/twitter/direct_message_spec.rb +56 -0
  183. data/spec/twitter/error/client_error_spec.rb +40 -0
  184. data/spec/twitter/error/server_error_spec.rb +24 -0
  185. data/spec/twitter/error_spec.rb +20 -0
  186. data/spec/twitter/geo/point_spec.rb +41 -0
  187. data/spec/twitter/geo/polygon_spec.rb +29 -0
  188. data/spec/twitter/geo_factory_spec.rb +21 -0
  189. data/spec/twitter/geo_spec.rb +29 -0
  190. data/spec/twitter/identifiable_spec.rb +54 -0
  191. data/spec/twitter/list_spec.rb +45 -0
  192. data/spec/twitter/media/photo_spec.rb +35 -0
  193. data/spec/twitter/media_factory_spec.rb +17 -0
  194. data/spec/twitter/oembed_spec.rb +146 -0
  195. data/spec/twitter/place_spec.rb +75 -0
  196. data/spec/twitter/rate_limit_spec.rb +76 -0
  197. data/spec/twitter/relationship_spec.rb +35 -0
  198. data/spec/twitter/saved_search_spec.rb +34 -0
  199. data/spec/twitter/search_results_spec.rb +89 -0
  200. data/spec/twitter/settings_spec.rb +16 -0
  201. data/spec/twitter/size_spec.rb +38 -0
  202. data/spec/twitter/source_user_spec.rb +23 -0
  203. data/spec/twitter/suggestion_spec.rb +50 -0
  204. data/spec/twitter/target_user_spec.rb +23 -0
  205. data/spec/twitter/trend_spec.rb +38 -0
  206. data/spec/twitter/tweet_spec.rb +307 -0
  207. data/spec/twitter/user_spec.rb +127 -0
  208. data/spec/twitter_spec.rb +93 -0
  209. data/twitter.gemspec +30 -0
  210. metadata +584 -0
@@ -0,0 +1,41 @@
1
+ require 'faraday'
2
+
3
+ module Twitter
4
+ module Request
5
+ class MultipartWithFile < Faraday::Middleware
6
+ CONTENT_TYPE = 'Content-Type'.freeze
7
+ class << self
8
+ attr_accessor :mime_type
9
+ end
10
+ self.mime_type = 'multipart/form-data'.freeze
11
+
12
+ def call(env)
13
+ if env[:body].is_a?(Hash)
14
+ env[:body].each do |key, value|
15
+ if value.respond_to?(:to_io)
16
+ env[:body][key] = Faraday::UploadIO.new(value, mime_type(value.path), value.path)
17
+ env[:request_headers][CONTENT_TYPE] = self.class.mime_type
18
+ end
19
+ end
20
+ end
21
+ @app.call(env)
22
+ end
23
+
24
+ private
25
+
26
+ def mime_type(path)
27
+ case path
28
+ when /\.jpe?g/i
29
+ 'image/jpeg'
30
+ when /\.gif$/i
31
+ 'image/gif'
32
+ when /\.png$/i
33
+ 'image/png'
34
+ else
35
+ 'application/octet-stream'
36
+ end
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,25 @@
1
+ require 'faraday'
2
+ require 'multi_json'
3
+
4
+ module Twitter
5
+ module Response
6
+ class ParseJson < Faraday::Response::Middleware
7
+
8
+ def parse(body)
9
+ case body
10
+ when /\A^\s*$\z/, nil
11
+ nil
12
+ else
13
+ MultiJson.load(body, :symbolize_keys => true)
14
+ end
15
+ end
16
+
17
+ def on_complete(env)
18
+ if respond_to?(:parse)
19
+ env[:body] = parse(env[:body]) unless [204, 301, 302, 304].include?(env[:status])
20
+ end
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,30 @@
1
+ require 'faraday'
2
+ require 'twitter/error/bad_gateway'
3
+ require 'twitter/error/bad_request'
4
+ require 'twitter/error/forbidden'
5
+ require 'twitter/error/gateway_timeout'
6
+ require 'twitter/error/internal_server_error'
7
+ require 'twitter/error/not_acceptable'
8
+ require 'twitter/error/not_found'
9
+ require 'twitter/error/rate_limited'
10
+ require 'twitter/error/service_unavailable'
11
+ require 'twitter/error/unauthorized'
12
+
13
+ module Twitter
14
+ module Response
15
+ class RaiseError < Faraday::Response::Middleware
16
+
17
+ def on_complete(env)
18
+ status_code = env[:status].to_i
19
+ error_class = @klass.errors[status_code]
20
+ raise error_class.from_response(env) if error_class
21
+ end
22
+
23
+ def initialize(app, klass)
24
+ @klass = klass
25
+ super(app)
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,9 @@
1
+ require 'twitter/creatable'
2
+ require 'twitter/identity'
3
+
4
+ module Twitter
5
+ class SavedSearch < Twitter::Identity
6
+ include Twitter::Creatable
7
+ attr_reader :name, :position, :query
8
+ end
9
+ end
@@ -0,0 +1,48 @@
1
+ require 'twitter/base'
2
+ require 'twitter/tweet'
3
+
4
+ module Twitter
5
+ class SearchResults < Twitter::Base
6
+
7
+ # @return [Array<Twitter::Tweet>]
8
+ def statuses
9
+ @results ||= Array(@attrs[:statuses]).map do |tweet|
10
+ Twitter::Tweet.fetch_or_new(tweet)
11
+ end
12
+ end
13
+ alias collection statuses
14
+ alias results statuses
15
+
16
+ # @return [Float]
17
+ def completed_in
18
+ @attrs[:search_metadata][:completed_in] unless @attrs[:search_metadata].nil?
19
+ end
20
+
21
+ # @return [Integer]
22
+ def max_id
23
+ @attrs[:search_metadata][:max_id] unless @attrs[:search_metadata].nil?
24
+ end
25
+
26
+ # @return [Integer]
27
+ def page
28
+ @attrs[:search_metadata][:page] unless @attrs[:search_metadata].nil?
29
+ end
30
+
31
+ # @return [String]
32
+ def query
33
+ @attrs[:search_metadata][:query] unless @attrs[:search_metadata].nil?
34
+ end
35
+
36
+ # @return [Integer]
37
+ def results_per_page
38
+ @attrs[:search_metadata][:results_per_page] unless @attrs[:search_metadata].nil?
39
+ end
40
+ alias rpp results_per_page
41
+
42
+ # @return [Integer]
43
+ def since_id
44
+ @attrs[:search_metadata][:since_id] unless @attrs[:search_metadata].nil?
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,17 @@
1
+ require 'twitter/base'
2
+ require 'twitter/place'
3
+
4
+ module Twitter
5
+ class Settings < Twitter::Base
6
+ attr_reader :always_use_https, :discoverable_by_email, :geo_enabled,
7
+ :language, :protected, :screen_name, :show_all_inline_media, :sleep_time,
8
+ :time_zone
9
+ alias protected? protected
10
+
11
+ # @return [Twitter::Place]
12
+ def trend_location
13
+ @trend_location ||= Twitter::Place.fetch_or_new(Array(@attrs[:trend_location]).first)
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,24 @@
1
+ require 'twitter/base'
2
+
3
+ module Twitter
4
+ class Size < Twitter::Base
5
+ attr_reader :h, :resize, :w
6
+ alias height h
7
+ alias width w
8
+
9
+ # @param other [Twitter::Size]
10
+ # @return [Boolean]
11
+ def ==(other)
12
+ super || size_equal(other) || attrs_equal(other)
13
+ end
14
+
15
+ protected
16
+
17
+ # @param other [Twitter::Size]
18
+ # @return [Boolean]
19
+ def size_equal(other)
20
+ self.class == other.class && !other.h.nil? && h == other.h && !other.w.nil? && w == other.w
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,15 @@
1
+ require 'twitter/basic_user'
2
+
3
+ module Twitter
4
+ class SourceUser < Twitter::BasicUser
5
+ attr_reader :all_replies, :blocking, :can_dm, :followed_by, :marked_spam,
6
+ :notifications_enabled, :want_retweets
7
+ alias all_replies? all_replies
8
+ alias blocking? blocking
9
+ alias can_dm? can_dm
10
+ alias followed_by? followed_by
11
+ alias marked_spam? marked_spam
12
+ alias notifications_enabled? notifications_enabled
13
+ alias want_retweets? want_retweets
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ require 'twitter/base'
2
+ require 'twitter/user'
3
+
4
+ module Twitter
5
+ class Suggestion < Twitter::Base
6
+ attr_reader :name, :size, :slug
7
+
8
+ # @param other [Twitter::Suggestion]
9
+ # @return [Boolean]
10
+ def ==(other)
11
+ super || attr_equal(:slug, other) || attrs_equal(other)
12
+ end
13
+
14
+ # @return [Array<Twitter::User>]
15
+ def users
16
+ @users ||= Array(@attrs[:users]).map do |user|
17
+ Twitter::User.fetch_or_new(user)
18
+ end
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,8 @@
1
+ require 'twitter/basic_user'
2
+
3
+ module Twitter
4
+ class TargetUser < Twitter::BasicUser
5
+ attr_reader :followed_by
6
+ alias followed_by? followed_by
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+ require 'twitter/base'
2
+
3
+ module Twitter
4
+ class Trend < Twitter::Base
5
+ attr_reader :events, :name, :promoted_content, :query, :url
6
+
7
+ # @param other [Twitter::Trend]
8
+ # @return [Boolean]
9
+ def ==(other)
10
+ super || attr_equal(:name, other) || attrs_equal(other)
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,145 @@
1
+ require 'twitter/core_ext/hash'
2
+ require 'twitter/creatable'
3
+ require 'twitter/entity/hashtag'
4
+ require 'twitter/entity/url'
5
+ require 'twitter/entity/user_mention'
6
+ require 'twitter/geo_factory'
7
+ require 'twitter/identity'
8
+ require 'twitter/media_factory'
9
+ require 'twitter/metadata'
10
+ require 'twitter/place'
11
+ require 'twitter/user'
12
+
13
+ module Twitter
14
+ class Tweet < Twitter::Identity
15
+ include Twitter::Creatable
16
+ attr_reader :favorited, :favoriters, :from_user_id, :from_user_name,
17
+ :in_reply_to_screen_name, :in_reply_to_attrs_id, :in_reply_to_status_id,
18
+ :in_reply_to_user_id, :iso_language_code, :profile_image_url,
19
+ :profile_image_url_https, :repliers, :retweeted, :retweeters, :source,
20
+ :text, :to_user, :to_user_id, :to_user_name, :truncated
21
+ alias in_reply_to_tweet_id in_reply_to_status_id
22
+ alias favorited? favorited
23
+ alias favourited favorited
24
+ alias favourited? favorited
25
+ alias retweeted? retweeted
26
+ alias truncated? truncated
27
+
28
+ # @return [Integer]
29
+ def favoriters_count
30
+ favoriters_count = @attrs[:favoriters_count]
31
+ favoriters_count.to_i if favoriters_count
32
+ end
33
+ alias favorite_count favoriters_count
34
+ alias favourite_count favoriters_count
35
+ alias favouriters_count favoriters_count
36
+
37
+ # @return [String]
38
+ def from_user
39
+ @attrs[:from_user] || user && user.screen_name
40
+ end
41
+
42
+ # @return [String]
43
+ # @note May be > 140 characters.
44
+ def full_text
45
+ retweeted_status && retweeted_status.user ? "RT @#{retweeted_status.user.screen_name}: #{retweeted_status.text}" : text
46
+ end
47
+
48
+ # @return [Twitter::Geo]
49
+ def geo
50
+ @geo ||= Twitter::GeoFactory.fetch_or_new(@attrs[:geo])
51
+ end
52
+
53
+ # @note Must include entities in your request for this method to work
54
+ # @return [Array<Twitter::Entity::Hashtag>]
55
+ def hashtags
56
+ @hashtags ||= entities(Twitter::Entity::Hashtag, :hashtags)
57
+ end
58
+
59
+ # @note Must include entities in your request for this method to work
60
+ # @return [Array<Twitter::Media>]
61
+ def media
62
+ @media ||= entities(Twitter::MediaFactory, :media)
63
+ end
64
+
65
+ # @return [Twitter::Metadata]
66
+ def metadata
67
+ @metadata ||= Twitter::Metadata.fetch_or_new(@attrs[:metadata])
68
+ end
69
+
70
+ # @return [Twitter::Place]
71
+ def place
72
+ @place ||= Twitter::Place.fetch_or_new(@attrs[:place])
73
+ end
74
+
75
+ # @return [Integer]
76
+ def repliers_count
77
+ repliers_count = @attrs[:repliers_count]
78
+ repliers_count.to_i if repliers_count
79
+ end
80
+ alias reply_count repliers_count
81
+
82
+ def retweet?
83
+ !!retweeted_status
84
+ end
85
+
86
+ # If this Tweet is a retweet, the original Tweet is available here.
87
+ #
88
+ # @return [Twitter::Tweet]
89
+ def retweeted_status
90
+ @retweeted_status ||= self.class.fetch_or_new(@attrs[:retweeted_status])
91
+ end
92
+ alias retweeted_tweet retweeted_status
93
+ alias retweet retweeted_status
94
+
95
+ # @return [String]
96
+ def retweeters_count
97
+ retweeters_count = (@attrs[:retweet_count] || @attrs[:retweeters_count])
98
+ retweeters_count.to_i if retweeters_count
99
+ end
100
+ alias retweet_count retweeters_count
101
+
102
+ # @note Must include entities in your request for this method to work
103
+ # @return [Array<Twitter::Entity::Url>]
104
+ def urls
105
+ @urls ||= entities(Twitter::Entity::Url, :urls)
106
+ end
107
+
108
+ # @return [Twitter::User]
109
+ def user
110
+ @user ||= Twitter::User.fetch_or_new(@attrs.dup[:user].merge(:status => @attrs.except(:user))) if user?
111
+ end
112
+
113
+ # @note Must include entities in your request for this method to work
114
+ # @return [Array<Twitter::Entity::UserMention>]
115
+ def user_mentions
116
+ @user_mentions ||= entities(Twitter::Entity::UserMention, :user_mentions)
117
+ end
118
+
119
+ def entities?
120
+ !@attrs[:entities].nil?
121
+ end
122
+
123
+ private
124
+
125
+ # @param klass [Class]
126
+ # @param method [Symbol]
127
+ def entities(klass, method)
128
+ if entities?
129
+ Array(@attrs[:entities][method.to_sym]).map do |user_mention|
130
+ klass.fetch_or_new(user_mention)
131
+ end
132
+ else
133
+ warn "#{Kernel.caller.first}: To get #{method.to_s.tr('_', ' ')}, you must pass `:include_entities => true` when requesting the #{self.class.name}."
134
+ []
135
+ end
136
+ end
137
+
138
+ def user?
139
+ !@attrs[:user].nil?
140
+ end
141
+
142
+ end
143
+
144
+ Status = Tweet
145
+ end
@@ -0,0 +1,97 @@
1
+ require 'twitter/basic_user'
2
+ require 'twitter/core_ext/hash'
3
+ require 'twitter/creatable'
4
+ require 'twitter/tweet'
5
+
6
+ module Twitter
7
+ class User < Twitter::BasicUser
8
+ PROFILE_IMAGE_SUFFIX_REGEX = /_normal(\.gif|\.jpe?g|\.png)$/
9
+ include Twitter::Creatable
10
+ attr_reader :connections, :contributors_enabled, :default_profile,
11
+ :default_profile_image, :description, :favourites_count,
12
+ :follow_request_sent, :followers_count, :friends_count, :geo_enabled,
13
+ :is_translator, :lang, :listed_count, :location, :name, :notifications,
14
+ :profile_background_color, :profile_background_image_url,
15
+ :profile_background_image_url_https, :profile_background_tile,
16
+ :profile_link_color, :profile_sidebar_border_color,
17
+ :profile_sidebar_fill_color, :profile_text_color,
18
+ :profile_use_background_image, :protected, :statuses_count, :time_zone,
19
+ :url, :utc_offset, :verified
20
+ alias contributors_enabled? contributors_enabled
21
+ alias default_profile? default_profile
22
+ alias default_profile_image? default_profile_image
23
+ alias follow_request_sent? follow_request_sent
24
+ alias favorite_count favourites_count
25
+ alias favorites_count favourites_count
26
+ alias favourite_count favourites_count
27
+ alias follower_count followers_count
28
+ alias friend_count friends_count
29
+ alias geo_enabled? geo_enabled
30
+ alias is_translator? is_translator
31
+ alias notifications? notifications
32
+ alias profile_background_tile? profile_background_tile
33
+ alias profile_use_background_image? profile_use_background_image
34
+ alias protected? protected
35
+ alias status_count statuses_count
36
+ alias translator is_translator
37
+ alias translator? is_translator
38
+ alias tweet_count statuses_count
39
+ alias tweets_count statuses_count
40
+ alias update_count statuses_count
41
+ alias updates_count statuses_count
42
+ alias verified? verified
43
+
44
+ # Return the URL to the user's profile image
45
+ #
46
+ # @param size [String, Symbol] The size of the image. Must be one of: 'mini', 'normal', 'bigger' or 'original'
47
+ # @return [String]
48
+ def profile_image_url(size=:normal)
49
+ # The profile image URL comes in looking like like this:
50
+ # http://a0.twimg.com/profile_images/1759857427/image1326743606_normal.png
51
+ # It can be converted to any of the following sizes:
52
+ # http://a0.twimg.com/profile_images/1759857427/image1326743606.png
53
+ # http://a0.twimg.com/profile_images/1759857427/image1326743606_mini.png
54
+ # http://a0.twimg.com/profile_images/1759857427/image1326743606_bigger.png
55
+ resize_profile_image_url(@attrs[:profile_image_url], size)
56
+ end
57
+
58
+ # Return the secure URL to the user's profile image
59
+ #
60
+ # @param size [String, Symbol] The size of the image. Must be one of: 'mini', 'normal', 'bigger' or 'original'
61
+ # @return [String]
62
+ def profile_image_url_https(size=:normal)
63
+ # The profile image URL comes in looking like like this:
64
+ # https://a0.twimg.com/profile_images/1759857427/image1326743606_normal.png
65
+ # It can be converted to any of the following sizes:
66
+ # https://a0.twimg.com/profile_images/1759857427/image1326743606.png
67
+ # https://a0.twimg.com/profile_images/1759857427/image1326743606_mini.png
68
+ # https://a0.twimg.com/profile_images/1759857427/image1326743606_bigger.png
69
+ resize_profile_image_url(@attrs[:profile_image_url_https], size)
70
+ end
71
+
72
+ # @return [Twitter::Tweet]
73
+ def status
74
+ @status ||= Twitter::Tweet.fetch_or_new(@attrs.dup[:status].merge(:user => @attrs.except(:status))) if status?
75
+ end
76
+
77
+ def status?
78
+ !@attrs[:status].nil?
79
+ end
80
+
81
+ private
82
+
83
+ def resize_profile_image_url(url, size)
84
+ return if url.nil?
85
+ url.sub(PROFILE_IMAGE_SUFFIX_REGEX, profile_image_suffix(size))
86
+ end
87
+
88
+ def profile_image_suffix(size)
89
+ if :original == size.to_sym
90
+ "\\1"
91
+ else
92
+ "_#{size}\\1"
93
+ end
94
+ end
95
+
96
+ end
97
+ end