twitter 5.0.0.rc.1 → 5.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 (102) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG.md +7 -1
  3. data/CONTRIBUTING.md +13 -15
  4. data/README.md +53 -33
  5. data/Rakefile +6 -0
  6. data/lib/twitter/arguments.rb +3 -0
  7. data/lib/twitter/base.rb +88 -89
  8. data/lib/twitter/client.rb +5 -41
  9. data/lib/twitter/configuration.rb +4 -5
  10. data/lib/twitter/core_ext/kernel.rb +5 -1
  11. data/lib/twitter/creatable.rb +6 -1
  12. data/lib/twitter/cursor.rb +16 -12
  13. data/lib/twitter/entity/uri.rb +2 -1
  14. data/lib/twitter/enumerable.rb +1 -1
  15. data/lib/twitter/error.rb +42 -39
  16. data/lib/twitter/factory.rb +12 -5
  17. data/lib/twitter/geo.rb +2 -7
  18. data/lib/twitter/geo_factory.rb +11 -7
  19. data/lib/twitter/geo_results.rb +12 -8
  20. data/lib/twitter/identity.rb +4 -12
  21. data/lib/twitter/list.rb +6 -3
  22. data/lib/twitter/media/photo.rb +5 -3
  23. data/lib/twitter/media_factory.rb +11 -7
  24. data/lib/twitter/null_object.rb +4 -3
  25. data/lib/twitter/place.rb +10 -16
  26. data/lib/twitter/profile_banner.rb +4 -5
  27. data/lib/twitter/rate_limit.rb +3 -0
  28. data/lib/twitter/relationship.rb +0 -9
  29. data/lib/twitter/rest/api/direct_messages.rb +9 -6
  30. data/lib/twitter/rest/api/favorites.rb +6 -11
  31. data/lib/twitter/rest/api/friends_and_followers.rb +6 -9
  32. data/lib/twitter/rest/api/lists.rb +27 -20
  33. data/lib/twitter/rest/api/oauth.rb +17 -0
  34. data/lib/twitter/rest/api/places_and_geo.rb +0 -18
  35. data/lib/twitter/rest/api/saved_searches.rb +6 -4
  36. data/lib/twitter/rest/api/suggested_users.rb +2 -2
  37. data/lib/twitter/rest/api/tweets.rb +7 -9
  38. data/lib/twitter/rest/api/users.rb +6 -6
  39. data/lib/twitter/rest/api/utils.rb +44 -17
  40. data/lib/twitter/rest/client.rb +25 -43
  41. data/lib/twitter/rest/response/parse_error_json.rb +15 -0
  42. data/lib/twitter/rest/response/parse_json.rb +5 -1
  43. data/lib/twitter/search_results.rb +12 -8
  44. data/lib/twitter/size.rb +2 -15
  45. data/lib/twitter/streaming/client.rb +23 -11
  46. data/lib/twitter/streaming/event.rb +35 -0
  47. data/lib/twitter/streaming/friend_list.rb +13 -0
  48. data/lib/twitter/streaming/message_parser.rb +18 -0
  49. data/lib/twitter/streaming/response.rb +4 -0
  50. data/lib/twitter/suggestion.rb +5 -10
  51. data/lib/twitter/token.rb +3 -1
  52. data/lib/twitter/trend.rb +2 -7
  53. data/lib/twitter/trend_results.rb +20 -14
  54. data/lib/twitter/tweet.rb +18 -23
  55. data/lib/twitter/user.rb +34 -19
  56. data/lib/twitter/version.rb +1 -1
  57. data/spec/fixtures/request_token.txt +6 -0
  58. data/spec/fixtures/track_streaming_user.json +5 -0
  59. data/spec/twitter/base_spec.rb +0 -16
  60. data/spec/twitter/basic_user_spec.rb +3 -3
  61. data/spec/twitter/cursor_spec.rb +4 -4
  62. data/spec/twitter/direct_message_spec.rb +9 -9
  63. data/spec/twitter/entity/uri_spec.rb +12 -11
  64. data/spec/twitter/geo/point_spec.rb +5 -5
  65. data/spec/twitter/geo/polygon_spec.rb +5 -5
  66. data/spec/twitter/geo_factory_spec.rb +2 -2
  67. data/spec/twitter/geo_spec.rb +6 -6
  68. data/spec/twitter/identifiable_spec.rb +5 -5
  69. data/spec/twitter/list_spec.rb +7 -7
  70. data/spec/twitter/media/photo_spec.rb +19 -18
  71. data/spec/twitter/media_factory_spec.rb +2 -2
  72. data/spec/twitter/null_object_spec.rb +7 -6
  73. data/spec/twitter/oembed_spec.rb +6 -6
  74. data/spec/twitter/place_spec.rb +37 -37
  75. data/spec/twitter/rate_limit_spec.rb +0 -17
  76. data/spec/twitter/relationship_spec.rb +4 -12
  77. data/spec/twitter/rest/api/direct_messages_spec.rb +8 -8
  78. data/spec/twitter/rest/api/friends_and_followers_spec.rb +50 -120
  79. data/spec/twitter/rest/api/geo_spec.rb +0 -14
  80. data/spec/twitter/rest/api/lists_spec.rb +39 -39
  81. data/spec/twitter/rest/api/oauth_spec.rb +15 -4
  82. data/spec/twitter/rest/api/saved_searches_spec.rb +6 -6
  83. data/spec/twitter/rest/api/tweets_spec.rb +6 -6
  84. data/spec/twitter/rest/api/users_spec.rb +4 -4
  85. data/spec/twitter/rest/client_spec.rb +9 -9
  86. data/spec/twitter/saved_search_spec.rb +5 -5
  87. data/spec/twitter/search_results_spec.rb +3 -3
  88. data/spec/twitter/settings_spec.rb +2 -2
  89. data/spec/twitter/size_spec.rb +5 -15
  90. data/spec/twitter/source_user_spec.rb +3 -3
  91. data/spec/twitter/streaming/client_spec.rb +33 -16
  92. data/spec/twitter/streaming/event_spec.rb +45 -0
  93. data/spec/twitter/suggestion_spec.rb +5 -15
  94. data/spec/twitter/target_user_spec.rb +3 -3
  95. data/spec/twitter/token_spec.rb +2 -2
  96. data/spec/twitter/trend_results_spec.rb +6 -6
  97. data/spec/twitter/trend_spec.rb +7 -17
  98. data/spec/twitter/tweet_spec.rb +31 -25
  99. data/spec/twitter/user_spec.rb +16 -16
  100. data/twitter.gemspec +5 -2
  101. metadata +67 -15
  102. metadata.gz.sig +0 -0
