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
data.tar.gz.sig CHANGED
Binary file
@@ -1,3 +1,33 @@
1
+ 5.0.0
2
+ -----
3
+ * [Remove `Twitter::API::Undocumented#status_activity` and `#statuses_activity`](https://github.com/sferik/twitter/commit/7f970810af251b2fe80c38b30c54485c55bd2034)
4
+ * [Remove `Twitter::Tweet#favoriters`, `#repliers`, `#repliers_count`, and `#retweeters`](https://github.com/sferik/twitter/commit/77cc963381a68e8299ef6c6b7a306b440666d792)
5
+ * [Remove identity map](https://github.com/sferik/twitter/commit/ec7c2df78a200e2b0b1cd3a40983c6ce9dee552d)
6
+ * [Remove `Twitter::Cursor#all`](https://github.com/sferik/twitter/commit/72be4148b973153c6d3044c406b768ad832555ff)
7
+ * [Remove `Twitter::Cursor#collection`](https://github.com/sferik/twitter/commit/9ae4621610ba6c26950e6b77f950f698cdfc8dac)
8
+ * [Remove `Twitter#from_user`](https://github.com/sferik/twitter/commit/d2ae9f1cc1f5224bcdff06cda65fabdf9e7fbcb3)
9
+ * [Remove `ClientError`, `ServerError`, and `ParserError`](https://github.com/sferik/twitter/commit/72843948d8a6f66345adc254fa91cf1097592b22)
10
+ * [Remove global configuration](https://github.com/sferik/twitter/commit/239c5a8462fabb8c8ef9ec6a4cdded34561d572d)
11
+ * [Replace `multi_json` with `json`](https://github.com/sferik/twitter/commit/e5fc292fee078567664acf6be4ed31a8ad077780)
12
+ * [Rename `oauth_token` to `access_token`](https://github.com/sferik/twitter/commit/d360f8015c487c4599460abd0dd0bc7e59a522a3)
13
+ * [Move `Twitter::Arguments` out of `REST::API` namespace](https://github.com/sferik/twitter/commit/8faa15309d906dd46fccc1b914ea4aa7a5da7c2d)
14
+ * [Move `Twitter::Client` into `REST` namespace](https://github.com/sferik/twitter/commit/5b8c3fd243227888fc0886b0bf864ecd3a018f99)
15
+ * [Add `Twitter::Streaming::Client`](https://github.com/sferik/twitter/commit/23afe90aa494229a4389c3e51f753102b34fc551)
16
+ * [Add `Twitter::Error::AlreadyPosted`](https://github.com/sferik/twitter/commit/e11d2a27dd0dfbbe16c812a81b9c2ab2852a7790)
17
+ * [Add `#url` methods to `Twitter::List`, `Twitter::Tweet`, and `Twitter::User`](https://github.com/sferik/twitter/commit/a89ec0f4e81097cc303b6c204e0375eb57ffd614)
18
+ * [Add `Twitter::Place#contained_within` and `#contained_within?`](https://github.com/sferik/twitter/commit/23cc247bd20001ecbafa544bfb4546bdfc630429)
19
+ * [Add `Twitter::GeoResults`](https://github.com/sferik/twitter/commit/be1a0a1425a6700267aae0f94a8835bff24dad56)
20
+ * [Add `NullObject`](https://github.com/sferik/twitter/commit/17880f491726cee77c1cbcf914887e95d5e6ae7e)
21
+ * [Add predicate methods for any possible `NullObject`](https://github.com/sferik/twitter/commit/eac5522edededacfc2a22d6f6879da43b8136d41)
22
+ * [Always return `URI` instead of `String`](https://github.com/sferik/twitter/commit/341f68d1a46667a820754d30ffa6ec2f50034afc)
23
+ * [Allow `URI` as argument](https://github.com/sferik/twitter/commit/c207567e674f108e4074e12c9e7343fb74e8a97c)
24
+ * [Allow `String` in addition to `URI` objects](https://github.com/sferik/twitter/commit/89a46fbd3560109da87d5f87262dcf6bd2a336c6)
25
+ * [Collection caching](https://github.com/sferik/twitter/commit/d484d7d7d7a0956f9b4fa6791a911ed7c9522cba)
26
+ * [Memoize result within `Twitter::Base#new_or_null_object`](https://github.com/sferik/twitter/commit/45dd18a9feadbb56a60cea76424dd466d3e80c5e)
27
+ * [Implement `Twitter::Cursor#each` without making an extra HTTP request](https://github.com/sferik/twitter/commit/8eeff57f5c6d6ca0a6f1ff5ebc31e652a71fc150)
28
+ * [Make `Twitter::SearchResults` enumerable](https://github.com/sferik/twitter/commit/d5ce8537164912e79dffc5a054ecd9ae6ecb8075)
29
+ * [Fix `Twitter::SearchResults#rpp` return value](https://github.com/sferik/twitter/commit/28d73200490ac2755c3e68d8d273fbc64a8d7066)
30
+
1
31
  4.8.1
2
32
  -----
3
33
  * [Ignore case of profile image extension](https://github.com/sferik/twitter/commit/73760610e959ae868de23de3da661d237fbcb106)
data/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2006-2013 John Nunemaker, Wynn Netherland, Erik Michaels-Ober, Steve Richert
1
+ Copyright (c) 2006-2013 Erik Michaels-Ober, John Nunemaker, Wynn Netherland, Steve Richert, Steve Agalloco
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -29,32 +29,6 @@ Then, install the gem with the high security trust policy:
29
29
 
30
30
  gem install twitter -P HighSecurity
31
31
 
32
- ## Quick Start Guide
33
- So you want to get up and tweeting as fast as possible?
34
-
35
- First, [register your application with Twitter][register].
36
-
37
- Then, copy and paste in your OAuth data.
38
-
39
- ```ruby
40
- Twitter.configure do |config|
41
- config.consumer_key = YOUR_CONSUMER_KEY
42
- config.consumer_secret = YOUR_CONSUMER_SECRET
43
- config.oauth_token = YOUR_OAUTH_TOKEN
44
- config.oauth_token_secret = YOUR_OAUTH_TOKEN_SECRET
45
- end
46
- ```
47
-
48
- That's it! You're ready to Tweet:
49
- ```ruby
50
- Twitter.update("I'm tweeting with @gem!")
51
- ```
52
-
53
- For more examples of how to use the gem, read the [documentation][] or see [Usage Examples][] below.
54
-
55
- [register]: https://dev.twitter.com/apps/new
56
- [Usage Examples]: #usage-examples
57
-
58
32
  ## CLI
59
33
 
60
34
  Looking for the Twitter command-line interface? It was [removed][] from this
@@ -85,107 +59,411 @@ wiki][apps]!
85
59
 
86
60
  [apps]: https://github.com/sferik/twitter/wiki/apps
87
61
 
88
- ## Configuration
89
- Twitter API v1.1 requires you to authenticate via OAuth, so you'll need to
90
- [register your application with Twitter][register]. Once you've registered an
91
- application, make sure to set the correct access level, otherwise you may see
92
- the error:
62
+ ## What's New in Version 5?
63
+ ### Configuration
64
+ Global configuration has been removed, as it was not threadsafe. Instead, you
65
+ can configure a `Twitter::REST::Client` by passing it a block when it's
66
+ initialized.
93
67
 
94
- Read-only application cannot POST
68
+ ```ruby
69
+ client = Twitter::REST::Client.new do |config|
70
+ config.consumer_key = "YOUR_CONSUMER_KEY"
71
+ config.consumer_secret = "YOUR_CONSUMER_SECRET"
72
+ config.access_token = "YOUR_ACCESS_TOKEN"
73
+ config.access_token_secret = "YOUR_ACCESS_SECRET"
74
+ end
75
+ ```
95
76
 
96
- Your new application will be assigned a consumer key/secret pair and you will
97
- be assigned an OAuth access token/secret pair for that application. You'll need
98
- to configure these values before you make a request or else you'll get the
99
- error:
77
+ Alternately, you can configure a `Twitter::REST::Client` piecemeal, after it
78
+ has been initialized, if that better suits your application:
100
79
 
101
- Bad Authentication data
80
+ ```ruby
81
+ client = Twitter::REST::Client.new
82
+ client.consumer_key = "YOUR_CONSUMER_KEY"
83
+ client.consumer_secret = "YOUR_CONSUMER_SECRET"
84
+ client.access_token = "YOUR_ACCESS_TOKEN"
85
+ client.access_token_secret = "YOUR_ACCESS_SECRET"
86
+ ```
87
+
88
+ Note: `oauth_token` has been renamed to `access_token` and `oauth_token_secret`
89
+ is now `access_token_secret` to conform to the terminology used in Twitter's
90
+ developer documentation.
91
+
92
+ ### Streaming (Experimental)
93
+ This library now offers support for the [Twitter Streaming API][streaming]. We
94
+ previously recommended using [TweetStream][] for this, however [TweetStream
95
+ does not work on Ruby 2.0.0][bug].
102
96
 
103
- Applications that make requests on behalf of a single Twitter user can pass
104
- global configuration options as a block to the `Twitter.configure` method.
97
+ [streaming]: https://dev.twitter.com/docs/streaming-apis
98
+ [tweetstream]: http://rubygems.org/gems/tweetstream
99
+ [bug]: https://github.com/tweetstream/tweetstream/issues/117
100
+
101
+ Unlike the rest of this library, this feature is not well tested and not
102
+ recommended for production applications. That said, if you need to do Twitter
103
+ streaming on Ruby 2.0.0, this is probably your best option. I've decided to
104
+ ship it as an experimental feature and make it more robust over time. Patches
105
+ in this area are particularly welcome.
106
+
107
+ Hopefully, by the time version 6 is released, this gem can fully replace
108
+ [TweetStream][], [em-twitter][], [twitterstream][], and [twitter-stream].
109
+ Special thanks to [Steve Agalloco][spagalloco], [Tim Carey-Smith][halorgium],
110
+ and [Tony Arcieri][tarcieri] for helping to develop this feature.
111
+
112
+ [em-twitter]: http://rubygems.org/gems/em-twitter
113
+ [twitterstream]: http://rubygems.org/gems/twitterstream
114
+ [twitter-stream]: http://rubygems.org/gems/twitter-stream
115
+ [spagalloco]: https://github.com/spagalloco
116
+ [halorgium]: https://github.com/halorgium
117
+ [tarcieri]: https://github.com/tarcieri
118
+
119
+ **Configuration works just like `Twitter::REST::Client`**
105
120
 
106
121
  ```ruby
107
- Twitter.configure do |config|
108
- config.consumer_key = YOUR_CONSUMER_KEY
109
- config.consumer_secret = YOUR_CONSUMER_SECRET
110
- config.oauth_token = YOUR_OAUTH_TOKEN
111
- config.oauth_token_secret = YOUR_OAUTH_TOKEN_SECRET
122
+ client = Twitter::Streaming::Client.new do
123
+ config.consumer_key = "YOUR_CONSUMER_KEY"
124
+ config.consumer_secret = "YOUR_CONSUMER_SECRET"
125
+ config.access_token = "YOUR_ACCESS_TOKEN"
126
+ config.access_token_secret = "YOUR_ACCESS_SECRET"
112
127
  end
113
128
  ```
114
129
 
115
- Alternately, you can set the following environment variables:
130
+ **Stream mentions of coffee or tea**
116
131
 
117
- TWITTER_CONSUMER_KEY
118
- TWITTER_CONSUMER_SECRET
119
- TWITTER_OAUTH_TOKEN
120
- TWITTER_OAUTH_TOKEN_SECRET
132
+ ```ruby
133
+ topics = ["coffee", "tea"]
134
+ client.filter(:track => topics.join(",")) do |tweet|
135
+ puts tweet.text
136
+ end
137
+ ```
121
138
 
122
- After configuration, requests can be made like so:
139
+ **Stream a random sample of all tweets**
123
140
 
124
141
  ```ruby
125
- Twitter.update("I'm tweeting with @gem!")
142
+ client.sample do |tweet|
143
+ puts tweet.text
144
+ end
126
145
  ```
127
146
 
128
- #### Thread Safety
129
- Applications that make requests on behalf of multiple Twitter users should
130
- avoid using global configuration. In this case, you may still specify the
131
- `consumer_key` and `consumer_secret` globally. (In a Rails application, this
132
- could go in `config/initializers/twitter.rb`.)
147
+ **Stream tweets for the authenticated user**
133
148
 
134
149
  ```ruby
135
- Twitter.configure do |config|
136
- config.consumer_key = YOUR_CONSUMER_KEY
137
- config.consumer_secret = YOUR_CONSUMER_SECRET
150
+ client.user do |tweet|
151
+ puts tweet.text
138
152
  end
139
153
  ```
140
154
 
141
- Then, for each user's access token/secret pair, instantiate a
142
- `Twitter::Client`:
155
+ Currently, this library will only stream tweets. The goal is to eventually
156
+ handle all [streaming message types][messages]. Patches that add support for a
157
+ new message type would be appreciated.
158
+
159
+ [messages]: https://dev.twitter.com/docs/streaming-apis/messages
160
+
161
+ ### Cursors
162
+ The `Twitter::Cursor` class has been completely redesigned with a focus on
163
+ simplicity and performance.
164
+
165
+ [cursors]: https://dev.twitter.com/docs/misc/cursoring
166
+
167
+ <table>
168
+ <thead>
169
+ <tr>
170
+ <th>Notes</th>
171
+ <th colspan="2">Version 4</th>
172
+ <th colspan="2">Version 5</th>
173
+ </th>
174
+ <tr>
175
+ <th></th>
176
+ <th>Code</th>
177
+ <th>HTTP GETs</th>
178
+ <th>Code</th>
179
+ <th>HTTP GETs</th>
180
+ </th>
181
+ </thead>
182
+ <tbody>
183
+ <tr>
184
+ <td>
185
+ Are you at the start of the cursor?
186
+ </td>
187
+ <td>
188
+ <pre><code lang="ruby">client.friends.first</code></pre>
189
+ </td>
190
+ <td>
191
+ <em>Θ(1)</em>
192
+ </td>
193
+ <td>
194
+ <pre><code lang="ruby">client.friends.first?</code></pre>
195
+ </td>
196
+ <td>
197
+ <em>Θ(1)</em>
198
+ </td>
199
+ </tr>
200
+ <tr>
201
+ <td>
202
+ Return your most recent follower.
203
+ </td>
204
+ <td>
205
+ <pre><code lang="ruby">client.friends.users.first</code></pre>
206
+ </td>
207
+ <td>
208
+ <em>Θ(1)</em>
209
+ </td>
210
+ <td>
211
+ <pre><code lang="ruby">client.friends.first</code></pre>
212
+ </td>
213
+ <td>
214
+ <em>Θ(1)</em>
215
+ </td>
216
+ </tr>
217
+ <tr>
218
+ <td>
219
+ Return an array of all your friends.
220
+ </td>
221
+ <td>
222
+ <pre><code lang="ruby">client.friends.all</code></pre>
223
+ </td>
224
+ <td>
225
+ <em>Θ(n+1)</em>
226
+ </td>
227
+ <td>
228
+ <pre><code lang="ruby">client.friends.to_a</code></pre>
229
+ </td>
230
+ <td>
231
+ <em>Θ(n)</em>
232
+ </td>
233
+ </tr>
234
+ <tr>
235
+ <td>
236
+ Collect your 20 most recent friends.
237
+ </td>
238
+ <td>
239
+ <pre><code lang="ruby">client.friends.take(20)</code></pre>
240
+ </td>
241
+ <td>
242
+ <em>Θ(n+1)</em>
243
+ </td>
244
+ <td>
245
+ <pre><code lang="ruby">client.friends.take(20)</code></pre>
246
+ </td>
247
+ <td>
248
+ <em>Θ(1)</em>
249
+ </td>
250
+ </tr>
251
+ <tr>
252
+ <td>
253
+ Collect your 20 most recent friends (twice).
254
+ </td>
255
+ <td>
256
+ <pre><code lang="ruby">friends = client.friends
257
+ 2.times.collect do
258
+ friends.take(20)
259
+ end</code></pre>
260
+ </td>
261
+ <td>
262
+ <em>Θ(2n+2)</em>
263
+ </td>
264
+ <td>
265
+ <pre><code lang="ruby">friends = client.friends
266
+ 2.times.collect do
267
+ friends.take(20)
268
+ end</code></pre>
269
+ </td>
270
+ <td>
271
+ <em>Θ(1)</em>
272
+ </td>
273
+ </tr>
274
+ </tbody>
275
+ </table>
276
+
277
+ In the examples above, *n* varies with the number of people the authenticated
278
+ user follows on Twitter. This resource returns up to 20 friends per HTTP GET,
279
+ so if the authenticated user follows 200 people, calling
280
+ `client.friends.take(20)` would make 11 HTTP requests in version 4. In version
281
+ 5, it makes just 1 HTTP request. Keep in mind, eliminating a single HTTP
282
+ request to the Twitter API will reduce the latency of your application by
283
+ [about 500 ms][status].
284
+
285
+ [status]: https://dev.twitter.com/status
286
+
287
+ The last example might seem contrived ("Why would I call
288
+ `client.friends.take(20)` twice?") but it applies to any
289
+ [`Enumerable`][enumerable] method you might call on a cursor, including:
290
+ `#all?`, `#collect`, `#count`, `#each`, `#inject`, `#max`, `#min`, `#reject`,
291
+ `#reverse_each`, `#select`, `#sort`, `#sort_by`, and `#to_a`. In version 4,
292
+ each time you called one of those methods, it would perform *n+1* HTTP
293
+ requests. In version 5, it only performs those HTTP requests the first time any
294
+ one of those methods is called. Each subsequent call fetches data from a
295
+ [cache][].
296
+
297
+ [enumerable]: http://ruby-doc.org/core-2.0/Enumerable.html
298
+ [cache]: https://github.com/sferik/twitter/commit/7d8b2727af9400643ac397207185fd54e3f6387b
299
+
300
+ The performance improvements are actually even **better** than the table above
301
+ indicates. In version 5, calling `Twitter::Cursor#each` (or any
302
+ [`Enumerable`][enumerable] method) starts yielding results immediately and
303
+ continues yielding as each response comes back from the server. In version 4,
304
+ `#each` made a series of requests and waited for the last one to complete
305
+ before yielding any data.
306
+
307
+ Here is a list of the interface changes to `Twitter::Cursor`:
308
+
309
+ * `#all` has been replaced by `#to_a`.
310
+ * `#last` has been replaced by `#last?`.
311
+ * `#first` has been replaced by `#first?`.
312
+ * `#first` now returns the first element in the collection, as prescribed by `Enumerable`.
313
+ * `#collection` and its aliases have been removed.
314
+
315
+ ### Search Results
316
+ The `Twitter::SearchResults` class has also been redesigned to have an
317
+ [`Enumerable`][enumerable] interface. The `#statuses` method and its aliases
318
+ (`#collection` and `#results`) have been replaced by `#to_a`. Additionally,
319
+ this class no longer inherits from `Twitter::Base`. As a result, the `#[]`
320
+ method has been removed.
321
+
322
+ ### Trend Results
323
+ The `#trends` method now returns an [`Enumerable`][enumerable]
324
+ `Twitter::TrendResults` object instead of an array. This object provides
325
+ methods to determinte the recency of the trend (`#as_of`), when the trend
326
+ started (`#created_at`), and the location of the trend (`#location`). This data
327
+ was previously unavailable.
328
+
329
+ ### Geo Results
330
+ Similarly, the `#reverse_geocode`, `#geo_search`, and `#similar_places` methods
331
+ now return an [`Enumerable`][enumerable] `Twitter::GeoResults` object instead
332
+ of an array. This object provides access to the token to create a new place
333
+ (`#token`), which was previously unavailable.
334
+
335
+ ### Tweets
336
+ The `Twitter::Tweet` object has been cleaned up. The following methods have been
337
+ removed:
338
+
339
+ * `#from_user`
340
+ * `#from_user_id`
341
+ * `#from_user_name`
342
+ * `#to_user`
343
+ * `#to_user_id`
344
+ * `#to_user_name`
345
+ * `#profile_image_url`
346
+ * `#profile_image_url_https`
347
+
348
+ These attributes can be accessed on the `Twitter::User` object, returned
349
+ through the `#user` method.
350
+
351
+ ### Users
352
+ The `Twitter::User` object has also been cleaned up. The following aliases have
353
+ been removed:
354
+
355
+ * `#favorite_count` (use `#favorites_count`)
356
+ * `#favoriters_count` (use `#favorites_count`)
357
+ * `#favourite_count` (use `#favourites_count`)
358
+ * `#favouriters_count` (use `#favourites_count`)
359
+ * `#follower_count` (use `#followers_count`)
360
+ * `#friend_count` (use `#friends_count`)
361
+ * `#status_count` (use `#statuses_count`)
362
+ * `#tweet_count` (use `#tweets_count`)
363
+ * `#update_count` (use `#tweets_count`)
364
+ * `#updates_count` (use `#tweets_count`)
365
+ * `#translator` (use `#translator?`)
366
+
367
+ ### Errors
368
+ The `Twitter::Error::ClientError` and `Twitter::Error::ServerError` class
369
+ hierarchy has been removed. All errors now inherit directly from
370
+ `Twitter::Error`.
371
+
372
+ ### Null Objects
373
+ In version 4, methods you would expect to return a `Twitter` object would
374
+ return `nil` if that object was missing. This may have resulted in a
375
+ `NoMethodError`. To prevent such errors, you may have introduced checks for the
376
+ truthiness of the response, for example:
143
377
 
144
378
  ```ruby
145
- erik = Twitter::Client.new(
146
- :oauth_token => "Erik's access token",
147
- :oauth_token_secret => "Erik's access secret"
148
- )
379
+ status = client.status(55709764298092545)
380
+ if status.place
381
+ # Do something with the Twitter::Place object
382
+ elsif status.geo
383
+ # Do something with the Twitter::Geo object
384
+ end
385
+ ```
386
+ In version 5, all such methods will return a `Twitter::NullObject` instead of
387
+ `nil`. This should prevent `NoMethodError` but may result in unexpected
388
+ behavior if you have truthiness checks in place, since everything is truthy in
389
+ Ruby except `false` and `nil`. For these cases, there are now predicate
390
+ methods:
149
391
 
150
- john = Twitter::Client.new(
151
- :oauth_token => "John's access token",
152
- :oauth_token_secret => "John's access secret"
153
- )
392
+ ```ruby
393
+ status = client.status(55709764298092545)
394
+ if status.place?
395
+ # Do something with the Twitter::Place object
396
+ elsif status.geo?
397
+ # Do something with the Twitter::Geo object
398
+ end
154
399
  ```
155
400
 
156
- You can now make threadsafe requests as the authenticated user:
401
+ ### URI Methods
402
+ The `Twitter::List`, `Twitter::Tweet`, and `Twitter::User` objects all have a
403
+ `#uri` method, which returns an HTTPS URI to twitter.com. This clobbers the
404
+ `Twitter::List#uri` method, which previously returned the list URI's path (not
405
+ a URI).
406
+
407
+ These methods are aliased to `#url` for users who prefer that nomenclature.
408
+ `Twitter::User` previously had a `#url` method, which returned the user's
409
+ website. This URI is now available via the `#website` method.
410
+
411
+ All `#uri` methods now return `URI` objects instead of strings. To convert a
412
+ `URI` object to a string, call `#to_s` on it.
413
+
414
+ ## Configuration
415
+ Twitter API v1.1 requires you to authenticate via OAuth, so you'll need to
416
+ [register your application with Twitter][register]. Once you've registered an
417
+ application, make sure to set the correct access level, otherwise you may see
418
+ the error:
419
+
420
+ [register]: https://dev.twitter.com/apps
421
+
422
+ Read-only application cannot POST
423
+
424
+ Your new application will be assigned a consumer key/secret pair and you will
425
+ be assigned an OAuth access token/secret pair for that application. You'll need
426
+ to configure these values before you make a request or else you'll get the
427
+ error:
428
+
429
+ Bad Authentication data
430
+
431
+ You can pass configuration options as a block to `Twitter::REST::Client.new`.
157
432
 
158
433
  ```ruby
159
- Thread.new{erik.update("Tweeting as Erik!")}
160
- Thread.new{john.update("Tweeting as John!")}
434
+ client = Twitter::REST::Client.new do |config|
435
+ config.consumer_key = YOUR_APP_CONSUMER_KEY
436
+ config.consumer_secret = YOUR_APP_CONSUMER_SECRET
437
+ config.access_token = A_USER_ACCESS_TOKEN
438
+ config.access_token_secret = A_USER_ACCESS_SECRET
439
+ end
161
440
  ```
162
441
 
163
- Or, if you prefer, you can specify all configuration options when instantiating
164
- a `Twitter::Client`:
442
+ Alternately, you can set the following environment variables:
443
+
444
+ TWITTER_CONSUMER_KEY
445
+ TWITTER_CONSUMER_SECRET
446
+ TWITTER_ACCESS_TOKEN
447
+ TWITTER_ACCESS_TOKEN_SECRET
448
+
449
+ After configuration, requests can be made like so:
165
450
 
166
451
  ```ruby
167
- client = Twitter::Client.new(
168
- :consumer_key => "an application's consumer key",
169
- :consumer_secret => "an application's consumer secret",
170
- :oauth_token => "a user's access token",
171
- :oauth_token_secret => "a user's access secret"
172
- )
452
+ client.update("I'm tweeting with @gem!")
173
453
  ```
174
454
 
175
- This may be useful if you're using multiple consumer key/secret pairs.
176
-
177
- #### Middleware
455
+ ### Middleware
178
456
  The Faraday middleware stack is fully configurable and is exposed as a
179
457
  `Faraday::Builder` object. You can modify the default middleware in-place:
180
458
 
181
459
  ```ruby
182
- Twitter.middleware.insert_after Twitter::Response::RaiseError, CustomMiddleware
460
+ client.middleware.insert_after Twitter::Response::RaiseError, CustomMiddleware
183
461
  ```
184
462
 
185
463
  A custom adapter may be set as part of a custom middleware stack:
186
464
 
187
465
  ```ruby
188
- Twitter.middleware = Faraday::Builder.new(
466
+ client.middleware = Faraday::Builder.new(
189
467
  &Proc.new do |builder|
190
468
  # Specify a middleware stack here
191
469
  builder.adapter :some_other_adapter
@@ -195,114 +473,81 @@ Twitter.middleware = Faraday::Builder.new(
195
473
 
196
474
  ## Usage Examples
197
475
  All examples require an authenticated Twitter client. See the section on <a
198
- href="#configuration">configuration</a> above.
476
+ href="#configuration">configuration</a>.
199
477
 
200
478
  **Tweet (as the authenticated user)**
201
479
 
202
480
  ```ruby
203
- Twitter.update("I'm tweeting with @gem!")
481
+ client.update("I'm tweeting with @gem!")
204
482
  ```
205
483
  **Follow a user (by screen name or user ID)**
206
484
 
207
485
  ```ruby
208
- Twitter.follow("gem")
209
- Twitter.follow(213747670)
486
+ client.follow("gem")
487
+ client.follow(213747670)
210
488
  ```
211
489
  **Fetch a user (by screen name or user ID)**
212
490
 
213
491
  ```ruby
214
- Twitter.user("gem")
215
- Twitter.user(213747670)
492
+ client.user("gem")
493
+ client.user(213747670)
216
494
  ```
217
495
  **Fetch a cursored list of followers with profile details (by screen name or user ID, or by implict authenticated user)**
218
496
 
219
497
  ```ruby
220
- Twitter.followers("gem")
221
- Twitter.followers(213747670)
222
- Twitter.followers
498
+ client.followers("gem")
499
+ client.followers(213747670)
500
+ client.followers
223
501
  ```
224
502
  **Fetch a cursored list of friends with profile details (by screen name or user ID, or by implict authenticated user)**
225
503
 
226
504
  ```ruby
227
- Twitter.friends("gem")
228
- Twitter.friends(213747670)
229
- Twitter.friends
505
+ client.friends("gem")
506
+ client.friends(213747670)
507
+ client.friends
230
508
  ```
231
509
 
232
510
  **Fetch a collection of user_ids that the currently authenticated user does not want to receive retweets from**
233
511
 
234
512
  ```ruby
235
- Twitter.no_retweet_ids
513
+ client.no_retweet_ids
236
514
  ````
237
515
 
238
516
  **Fetch the timeline of Tweets by a user**
239
517
 
240
518
  ```ruby
241
- Twitter.user_timeline("gem")
242
- Twitter.user_timeline(213747670)
519
+ client.user_timeline("gem")
520
+ client.user_timeline(213747670)
243
521
  ```
244
522
  **Fetch the timeline of Tweets from the authenticated user's home page**
245
523
 
246
524
  ```ruby
247
- Twitter.home_timeline
525
+ client.home_timeline
248
526
  ```
249
527
  **Fetch the timeline of Tweets mentioning the authenticated user**
250
528
 
251
529
  ```ruby
252
- Twitter.mentions_timeline
530
+ client.mentions_timeline
253
531
  ```
254
532
  **Fetch a particular Tweet by ID**
255
533
 
256
534
  ```ruby
257
- Twitter.status(27558893223)
535
+ client.status(27558893223)
258
536
  ```
259
- **Find the 3 most recent marriage proposals to @justinbieber**
537
+ **Collect the 3 most recent marriage proposals to @justinbieber**
260
538
 
261
539
  ```ruby
262
- Twitter.search("to:justinbieber marry me", :count => 3, :result_type => "recent").results.map do |status|
263
- "#{status.from_user}: #{status.text}"
540
+ client.search("to:justinbieber marry me", :count => 3, :result_type => "recent").collect do |tweet|
541
+ "#{tweet.user.screen_name}: #{tweet.text}"
264
542
  end
265
543
  ```
266
544
  **Find a Japanese-language Tweet tagged #ruby (excluding retweets)**
267
545
 
268
546
  ```ruby
269
- Twitter.search("#ruby -rt", :lang => "ja", :count => 1).results.first.text
547
+ client.search("#ruby -rt", :lang => "ja").first.text
270
548
  ```
271
549
  For more usage examples, please see the full [documentation][].
272
550
 
273
- ## Streaming
274
- To access the Twitter Streaming API, we recommend [TweetStream][].
275
-
276
- [tweetstream]: https://github.com/intridea/tweetstream
277
-
278
- ## Performance
279
- You can improve performance by loading a faster JSON parsing library. By
280
- default, JSON will be parsed with [okjson][]. For faster JSON parsing, we
281
- recommend [Oj][].
282
-
283
- [okjson]: https://github.com/ddollar/okjson
284
- [oj]: https://rubygems.org/gems/oj
285
-
286
- ## Statistics
287
- Here are some fun facts about this library:
288
-
289
- * It is implemented in just 2,000 lines of Ruby code
290
- * With over 5,000 lines of specs, the spec-to-code ratio is about 2.5:1
291
- * The spec suite contains over 750 examples and runs in about 5 seconds
292
- * It has 100% C0 code coverage (the tests execute every line of
293
- source code at least once)
294
- * It is comprehensive: you can request all documented Twitter REST API
295
- resources (over 100 resources)
296
- * This gem works on every major Ruby implementation, including JRuby and
297
- Rubinius
298
- * The first version was released on November 26, 2006
299
- * This gem has just three runtime dependencies: `faraday`, `multi_json`, and
300
- `simple_oauth`
301
- * Previous versions of this gem have been [downloaded over half a million
302
- times][stats]
303
-
304
- [stats]: https://rubygems.org/gems/twitter
305
-
306
551
  ## Supported Ruby Versions
307
552
  This library aims to support and is [tested against][travis] the following Ruby
308
553
  implementations:
@@ -340,133 +585,8 @@ Constraint][pvc] with two digits of precision. For example:
340
585
  [semver]: http://semver.org/
341
586
  [pvc]: http://docs.rubygems.org/read/chapter/16#page74
342
587
 
343
- ## What's new in version 4?
344
- #### Twitter API v1.1
345
- Version 4 of this library targets Twitter API v1.1. To understand the
346
- implications of this change, please read the following announcements from
347
- Twitter:
348
-
349
- * [Changes coming in Version 1.1 of the Twitter API][coming]
350
- * [Current status: API v1.1][status]
351
- * [Overview: Version 1.1 of the Twitter API][overview]
352
-
353
- [coming]: https://dev.twitter.com/blog/changes-coming-to-twitter-api
354
- [status]: https://dev.twitter.com/blog/current-status-api-v1.1
355
- [overview]: https://dev.twitter.com/docs/api/1.1/overview
356
-
357
- Despite the removal of certain underlying functionality in Twitter API v1.1,
358
- this library aims to preserve backward-compatibility wherever possible. For
359
- example, despite the removal of the [`GET
360
- statuses/retweeted_by_user`][retweeted_by_user] resource, the
361
- `Twitter::API#retweeted_by_user` method continues to exist, implemented by
362
- making multiple requests to the [`GET statuses/user_timeline`][user_timeline]
363
- resource. As a result, there is no longer a one-to-one correlation between
364
- method calls and Twitter API requests. In fact, it's possible for a single
365
- method call to exceed the Twitter API rate limit for a resource. If you think
366
- this might cause a problem for your application, feel free to [join the
367
- discussion][discussion].
368
-
369
- [retweeted_by_user]: https://dev.twitter.com/docs/api/1/get/statuses/retweeted_by_user
370
- [user_timeline]: https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline
371
- [discussion]: https://dev.twitter.com/discussions/10644
372
-
373
- #### Rate Limiting
374
- Another consequence of Twitter API v1.1 is that the
375
- `Twitter::Client#rate_limit` method has been removed, since the concept of a
376
- client-wide rate limit no longer exists. Rate limits are now applied on a
377
- per-resource level, however, since there is no longer a one-to-one mapping
378
- between methods and Twitter API resources, it's not entirely obvious how rate
379
- limit information should be exposed. I've decided to go back to the pre-3.0.0
380
- behavior of including rate limit information on `Twitter::Error` objects.
381
- Here's an example of how to handle rate limits:
382
-
383
- ```ruby
384
- MAX_ATTEMPTS = 3
385
- num_attempts = 0
386
- begin
387
- num_attempts += 1
388
- retweets = Twitter.retweeted_by_user("sferik")
389
- rescue Twitter::Error::TooManyRequests => error
390
- if num_attempts <= MAX_ATTEMPTS
391
- # NOTE: Your process could go to sleep for up to 15 minutes but if you
392
- # retry any sooner, it will almost certainly fail with the same exception.
393
- sleep error.rate_limit.reset_in
394
- retry
395
- else
396
- raise
397
- end
398
- end
399
- ```
400
- #### Methods Missing
401
- As a consequence of moving to Twitter API v1.1, the following methods from
402
- version 3 are no longer available in version 4:
403
-
404
- * `Twitter::API#accept`
405
- * `Twitter::API#deny`
406
- * `Twitter::API#disable_notifications`
407
- * `Twitter::API#enable_notifications`
408
- * `Twitter::API#end_session`
409
- * `Twitter::API#rate_limit_status`
410
- * `Twitter::API#rate_limited?`
411
- * `Twitter::API#recommendations`
412
- * `Twitter::API#related_results`
413
- * `Twitter::API#retweeted_to_user`
414
- * `Twitter::API#trends_daily`
415
- * `Twitter::API#trends_weekly`
416
- * `Twitter::Client#rate_limit`
417
- * `Twitter::RateLimit#class`
418
-
419
- #### Custom Endpoints
420
- The `Twitter::API#update_with_media` method no longer uses the custom
421
- `upload.twitter.com` endpoint, so `media_endpoint` configuration has been
422
- removed. Likewise, the `Twitter::API#search` method no longer uses the custom
423
- `search.twitter.com` endpoint, so `search_endpoint` configuration has also been
424
- removed.
425
-
426
- #### Errors
427
- It's worth mentioning new error classes:
428
-
429
- * `Twitter::Error::GatewayTimeout`
430
- * `Twitter::Error::TooManyRequests`
431
- * `Twitter::Error::UnprocessableEntity`
432
-
433
- In previous versions of this library, rate limit errors were indicated by
434
- raising either `Twitter::Error::BadRequest` or
435
- `Twitter::Error::EnhanceYourCalm` (for the Search API). As of version 4, the
436
- library will raise `Twitter::Error::TooManyRequests` for all rate limit errors.
437
- The `Twitter::Error::EnhanceYourCalm` class has been aliased to
438
- `Twitter::Error::TooManyRequests`.
439
-
440
- #### Identity Map
441
- In version 4, the identity map is [disabled by default][disabled]. If you want
442
- to enable this feature, you can use the [default identity map][default] or
443
- [write a custom identity map][custom].
444
-
445
- ```ruby
446
- Twitter.identity_map = Twitter::IdentityMap
447
- ```
448
-
449
- [disabled]: https://github.com/sferik/twitter/commit/c6c5960bea998abdc3e82cbb8dd68766a2df52e1
450
- [default]: lib/twitter/identity_map.rb
451
- [custom]: etc/sqlite_identity_map.rb
452
-
453
- ## Additional Notes
454
- This will be the last major version of this library to support Ruby 1.8.
455
- Requiring Ruby 1.9 will allow us to [remove][class_variable_get]
456
- [various][each_with_object] [hacks][singleton_class] put in place to maintain
457
- Ruby 1.8 compatibility. [The first stable version of Ruby 1.9 was released on
458
- August 19, 2010.][ruby192] If you haven't found the opportunity to upgrade your
459
- Ruby interpreter since then, let this be your nudge. Once version 5 of this
460
- library is released, all previous versions will cease to be supported, even if
461
- critical security vulnerabilities are discovered.
462
-
463
- [class_variable_get]: https://github.com/sferik/twitter/commit/88c5a0513d1b58a1d4ae1a1e3deeb012c9d19547
464
- [each_with_object]: https://github.com/sferik/twitter/commit/6052252a07baf7aefe0f100bba0abd2cbb7139bb
465
- [singleton_class]: https://github.com/sferik/twitter/commit/2ed9db21c87d1218b15373e42a36ad536b07dcbb
466
- [ruby192]: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/367983
467
-
468
588
  ## Copyright
469
- Copyright (c) 2006-2013 John Nunemaker, Wynn Netherland, Erik Michaels-Ober, Steve Richert.
589
+ Copyright (c) 2006-2013 Erik Michaels-Ober, John Nunemaker, Wynn Netherland, Steve Richert, Steve Agalloco.
470
590
  See [LICENSE][] for details.
471
591
 
472
592
  [license]: LICENSE.md