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
+ class String
2
+
3
+ # Converts a snake_case string to CamelCase
4
+ #
5
+ # @return [String]
6
+ def camelize
7
+ self.gsub(/\/(.?)/){"::#{$1.upcase}"}.gsub(/(?:^|_)(.)/){$1.upcase}
8
+ end unless method_defined?(:camelize)
9
+
10
+ end
@@ -0,0 +1,20 @@
1
+ require 'time'
2
+
3
+ module Twitter
4
+ module Creatable
5
+
6
+ # Time when the object was created on Twitter
7
+ #
8
+ # @return [Time]
9
+ def created_at
10
+ @created_at ||= Time.parse(@attrs[:created_at]) if created?
11
+ end
12
+
13
+ private
14
+
15
+ def created?
16
+ !@attrs[:created_at].nil?
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,87 @@
1
+ require 'twitter/core_ext/kernel'
2
+
3
+ module Twitter
4
+ class Cursor
5
+ include Enumerable
6
+ attr_reader :attrs, :collection
7
+ alias to_hash attrs
8
+
9
+ # Initializes a new Cursor object
10
+ #
11
+ # @param response [Hash]
12
+ # @param collection_name [String, Symbol] The name of the method to return the collection
13
+ # @param klass [Class] The class to instantiate object in the collection
14
+ # @param client [Twitter::Client]
15
+ # @param method_name [String, Symbol]
16
+ # @param method_options [Hash]
17
+ # @return [Twitter::Cursor]
18
+ def self.from_response(response, collection_name, klass, client, method_name, method_options)
19
+ new(response[:body], collection_name, klass, client, method_name, method_options)
20
+ end
21
+
22
+ # Initializes a new Cursor
23
+ #
24
+ # @param attrs [Hash]
25
+ # @param collection_name [String, Symbol] The name of the method to return the collection
26
+ # @param klass [Class] The class to instantiate object in the collection
27
+ # @param client [Twitter::Client]
28
+ # @param method_name [String, Symbol]
29
+ # @param method_options [Hash]
30
+ # @return [Twitter::Cursor]
31
+ def initialize(attrs, collection_name, klass, client, method_name, method_options)
32
+ @attrs = attrs
33
+ @client = client
34
+ @method_name = method_name
35
+ @method_options = method_options
36
+ @collection = Array(attrs[collection_name.to_sym]).map do |item|
37
+ if klass
38
+ klass.fetch_or_new(item)
39
+ else
40
+ item
41
+ end
42
+ end
43
+ class_eval do
44
+ alias_method(collection_name.to_sym, :collection)
45
+ end
46
+ end
47
+
48
+ # @param collection [Array]
49
+ # @param cursor [Integer]
50
+ # @return [Array]
51
+ def all(collection=collection, cursor=next_cursor)
52
+ cursor = @client.send(@method_name.to_sym, @method_options.merge(:cursor => cursor))
53
+ collection += cursor.collection
54
+ cursor.last? ? collection.flatten : all(collection, cursor.next_cursor)
55
+ end
56
+
57
+ # @return [Enumerable]
58
+ def each
59
+ all(collection, next_cursor).each do |element|
60
+ yield element
61
+ end
62
+ end
63
+
64
+ def next_cursor
65
+ @attrs[:next_cursor] || -1
66
+ end
67
+ alias next next_cursor
68
+
69
+ def previous_cursor
70
+ @attrs[:previous_cursor]
71
+ end
72
+ alias previous previous_cursor
73
+
74
+ # @return [Boolean]
75
+ def first?
76
+ previous_cursor.zero?
77
+ end
78
+ alias first first?
79
+
80
+ # @return [Boolean]
81
+ def last?
82
+ next_cursor.zero?
83
+ end
84
+ alias last last?
85
+
86
+ end
87
+ end
@@ -0,0 +1,101 @@
1
+ require 'faraday'
2
+ require 'twitter/configurable'
3
+ require 'twitter/error/client_error'
4
+ require 'twitter/error/server_error'
5
+ require 'twitter/identity_map'
6
+ require 'twitter/request/multipart_with_file'
7
+ require 'twitter/response/parse_json'
8
+ require 'twitter/response/raise_error'
9
+ require 'twitter/version'
10
+
11
+ module Twitter
12
+ module Default
13
+ ENDPOINT = 'https://api.twitter.com' unless defined? ENDPOINT
14
+ CONNECTION_OPTIONS = {
15
+ :headers => {
16
+ :accept => 'application/json',
17
+ :user_agent => "Twitter Ruby Gem #{Twitter::Version}"
18
+ },
19
+ :open_timeout => 5,
20
+ :raw => true,
21
+ :ssl => {:verify => false},
22
+ :timeout => 10,
23
+ } unless defined? CONNECTION_OPTIONS
24
+ IDENTITY_MAP = false unless defined? IDENTITY_MAP
25
+ MIDDLEWARE = Faraday::Builder.new(
26
+ &Proc.new do |builder|
27
+ # Convert file uploads to Faraday::UploadIO objects
28
+ builder.use Twitter::Request::MultipartWithFile
29
+ # Checks for files in the payload
30
+ builder.use Faraday::Request::Multipart
31
+ # Convert request params to "www-form-urlencoded"
32
+ builder.use Faraday::Request::UrlEncoded
33
+ # Handle 4xx server responses
34
+ builder.use Twitter::Response::RaiseError, Twitter::Error::ClientError
35
+ # Parse JSON response bodies using MultiJson
36
+ builder.use Twitter::Response::ParseJson
37
+ # Handle 5xx server responses
38
+ builder.use Twitter::Response::RaiseError, Twitter::Error::ServerError
39
+ # Set Faraday's HTTP adapter
40
+ builder.adapter Faraday.default_adapter
41
+ end
42
+ )
43
+
44
+ class << self
45
+
46
+ # @return [Hash]
47
+ def options
48
+ Hash[Twitter::Configurable.keys.map{|key| [key, send(key)]}]
49
+ end
50
+
51
+ # @return [String]
52
+ def consumer_key
53
+ ENV['TWITTER_CONSUMER_KEY']
54
+ end
55
+
56
+ # @return [String]
57
+ def consumer_secret
58
+ ENV['TWITTER_CONSUMER_SECRET']
59
+ end
60
+
61
+ # @return [String]
62
+ def oauth_token
63
+ ENV['TWITTER_OAUTH_TOKEN']
64
+ end
65
+
66
+ # @return [String]
67
+ def oauth_token_secret
68
+ ENV['TWITTER_OAUTH_TOKEN_SECRET']
69
+ end
70
+
71
+ # @note This is configurable in case you want to use HTTP instead of HTTPS or use a Twitter-compatible endpoint.
72
+ # @see http://status.net/wiki/Twitter-compatible_API
73
+ # @see http://en.blog.wordpress.com/2009/12/12/twitter-api/
74
+ # @see http://staff.tumblr.com/post/287703110/api
75
+ # @see http://developer.typepad.com/typepad-twitter-api/twitter-api.html
76
+ # @return [String]
77
+ def endpoint
78
+ ENDPOINT
79
+ end
80
+
81
+ # @return [Hash]
82
+ def connection_options
83
+ CONNECTION_OPTIONS
84
+ end
85
+
86
+ # @return [Twitter::IdentityMap]
87
+ def identity_map
88
+ IDENTITY_MAP
89
+ end
90
+
91
+ # @note Faraday's middleware stack implementation is comparable to that of Rack middleware. The order of middleware is important: the first middleware on the list wraps all others, while the last middleware is the innermost one.
92
+ # @see https://github.com/technoweenie/faraday#advanced-middleware-usage
93
+ # @see http://mislav.uniqpath.com/2011/07/faraday-advanced-http/
94
+ # @return [Faraday::Builder]
95
+ def middleware
96
+ MIDDLEWARE
97
+ end
98
+
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,21 @@
1
+ require 'twitter/creatable'
2
+ require 'twitter/identity'
3
+ require 'twitter/user'
4
+
5
+ module Twitter
6
+ class DirectMessage < Twitter::Identity
7
+ include Twitter::Creatable
8
+ attr_reader :text
9
+
10
+ # @return [Twitter::User]
11
+ def recipient
12
+ @recipient ||= Twitter::User.fetch_or_new(@attrs[:recipient])
13
+ end
14
+
15
+ # @return [Twitter::User]
16
+ def sender
17
+ @sender ||= Twitter::User.fetch_or_new(@attrs[:sender])
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,7 @@
1
+ require 'twitter/base'
2
+
3
+ module Twitter
4
+ class Entity < Twitter::Base
5
+ attr_reader :indices
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ require 'twitter/entity'
2
+
3
+ module Twitter
4
+ class Entity
5
+ class Hashtag < Twitter::Entity
6
+ attr_reader :text
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'twitter/entity'
2
+
3
+ module Twitter
4
+ class Entity
5
+ class Url < Twitter::Entity
6
+ attr_reader :display_url, :expanded_url, :url
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'twitter/entity'
2
+
3
+ module Twitter
4
+ class Entity
5
+ class UserMention < Twitter::Entity
6
+ attr_reader :id, :name, :screen_name
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,34 @@
1
+ require 'twitter/rate_limit'
2
+
3
+ module Twitter
4
+ # Custom error class for rescuing from all Twitter errors
5
+ class Error < StandardError
6
+ attr_reader :rate_limit, :wrapped_exception
7
+
8
+ # @return [Hash]
9
+ def self.errors
10
+ @errors ||= Hash[descendants.map{|klass| [klass.const_get(:HTTP_STATUS_CODE), klass]}]
11
+ end
12
+
13
+ # @return [Array]
14
+ def self.descendants
15
+ ObjectSpace.each_object(::Class).select{|klass| klass < self}
16
+ end
17
+
18
+ # Initializes a new Error object
19
+ #
20
+ # @param exception [Exception, String]
21
+ # @param response_headers [Hash]
22
+ # @return [Twitter::Error]
23
+ def initialize(exception=$!, response_headers={})
24
+ @rate_limit = Twitter::RateLimit.new(response_headers)
25
+ @wrapped_exception = exception
26
+ exception.respond_to?(:backtrace) ? super(exception.message) : super(exception.to_s)
27
+ end
28
+
29
+ def backtrace
30
+ @wrapped_exception.respond_to?(:backtrace) ? @wrapped_exception.backtrace : super
31
+ end
32
+
33
+ end
34
+ 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 502
6
+ class BadGateway < Twitter::Error::ServerError
7
+ HTTP_STATUS_CODE = 502
8
+ MESSAGE = "Twitter is down or being upgraded."
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 400
6
+ class BadRequest < Twitter::Error::ClientError
7
+ HTTP_STATUS_CODE = 400
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,35 @@
1
+ require 'twitter/error'
2
+
3
+ module Twitter
4
+ class Error
5
+ # Raised when Twitter returns a 4xx HTTP status code or there's an error in Faraday
6
+ class ClientError < Twitter::Error
7
+
8
+ # Create a new error from an HTTP environment
9
+ #
10
+ # @param response [Hash]
11
+ # @return [Twitter::Error]
12
+ def self.from_response(response={})
13
+ new(parse_error(response[:body]), response[:response_headers])
14
+ end
15
+
16
+ private
17
+
18
+ def self.parse_error(body)
19
+ if body.nil?
20
+ ''
21
+ elsif body[:error]
22
+ body[:error]
23
+ elsif body[:errors]
24
+ first = Array(body[:errors]).first
25
+ if first.kind_of?(Hash)
26
+ first[:message].chomp
27
+ else
28
+ first.chomp
29
+ end
30
+ end
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,9 @@
1
+ require 'twitter/error'
2
+
3
+ module Twitter
4
+ class Error
5
+ # Raised when JSON parsing fails
6
+ class DecodeError < Twitter::Error
7
+ end
8
+ end
9
+ 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 403
6
+ class Forbidden < Twitter::Error::ClientError
7
+ HTTP_STATUS_CODE = 403
8
+ end
9
+ end
10
+ 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 504
6
+ class GatewayTimeout < Twitter::Error::ServerError
7
+ HTTP_STATUS_CODE = 504
8
+ MESSAGE = "The Twitter servers are up, but the request couldn't be serviced due to some failure within our stack. Try again later."
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ require 'twitter/error'
2
+
3
+ module Twitter
4
+ class Error
5
+ # Inherit from KeyError when Ruby 1.8 compatibility is removed
6
+ class IdentityMapKeyError < ::IndexError
7
+ end
8
+ end
9
+ 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 500
6
+ class InternalServerError < Twitter::Error::ServerError
7
+ HTTP_STATUS_CODE = 500
8
+ MESSAGE = "Something is technically wrong."
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 406
6
+ class NotAcceptable < Twitter::Error::ClientError
7
+ HTTP_STATUS_CODE = 406
8
+ end
9
+ end
10
+ end