@@ -1,24 +1,11 @@
1
+ require 'equalizer'
1
2
  require 'twitter/base'
2
3
 
3
4
  module Twitter
4
5
  class Size < Twitter::Base
6
+ include Equalizer.new(:h, :w)
5
7
  attr_reader :h, :resize, :w
6
8
  alias height h
7
9
  alias width w
8
-
9
- # @param other [Twitter::Size]
10
- # @return [Boolean]
11
- def ==(other)
12
- super || size_equal(other) || attrs_equal(other)
13
- end
14
-
15
- private
16
-
17
- # @param other [Twitter::Size]
18
- # @return [Boolean]
19
- def size_equal(other)
20
- self.class == other.class && !other.h.nil? && h == other.h && !other.w.nil? && w == other.w
21
- end
22
-
23
10
  end
24
11
  end
@@ -3,45 +3,56 @@ require 'twitter/arguments'
3
3
  require 'twitter/client'
4
4
  require 'twitter/streaming/connection'
5
5
  require 'twitter/streaming/response'
6
+ require 'twitter/streaming/message_parser'
7
+ require 'twitter/streaming/event'
8
+ require 'twitter/streaming/friend_list'
6
9
 
7
10
  module Twitter
8
11
  module Streaming
9
12
  class Client < Twitter::Client
10
13
  attr_writer :connection
11
14
 
15
+ # Initializes a new Client object
16
+ #
17
+ # @return [Twitter::Streaming::Client]
12
18
  def initialize(options={}, &block)
13
19
  super
14
- @connection = Twitter::Streaming::Connection.new
20
+ @connection = Streaming::Connection.new
15
21
  end
16
22
 
23
+ # @yield [Twitter::Tweet] A stream of tweets.
17
24
  def filter(options={}, &block)
18
- request(:get, 'https://stream.twitter.com:443/1.1/statuses/filter.json', options, &block)
25
+ request(:post, 'https://stream.twitter.com:443/1.1/statuses/filter.json', options, &block)
19
26
  end
20
27
 
28
+ # @yield [Twitter::Tweet] A stream of tweets.
21
29
  def firehose(options={}, &block)
22
30
  request(:get, 'https://stream.twitter.com:443/1.1/statuses/firehose.json', options, &block)
23
31
  end
24
32
 
33
+ # @yield [Twitter::Tweet] A stream of tweets.
25
34
  def sample(options={}, &block)
