twitter 4.8.1 → 5.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
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