twitter 5.0.0.rc.1 → 5.0.0

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