26
35
  request(:get, 'https://stream.twitter.com:443/1.1/statuses/sample.json', options, &block)
27
36
  end
28
37
 
38
+ # @yield [Twitter::Tweet] A stream of tweets.
29
39
  def site(*args, &block)
30
- arguments = Twitter::Arguments.new(args)
40
+ arguments = Arguments.new(args)
31
41
  request(:get, 'https://sitestream.twitter.com:443/1.1/site.json', arguments.options.merge(:follow => arguments.join(',')), &block)
32
42
  end
33
43
 
44
+ # @yield [Twitter::Tweet] A stream of tweets.
34
45
  def user(options={}, &block)
35
46
  request(:get, 'https://userstream.twitter.com:443/1.1/user.json', options, &block)
36
47
  end
37
48
 
38
49
  # Set a Proc to be run when connection established.
39
- def on_request(&block)
50
+ def before_request(&block)
40
51
  if block_given?
41
- @on_request = block
52
+ @before_request = block
42
53
  self
43
- elsif instance_variable_defined?(:@on_request)
44
- @on_request
54
+ elsif instance_variable_defined?(:@before_request)
55
+ @before_request
45
56
  else
46
57
  Proc.new {}
47
58
  end
@@ -50,11 +61,13 @@ module Twitter
50
61
  private
51
62
 
52
63
  def request(method, uri, params, &block)
53
- on_request.call
64
+ before_request.call
54
65
  headers = default_headers.merge(:authorization => oauth_auth_header(method, uri, params).to_s)
55
66
  request = HTTP::Request.new(method, uri + '?' + to_url_params(params), headers)
56
- response = Twitter::Streaming::Response.new do |data|
57
- yield(Tweet.new(data)) if data[:id]
67
+ response = Streaming::Response.new do |data|
68
+ if item = Streaming::MessageParser.parse(data)
69
+ yield item
70
+ end
58
71
  end
59
72
  @connection.stream(request, response)
60
73
  end
@@ -71,7 +84,6 @@ module Twitter
71
84
  :user_agent => user_agent,
72
85
  }
73
86
  end
74
-
75
87
  end
76
88
  end
77
89
  end
@@ -0,0 +1,35 @@
1
+ module Twitter
2
+ module Streaming
3
+ class Event
4
+
5
+ LIST_EVENTS = [
6
+ :list_created, :list_destroyed, :list_updated, :list_member_added,
7
+ :list_member_added, :list_member_removed, :list_user_subscribed,
8
+ :list_user_subscribed, :list_user_unsubscribed, :list_user_unsubscribed
9
+ ]
10
+
11
+ TWEET_EVENTS = [
12
+ :favorite, :unfavorite
13
+ ]
14
+
15
+ attr_reader :name, :source, :target, :target_object
16
+
17
+ # @param data [Hash]
18
+ def initialize(data)
19
+ @name = data[:event].intern
20
+ @source = Twitter::User.new(data[:source])
21
+ @target = Twitter::User.new(data[:target])
22
+ @target_object = target_object_factory(@name, data[:target_object])
23
+ end
24
+
25
+ private
26
+ def target_object_factory(event_name, data)
27
+ if LIST_EVENTS.include?(event_name)
28
+ Twitter::List.new(data)
29
+ elsif TWEET_EVENTS.include?(event_name)
30
+ Twitter::Tweet.new(data)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,13 @@
1
+ module Twitter
2
+ module Streaming
3
+ class FriendList
4
+
5
+ attr_reader :friend_ids
6
+
7
+ # @param friend_ids [Array]
8
+ def initialize(friend_ids)
9
+ @friend_ids = friend_ids
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,18 @@
1
+ module Twitter
2
+ module Streaming
3
+ class MessageParser
4
+
5
+ def self.parse(data)
6
+ if data[:id]
7
+ Tweet.new(data)
8
+ elsif data[:event]
9
+ Event.new(data)
10
+ elsif data[:direct_message]
11
+ DirectMessage.new(data[:direct_message])
12
+ elsif data[:friends]
13
+ FriendList.new(data[:friends])
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -3,6 +3,10 @@ require 'buftok'
3
3
  module Twitter
4
4
  module Streaming
5
5
  class Response
6
+
7
+ # Initializes a new Response object
8
+ #
9
+ # @return [Twitter::Streaming::Response]
6
10
  def initialize(&block)
7
11
  @block = block
8
12
  @parser = Http::Parser.new(self)
@@ -1,23 +1,18 @@
1
+ require 'equalizer'
1
2
  require 'twitter/base'
2
3
 
