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,10 @@
1
+ require 'twitter/error/client_error'
2
+
3
+ module Twitter
4
+ class Error
5
+ # Raised when Twitter returns the HTTP status code 404
6
+ class NotFound < Twitter::Error::ClientError
7
+ HTTP_STATUS_CODE = 404
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ require 'twitter/error/client_error'
2
+
3
+ module Twitter
4
+ class Error
5
+ # Raised when Twitter returns the HTTP status code 429
6
+ class RateLimited < Twitter::Error::ClientError
7
+ HTTP_STATUS_CODE = 429
8
+ end
9
+ EnhanceYourCalm = RateLimited
10
+ end
11
+ end
@@ -0,0 +1,28 @@
1
+ require 'twitter/error'
2
+
3
+ module Twitter
4
+ class Error
5
+ # Raised when Twitter returns a 5xx HTTP status code
6
+ class ServerError < Twitter::Error
7
+ MESSAGE = "Server Error"
8
+
9
+ # Create a new error from an HTTP environment
10
+ #
11
+ # @param response [Hash]
12
+ # @return [Twitter::Error]
13
+ def self.from_response(response={})
14
+ new(nil, response[:response_headers])
15
+ end
16
+
17
+ # Initializes a new ServerError object
18
+ #
19
+ # @param message [String]
20
+ # @param response_headers [Hash]
21
+ # @return [Twitter::Error::ServerError]
22
+ def initialize(message=nil, response_headers={})
23
+ super((message || self.class.const_get(:MESSAGE)), response_headers)
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,11 @@
1
+ require 'twitter/error/server_error'
2
+
3
+ module Twitter
4
+ class Error
5
+ # Raised when Twitter returns the HTTP status code 503
6
+ class ServiceUnavailable < Twitter::Error::ServerError
7
+ HTTP_STATUS_CODE = 503
8
+ MESSAGE = "(__-){ Twitter is over capacity."
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ require 'twitter/error/client_error'
2
+
3
+ module Twitter
4
+ class Error
5
+ # Raised when Twitter returns the HTTP status code 401
6
+ class Unauthorized < Twitter::Error::ClientError
7
+ HTTP_STATUS_CODE = 401
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,21 @@
1
+ require 'twitter/core_ext/string'
2
+
3
+ module Twitter
4
+ class Factory
5
+
6
+ # Instantiates a new action object
7
+ #
8
+ # @param attrs [Hash]
9
+ # @raise [ArgumentError] Error raised when supplied argument is missing an :action key.
10
+ # @return [Twitter::Action::Favorite, Twitter::Action::Follow, Twitter::Action::ListMemberAdded, Twitter::Action::Mention, Twitter::Action::Reply, Twitter::Action::Retweet]
11
+ def self.fetch_or_new(method, klass, attrs={})
12
+ return unless attrs
13
+ if type = attrs.delete(method.to_sym)
14
+ klass.const_get(type.camelize.to_sym).fetch_or_new(attrs)
15
+ else
16
+ raise ArgumentError, "argument must have :#{method} key"
17
+ end
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ require 'twitter/base'
2
+
3
+ module Twitter
4
+ class Geo < Twitter::Base
5
+ attr_reader :coordinates
6
+ alias coords coordinates
7
+
8
+ # @param other [Twitter::Geo]
9
+ # @return [Boolean]
10
+ def ==(other)
11
+ super || attr_equal(:coordinates, other) || attrs_equal(other)
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ require 'twitter/geo'
2
+
3
+ module Twitter
4
+ class Geo
5
+ class Point < Twitter::Geo
6
+
7
+ # @return [Integer]
8
+ def latitude
9
+ self.coordinates[0]
10
+ end
11
+ alias lat latitude
12
+
13
+ # @return [Integer]
14
+ def longitude
15
+ self.coordinates[1]
16
+ end
17
+ alias long longitude
18
+ alias lng longitude
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,8 @@
1
+ require 'twitter/geo'
2
+
3
+ module Twitter
4
+ class Geo
5
+ class Polygon < Twitter::Geo
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,18 @@
1
+ require 'twitter/factory'
2
+ require 'twitter/geo/point'
3
+ require 'twitter/geo/polygon'
4
+
5
+ module Twitter
6
+ class GeoFactory < Twitter::Factory
7
+
8
+ # Instantiates a new geo object
9
+ #
10
+ # @param attrs [Hash]
11
+ # @raise [ArgumentError] Error raised when supplied argument is missing a :type key.
12
+ # @return [Twitter::Geo]
13
+ def self.fetch_or_new(attrs={})
14
+ super(:type, Twitter::Geo, attrs)
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,50 @@
1
+ require 'twitter/base'
2
+ require 'twitter/error/identity_map_key_error'
3
+
4
+ module Twitter
5
+ class Identity < Twitter::Base
6
+
7
+ def self.fetch(attrs)
8
+ return unless identity_map
9
+
10
+ id = attrs[:id]
11
+ if id && object = identity_map.fetch(id)
12
+ return object.update(attrs)
13
+ end
14
+
15
+ return yield if block_given?
16
+ raise Twitter::Error::IdentityMapKeyError, "key not found"
17
+ end
18
+
19
+ # Stores an object in the identity map.
20
+ #
21
+ # @param object [Object]
22
+ # @return [Twitter::Identity]
23
+ def self.store(object)
24
+ return object unless identity_map
25
+ identity_map.store(object.id, object)
26
+ end
27
+
28
+ # Initializes a new object
29
+ #
30
+ # @param attrs [Hash]
31
+ # @raise [ArgumentError] Error raised when supplied argument is missing an :id key.
32
+ # @return [Twitter::Identity]
33
+ def initialize(attrs={})
34
+ super
35
+ raise ArgumentError, "argument must have an :id key" unless id
36
+ end
37
+
38
+ # @param other [Twitter::Identity]
39
+ # @return [Boolean]
40
+ def ==(other)
41
+ super || attr_equal(:id, other) || attrs_equal(other)
42
+ end
43
+
44
+ # @return [Integer]
45
+ def id
46
+ @attrs[:id]
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,22 @@
1
+ module Twitter
2
+
3
+ # Tracks objects to help ensure that each object gets loaded only once.
4
+ # See: http://www.martinfowler.com/eaaCatalog/identityMap.html
5
+ class IdentityMap < Hash
6
+
7
+ # @param id
8
+ # @return [Object]
9
+ def fetch(id)
10
+ self[id]
11
+ end
12
+
13
+ # @param id
14
+ # @param object
15
+ # @return [Object]
16
+ def store(id, object)
17
+ self[id] = object
18
+ end
19
+
20
+ end
21
+
22
+ end
@@ -0,0 +1,7 @@
1
+ require 'twitter/base'
2
+
3
+ module Twitter
4
+ class Language < Twitter::Base
5
+ attr_reader :code, :name, :status
6
+ end
7
+ end
@@ -0,0 +1,18 @@
1
+ require 'twitter/creatable'
2
+ require 'twitter/identity'
3
+ require 'twitter/user'
4
+
5
+ module Twitter
6
+ class List < Twitter::Identity
7
+ include Twitter::Creatable
8
+ attr_reader :description, :following, :full_name, :member_count,
9
+ :mode, :name, :slug, :subscriber_count, :uri
10
+ alias following? following
11
+
12
+ # @return [Twitter::User]
13
+ def user
14
+ @user ||= Twitter::User.fetch_or_new(@attrs[:user])
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ require 'twitter/identity'
2
+ require 'twitter/size'
3
+
4
+ module Twitter
5
+ module Media
6
+ class Photo < Twitter::Identity
7
+ attr_reader :display_url, :expanded_url, :indices, :media_url,
8
+ :media_url_https, :url
9
+
10
+ # Returns an array of photo sizes
11
+ #
12
+ # @return [Array<Twitter::Size>]
13
+ def sizes
14
+ @sizes ||= Array(@attrs[:sizes]).inject({}) do |object, (key, value)|
15
+ object[key] = Twitter::Size.fetch_or_new(value)
16
+ object
17
+ end
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ require 'twitter/factory'
2
+ require 'twitter/media/photo'
3
+
4
+ module Twitter
5
+ class MediaFactory < Twitter::Factory
6
+
7
+ # Instantiates a new media object
8
+ #
9
+ # @param attrs [Hash]
10
+ # @raise [ArgumentError] Error raised when supplied argument is missing a :type key.
11
+ # @return [Twitter::Media]
12
+ def self.fetch_or_new(attrs={})
13
+ super(:type, Twitter::Media, attrs)
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ require 'twitter/base'
2
+
3
+ module Twitter
4
+ class Metadata < Twitter::Base
5
+ attr_reader :result_type
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ require 'twitter/base'
2
+
3
+ module Twitter
4
+ class OEmbed < Twitter::Base
5
+ attr_reader :author_name, :author_url, :cache_age, :height, :html,
6
+ :provider_name, :provider_url, :type, :url, :version, :width
7
+ end
8
+ end
@@ -0,0 +1,34 @@
1
+ require 'twitter/geo_factory'
2
+ require 'twitter/identity'
3
+
4
+ module Twitter
5
+ class Place < Twitter::Identity
6
+ attr_reader :attributes, :country, :full_name, :name, :url, :woeid
7
+ alias woe_id woeid
8
+
9
+ # @return [Twitter::Geo]
10
+ def bounding_box
11
+ @bounding_box ||= Twitter::GeoFactory.fetch_or_new(@attrs[:bounding_box])
12
+ end
13
+
14
+ # @return [String]
15
+ def country_code
16
+ @country_code ||= @attrs[:country_code] || @attrs[:countryCode]
17
+ end
18
+
19
+ # @return [Integer]
20
+ def parent_id
21
+ @parent_id ||= @attrs[:parentid]
22
+ end
23
+
24
+ # @return [String]
25
+ def place_type
26
+ @place_type ||= @attrs[:place_type] || @attrs[:placeType] && @attrs[:placeType][:name]
27
+ end
28
+
29
+ def id
30
+ @attrs[:id] || @attrs[:woeid]
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,45 @@
1
+ module Twitter
2
+ class RateLimit
3
+ attr_reader :attrs
4
+ alias to_hash attrs
5
+
6
+ # @return [Twitter::RateLimit]
7
+ def initialize(attrs={})
8
+ @attrs = attrs
9
+ end
10
+
11
+ # @return [Integer]
12
+ def limit
13
+ limit = @attrs['x-rate-limit-limit']
14
+ limit.to_i if limit
15
+ end
16
+
17
+ # @return [Integer]
18
+ def remaining
19
+ remaining = @attrs['x-rate-limit-remaining']
20
+ remaining.to_i if remaining
21
+ end
22
+
23
+ # @return [Time]
24
+ def reset_at
25
+ reset = @attrs['x-rate-limit-reset']
26
+ Time.at(reset.to_i) if reset
27
+ end
28
+
29
+ # @return [Integer]
30
+ def reset_in
31
+ [(reset_at - Time.now).ceil, 0].max if reset_at
32
+ end
33
+ alias retry_after reset_in
34
+
35
+ # Update the attributes of a RateLimit
36
+ #
37
+ # @param attrs [Hash]
38
+ # @return [Twitter::RateLimit]
39
+ def update(attrs)
40
+ @attrs.update(attrs)
41
+ self
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,36 @@
1
+ require 'twitter/base'
2
+ require 'twitter/source_user'
3
+ require 'twitter/target_user'
4
+
5
+ module Twitter
6
+ class Relationship < Twitter::Base
7
+
8
+ # Initializes a new object
9
+ #
10
+ # @param attrs [Hash]
11
+ # @return [Twitter::Relationship]
12
+ def initialize(attrs={})
13
+ @attrs = attrs[:relationship]
14
+ end
15
+
16
+ # @return [Twitter::SourceUser]
17
+ def source
18
+ @source ||= Twitter::SourceUser.fetch_or_new(@attrs[:source])
19
+ end
20
+
21
+ # @return [Twitter::TargetUser]
22
+ def target
23
+ @target ||= Twitter::TargetUser.fetch_or_new(@attrs[:target])
24
+ end
25
+
26
+ # Update the attributes of a Relationship
27
+ #
28
+ # @param attrs [Hash]
29
+ # @return [Twitter::Relationship]
30
+ def update(attrs)
31
+ @attrs.update(attrs[:relationship]) unless attrs[:relationship].nil?
32
+ self
33
+ end
34
+
35
+ end
36
+ end