3
4
  module Twitter
4
5
  class Suggestion < Twitter::Base
6
+ include Equalizer.new(:slug)
5
7
  attr_reader :name, :size, :slug
6
8
 
7
- # @param other [Twitter::Suggestion]
8
- # @return [Boolean]
9
- def ==(other)
10
- super || attr_equal(:slug, other) || attrs_equal(other)
11
- end
12
-
13
9
  # @return [Array<Twitter::User>]
14
10
  def users
15
- memoize(:users) do
16
- Array(@attrs[:users]).map do |user|
17
- Twitter::User.new(user)
18
- end
11
+ Array(@attrs[:users]).map do |user|
12
+ User.new(user)
19
13
  end
20
14
  end
15
+ memoize :users
21
16
 
22
17
  end
23
18
  end
@@ -2,7 +2,8 @@ require 'twitter/base'
2
2
 
3
3
  module Twitter
4
4
  class Token < Twitter::Base
5
- attr_reader :token_type, :access_token
5
+ attr_reader :access_token, :token_type
6
+ alias to_s access_token
6
7
 
7
8
  BEARER_TYPE = "bearer"
8
9
 
@@ -10,6 +11,7 @@ module Twitter
10
11
  def bearer?
11
12
  @attrs[:token_type] == BEARER_TYPE
12
13
  end
14
+ memoize :bearer?
13
15
 
14
16
  end
15
17
  end
@@ -1,15 +1,10 @@
1
+ require 'equalizer'
1
2
  require 'twitter/base'
2
3
 
3
4
  module Twitter
4
5
  class Trend < Twitter::Base
6
+ include Equalizer.new(:name)
5
7
  attr_reader :events, :name, :promoted_content, :query
6
8
  uri_attr_reader :uri
7
-
8
- # @param other [Twitter::Trend]
9
- # @return [Boolean]
10
- def ==(other)
11
- super || attr_equal(:name, other) || attrs_equal(other)
12
- end
13
-
14
9
  end
15
10
  end
@@ -1,32 +1,38 @@
1
1
  require 'twitter/creatable'
2
2
  require 'twitter/enumerable'
3
+ require 'memoizable'
3
4
  require 'twitter/null_object'
4
5
 
5
6
  module Twitter
6
7
  class TrendResults
7
8
  include Twitter::Creatable
8
9
  include Twitter::Enumerable
10
+ include Memoizable
9
11
  attr_reader :attrs
10
12
  alias to_h attrs
11
13
  alias to_hash attrs
12
14
  alias to_hsh attrs
13
15
 
14
- # Construct a new SearchResults object from a response hash
15
- #
16
- # @param response [Hash]
17
- # @return [Twitter::Base]
18
- def self.from_response(response={})
19
- new(response[:body].first)
16
+ class << self
17
+
18
+ # Construct a new TrendResults object from a response hash
19
+ #
20
+ # @param response [Hash]
21
+ # @return [Twitter::Base]
22
+ def from_response(response={})
23
+ new(response[:body].first)
24
+ end
25
+
20
26
  end
21
27
 
22
- # Initializes a new SearchResults object
28
+ # Initializes a new TrendResults object
23
29
  #
24
30
  # @param attrs [Hash]
25
31
  # @return [Twitter::TrendResults]
26
32
  def initialize(attrs={})
27
33
  @attrs = attrs
28
34
  @collection = Array(@attrs[:trends]).map do |trend|
29
- Twitter::Trend.new(trend)
35
+ Trend.new(trend)
30
36
  end
31
37
  end
32
38
 
@@ -34,26 +40,26 @@ module Twitter
34
40
  #
35
41
  # @return [Time]
36
42
  def as_of
37
- @as_of ||= Time.parse(@attrs[:as_of]) if @attrs[:as_of]
43
+ Time.parse(@attrs[:as_of]) if @attrs[:as_of]
38
44
  end
45
+ memoize :as_of
39
46
 
40
47
  def as_of?
41
48
  !!@attrs[:as_of]
42
49
  end
50
+ memoize :as_of?
43
51
 
44
52
  # @return [Twitter::Place, NullObject]
45
53
  def location
46
- @location ||= if location?
47
- Twitter::Place.new(@attrs[:locations].first)
48
- else
49
- Twitter::NullObject.instance
50
- end
54
+ location? ? Place.new(@attrs[:locations].first) : NullObject.new
51
55
  end
56
+ memoize :location
52
57
 
53
58
  # @return [Boolean]
54
59
  def location?
55
60
  !@attrs[:locations].nil? && !@attrs[:locations].first.nil?
56
61
  end
62
+ memoize :location?
57
63
 
58
64
  end
59
65
  end
@@ -7,12 +7,7 @@ module Twitter
7
7
  :in_reply_to_attrs_id, :in_reply_to_status_id, :in_reply_to_user_id,
8
8
  :lang, :retweet_count, :retweeted, :source, :text, :truncated
9
9
  alias favorites_count favorite_count
10
- alias favourite_count favorite_count
11
- alias favourites_count favorite_count
12
10
  alias favoriters_count favorite_count
13
- alias favouriters_count favorite_count
14
- alias favourited favorited
15
- alias favourited? favorited?
16
11
  alias in_reply_to_tweet_id in_reply_to_status_id
17
12
  alias retweeters_count retweet_count
18
13
  object_attr_reader :GeoFactory, :geo
@@ -27,12 +22,14 @@ module Twitter
27
22
 
28
23
  # @return [Boolean]
29
24
  def entities?
30
- !@attrs[:entities].nil?
25
+ !@attrs[:entities].nil? && @attrs[:entities].any?{|_, array| !array.empty?}
31
26
  end
27
+ memoize :entities?
32
28
 
33
29
  def filter_level
34
30
  @attrs[:filter_level] || "none"
35
31
  end
32
+ memoize :filter_level
36
33
 
37
34
  # @return [String]
38
35
  # @note May be > 140 characters.
@@ -44,58 +41,56 @@ module Twitter
44
41
  text
45
42
  end
46
43
  end
44
+ memoize :full_text
47
45
 
48
46
  # @note Must include entities in your request for this method to work
49
47
  # @return [Array<Twitter::Entity::Hashtag>]
50
48
  def hashtags
51
- memoize(:hashtags) do
52
- entities(Twitter::Entity::Hashtag, :hashtags)
53
- end
49
+ entities(Entity::Hashtag, :hashtags)
54
50
  end
51
+ memoize :hashtags
55
52
 
56
53
  # @note Must include entities in your request for this method to work
57
54
  # @return [Array<Twitter::Media>]
58
55
  def media
59
- memoize(:media) do
60
- entities(Twitter::MediaFactory, :media)
61
- end
56
+ entities(MediaFactory, :media)
62
57
  end
58
+ memoize :media
63
59
 
64
60
  # @return [Boolean]
65
61
  def reply?
66
62
  !!@attrs[:in_reply_to_status_id]
67
63
  end
64
+ memoize :reply?
68
65
 
69
66
  # @note Must include entities in your request for this method to work
70
67
  # @return [Array<Twitter::Entity::Symbol>]
71
68
  def symbols
72
- memoize(:symbols) do
73
- entities(Twitter::Entity::Symbol, :symbols)
74
- end
69
+ entities(Entity::Symbol, :symbols)
75
70
  end
71
+ memoize :symbols
76
72
 
77
73
  # @return [String] The URL to the tweet.
78
74
  def uri
79
- @uri ||= ::URI.parse("https://twitter.com/#{user.screen_name}/status/#{id}")
75
+ URI.parse("https://twitter.com/#{user.screen_name}/status/#{id}")
80
76
  end
77
+ memoize :uri
81
78
  alias url uri
82
79
 
83
80
  # @note Must include entities in your request for this method to work
84
81
  # @return [Array<Twitter::Entity::URI>]
85
82
  def uris
86
- memoize(:uris) do
87
- entities(Twitter::Entity::URI, :urls)
88
- end
83
+ entities(Entity::URI, :urls)
89
84
  end
85
+ memoize :uris
90
86
  alias urls uris
91
87
 
92
88
  # @note Must include entities in your request for this method to work
93
89
  # @return [Array<Twitter::Entity::UserMention>]
94
90
  def user_mentions
95
- memoize(:user_mentions) do
96
- entities(Twitter::Entity::UserMention, :user_mentions)
97
- end
91
+ entities(Entity::UserMention, :user_mentions)
98
92
  end
93
+ memoize :user_mentions
99
94
 
100
95
  private
101
96
 
@@ -107,7 +102,7 @@ module Twitter
107
102
  klass.new(entity)
108
103
  end
109
104
  else
110
- warn "#{Kernel.caller.first}: To get #{key.to_s.tr('_', ' ')}, you must pass `:include_entities => true` when requesting the #{self.class.name}."
105
+ warn "#{Kernel.caller.first}: To get #{key.to_s.tr('_', ' ')}, you must pass `:include_entities => true` when requesting the #{self.class}."
111
106
  []
112
107
  end
113
108
  end