twitter 5.4.1 → 5.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: baa0ce3302ef65ee7f6c6472b847ce5c71ce005a
4
+ data.tar.gz: 8933bed1f45fd295836a0cd4b75873f41aee8189
5
+ SHA512:
6
+ metadata.gz: b3a5cb3b3259de32cd96dd7e913b816b3c063230d64c375e53cb9e9b84cdd22856c75b575b98c2fd3d99dc22d438a634a3f38739b0992703a9d11750e84ee713
7
+ data.tar.gz: cbf5b4fb759e16ae6c6146a2081e479533ea11a640270b153d86d25478e688e5b910410c06c19711436acf7151b340275777d077609776afe6902b33b43bdb98
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -1,3 +1,8 @@
1
+ 5.5.0
2
+ -----
3
+ * [Add entities to `Twitter::DirectMessage`](https://github.com/sferik/twitter/commit/d911deb456cb2da6e14d0b3c69ba4d068ca85868)
4
+ * [Add conversion methods to `Twitter::NullObject`](https://github.com/sferik/twitter/commit/4900fee474feaa1514c06d459a9da6d52c45a60e)
5
+
1
6
  5.4.1
2
7
  -----
3
8
  * [Default to maximum number of tweets per request](https://github.com/sferik/twitter/commit/1e41b5d4dde8678f5968b57dafe9da63b092646c)
@@ -35,16 +35,14 @@ Ideally, a bug report should include a pull request with failing specs.
35
35
  3. Add specs for your unimplemented feature or bug fix.
36
36
  4. Run `bundle exec rake spec`. If your specs pass, return to step 3.
37
37
  5. Implement your feature or bug fix.
38
- 6. Run `bundle exec rake default`. If your specs fail, return to step 5.
38
+ 6. Run `bundle exec rake`. If your specs fail, return to step 5.
39
39
  7. Run `open coverage/index.html`. If your changes are not completely covered
40
40
  by your tests, return to step 3.
41
- 8. Run `RUBYOPT=W2 bundle exec rake spec 2>&1 | grep twitter`. If your changes
42
- produce any warnings, return to step 5.
43
- 9. Add documentation for your feature or bug fix.
44
- 10. Run `bundle exec rake verify_measurements`. If your changes are not 100% documented, go
45
- back to step 9.
46
- 11. Commit and push your changes.
47
- 12. [Submit a pull request.][pr]
41
+ 8. Add documentation for your feature or bug fix.
42
+ 9. Run `bundle exec rake verify_measurements`. If your changes are not 100%
43
+ documented, go back to step 8.
44
+ 10. Commit and push your changes.
45
+ 11. [Submit a pull request.][pr]
48
46
 
49
47
  [fork]: http://help.github.com/fork-a-repo/
50
48
  [branch]: http://learn.github.com/p/branching.html
data/README.md CHANGED
@@ -82,6 +82,13 @@ does not work on Ruby 2.0.0][bug].
82
82
  [tweetstream]: http://rubygems.org/gems/tweetstream
83
83
  [bug]: https://github.com/tweetstream/tweetstream/issues/117
84
84
 
85
+ Site Streams are restricted to whitelisted accounts. To apply for access,
86
+ [follow the steps in the Site Streams documentation][site-streams]. [User
87
+ Streams][user-streams] do not require prior approval.
88
+
89
+ [site-streams]: https://dev.twitter.com/docs/streaming-apis/streams/site#Applying_for_access
90
+ [user-streams]: https://dev.twitter.com/docs/streaming-apis/streams/user
91
+
85
92
  Unlike the rest of this library, this feature is not well tested and not
86
93
  recommended for production applications. That said, if you need to do Twitter
87
94
  streaming on Ruby 2.0.0, this is probably your best option. I've decided to
@@ -577,6 +584,7 @@ versions:
577
584
  * Ruby 1.9.2
578
585
  * Ruby 1.9.3
579
586
  * Ruby 2.0.0
587
+ * Ruby 2.1.0
580
588
 
581
589
  If something doesn't work on one of these versions, it's a bug.
582
590
 
data/Rakefile CHANGED
@@ -16,7 +16,6 @@ begin
16
16
  require 'rubocop/rake_task'
17
17
  Rubocop::RakeTask.new
18
18
  rescue LoadError
19
- desc 'Run RuboCop'
20
19
  task :rubocop do
21
20
  $stderr.puts 'Rubocop is disabled'
22
21
  end
@@ -32,7 +31,7 @@ end
32
31
 
33
32
  require 'yardstick/rake/verify'
34
33
  Yardstick::Rake::Verify.new do |verify|
35
- verify.threshold = 59.9
34
+ verify.threshold = 59.8
36
35
  end
37
36
 
38
37
  task :default => [:spec, :rubocop, :verify_measurements]
@@ -73,7 +73,7 @@ module Twitter
73
73
  # @param key2 [Symbol]
74
74
  def define_uri_method(key1, key2)
75
75
  define_method(key1) do ||
76
- Addressable::URI.parse(@attrs[key2]) if @attrs[key2]
76
+ Addressable::URI.parse(@attrs[key2]) unless @attrs[key2].nil?
77
77
  end
78
78
  memoize(key1)
79
79
  end
@@ -88,11 +88,11 @@ module Twitter
88
88
  if klass.nil?
89
89
  @attrs[key1]
90
90
  else
91
- if @attrs[key1]
91
+ if @attrs[key1].nil?
92
+ NullObject.new
93
+ else
92
94
  attrs = attrs_for_object(key1, key2)
93
95
  Twitter.const_get(klass).new(attrs)
94
- else
95
- NullObject.new
96
96
  end
97
97
  end
98
98
  end
@@ -9,7 +9,7 @@ module Twitter
9
9
  #
10
10
  # @return [Time]
11
11
  def created_at
12
- Time.parse(@attrs[:created_at]) if @attrs[:created_at]
12
+ Time.parse(@attrs[:created_at]) unless @attrs[:created_at].nil?
13
13
  end
14
14
  memoize :created_at
15
15
 
@@ -42,7 +42,7 @@ module Twitter
42
42
  @path = path
43
43
  @options = options
44
44
  @collection = []
45
- set_attrs(attrs)
45
+ self.attrs = attrs
46
46
  end
47
47
 
48
48
  private
@@ -59,10 +59,10 @@ module Twitter
59
59
 
60
60
  def fetch_next_page
61
61
  response = @client.send(@request_method, @path, @options.merge(:cursor => next_cursor))
62
- set_attrs(response[:body])
62
+ self.attrs = response[:body]
63
63
  end
64
64
 
65
- def set_attrs(attrs)
65
+ def attrs=(attrs)
66
66
  @attrs = attrs
67
67
  Array(attrs[@key]).each do |element|
68
68
  @collection << (@klass ? @klass.new(element) : element)
@@ -1,9 +1,11 @@
1
1
  require 'twitter/creatable'
2
+ require 'twitter/entities'
2
3
  require 'twitter/identity'
3
4
 
4
5
  module Twitter
5
6
  class DirectMessage < Twitter::Identity
6
7
  include Twitter::Creatable
8
+ include Twitter::Entities
7
9
  attr_reader :text
8
10
  alias_method :full_text, :text
9
11
  object_attr_reader :User, :recipient
@@ -0,0 +1,69 @@
1
+ require 'memoizable'
2
+ require 'twitter/entity/hashtag'
3
+ require 'twitter/entity/symbol'
4
+ require 'twitter/entity/uri'
5
+ require 'twitter/entity/user_mention'
6
+ require 'twitter/media_factory'
7
+
8
+ module Twitter
9
+ module Entities
10
+ include Memoizable
11
+
12
+ # @note Must include entities in your request for this method to work
13
+ # @return [Array<Twitter::Entity::Hashtag>]
14
+ def hashtags
15
+ entities(Entity::Hashtag, :hashtags)
16
+ end
17
+ memoize :hashtags
18
+
19
+ # @note Must include entities in your request for this method to work
20
+ # @return [Array<Twitter::Media>]
21
+ def media
22
+ entities(MediaFactory, :media)
23
+ end
24
+ memoize :media
25
+
26
+ # @note Must include entities in your request for this method to work
27
+ # @return [Array<Twitter::Entity::Symbol>]
28
+ def symbols
29
+ entities(Entity::Symbol, :symbols)
30
+ end
31
+ memoize :symbols
32
+
33
+ # @note Must include entities in your request for this method to work
34
+ # @return [Array<Twitter::Entity::URI>]
35
+ def uris
36
+ entities(Entity::URI, :urls)
37
+ end
38
+ memoize :uris
39
+ alias_method :urls, :uris
40
+
41
+ # @note Must include entities in your request for this method to work
42
+ # @return [Array<Twitter::Entity::UserMention>]
43
+ def user_mentions
44
+ entities(Entity::UserMention, :user_mentions)
45
+ end
46
+ memoize :user_mentions
47
+
48
+ private
49
+
50
+ # @return [Boolean]
51
+ def entities?
52
+ !@attrs[:entities].nil? && @attrs[:entities].any? { |_, array| !array.empty? }
53
+ end
54
+ memoize :entities?
55
+
56
+ # @param klass [Class]
57
+ # @param key [Symbol]
58
+ def entities(klass, key)
59
+ if entities?
60
+ Array(@attrs[:entities][key.to_sym]).map do |entity|
61
+ klass.new(entity)
62
+ end
63
+ else
64
+ warn "#{Kernel.caller.first}: To get #{key.to_s.tr('_', ' ')}, you must pass `:include_entities => true` when requesting the #{self.class}."
65
+ []
66
+ end
67
+ end
68
+ end
69
+ end
@@ -16,6 +16,8 @@ module Twitter
16
16
  self
17
17
  end
18
18
 
19
+ private
20
+
19
21
  # @return [Boolean]
20
22
  def last?
21
23
  true
@@ -5,7 +5,8 @@ module Twitter
5
5
  # Custom error class for rescuing from all Twitter errors
6
6
  class Error < StandardError
7
7
  extend DescendantsTracker
8
- attr_reader :rate_limit, :wrapped_exception, :code
8
+ attr_reader :cause, :code, :rate_limit
9
+ alias_method :wrapped_exception, :cause
9
10
 
10
11
  # If error code is missing see https://dev.twitter.com/docs/error-codes-responses
11
12
  module Codes
@@ -75,9 +76,9 @@ module Twitter
75
76
  # @param response_headers [Hash]
76
77
  # @param code [Integer]
77
78
  # @return [Twitter::Error]
78
- def initialize(exception = $ERROR_INFO, response_headers = {}, code = nil) # rubocop:disable MethodLength
79
+ def initialize(exception = $ERROR_INFO, response_headers = {}, code = nil)
79
80
  @rate_limit = RateLimit.new(response_headers)
80
- @wrapped_exception = exception
81
+ @cause = exception
81
82
  @code = code
82
83
  exception.respond_to?(:message) ? super(exception.message) : super(exception.to_s)
83
84
  end
@@ -1,9 +1,12 @@
1
+ require 'forwardable'
2
+
1
3
  module Twitter
2
4
  class NullObject
3
- # @return [TrueClass] This method always returns true.
4
- def nil?
5
- true
6
- end
5
+ extend Forwardable
6
+ def_instance_delegators :nil, :nil?, :to_a, :to_c, :to_c, :to_f, :to_h,
7
+ :to_i, :to_r, :to_s
8
+ alias_method :to_ary, :to_a
9
+ alias_method :to_str, :to_s
7
10
 
8
11
  # @return [Twitter::NullObject] This method always returns self.
9
12
  def method_missing(*args, &block)
@@ -0,0 +1,94 @@
1
+ require 'addressable/uri'
2
+ require 'memoizable'
3
+
4
+ module Twitter
5
+ module Profile
6
+ PROFILE_IMAGE_SUFFIX_REGEX = /_normal(\.gif|\.jpe?g|\.png)$/i
7
+ PREDICATE_URI_METHOD_REGEX = /_uri\?$/
8
+ include Memoizable
9
+
10
+ class << self
11
+ private
12
+
13
+ def alias_predicate_uri_methods(method)
14
+ %w(_url? _uri_https? _url_https?).each do |replacement|
15
+ alias_method_sub(method, PREDICATE_URI_METHOD_REGEX, replacement)
16
+ end
17
+ end
18
+
19
+ def alias_method_sub(method, pattern, replacement)
20
+ alias_method(method.to_s.sub(pattern, replacement).to_sym, method)
21
+ end
22
+ end
23
+
24
+ # Return the URL to the user's profile banner image
25
+ #
26
+ # @param size [String, Symbol] The size of the image. Must be one of: 'mobile', 'mobile_retina', 'web', 'web_retina', 'ipad', or 'ipad_retina'
27
+ # @return [String]
28
+ def profile_banner_uri(size = :web)
29
+ parse_encoded_uri(insecure_uri([@attrs[:profile_banner_url], size].join('/'))) unless @attrs[:profile_banner_url].nil?
30
+ end
31
+ alias_method :profile_banner_url, :profile_banner_uri
32
+
33
+ # Return the secure URL to the user's profile banner image
34
+ #
35
+ # @param size [String, Symbol] The size of the image. Must be one of: 'mobile', 'mobile_retina', 'web', 'web_retina', 'ipad', or 'ipad_retina'
36
+ # @return [String]
37
+ def profile_banner_uri_https(size = :web)
38
+ parse_encoded_uri([@attrs[:profile_banner_url], size].join('/')) unless @attrs[:profile_banner_url].nil?
39
+ end
40
+ alias_method :profile_banner_url_https, :profile_banner_uri_https
41
+
42
+ # @return [Boolean]
43
+ def profile_banner_uri?
44
+ !!@attrs[:profile_banner_url]
45
+ end
46
+ memoize :profile_banner_uri?
47
+ alias_predicate_uri_methods :profile_banner_uri?
48
+
49
+ # Return the URL to the user's profile image
50
+ #
51
+ # @param size [String, Symbol] The size of the image. Must be one of: 'mini', 'normal', 'bigger' or 'original'
52
+ # @return [String]
53
+ def profile_image_uri(size = :normal)
54
+ parse_encoded_uri(insecure_uri(profile_image_uri_https(size))) unless @attrs[:profile_image_url_https].nil?
55
+ end
56
+ alias_method :profile_image_url, :profile_image_uri
57
+
58
+ # Return the secure URL to the user's profile image
59
+ #
60
+ # @param size [String, Symbol] The size of the image. Must be one of: 'mini', 'normal', 'bigger' or 'original'
61
+ # @return [String]
62
+ def profile_image_uri_https(size = :normal)
63
+ # The profile image URL comes in looking like like this:
64
+ # https://a0.twimg.com/profile_images/1759857427/image1326743606_normal.png
65
+ # It can be converted to any of the following sizes:
66
+ # https://a0.twimg.com/profile_images/1759857427/image1326743606.png
67
+ # https://a0.twimg.com/profile_images/1759857427/image1326743606_mini.png
68
+ # https://a0.twimg.com/profile_images/1759857427/image1326743606_bigger.png
69
+ parse_encoded_uri(@attrs[:profile_image_url_https].sub(PROFILE_IMAGE_SUFFIX_REGEX, profile_image_suffix(size))) unless @attrs[:profile_image_url_https].nil?
70
+ end
71
+ alias_method :profile_image_url_https, :profile_image_uri_https
72
+
73
+ # @return [Boolean]
74
+ def profile_image_uri?
75
+ !!@attrs[:profile_image_url_https]
76
+ end
77
+ memoize :profile_image_uri?
78
+ alias_predicate_uri_methods :profile_image_uri?
79
+
80
+ private
81
+
82
+ def parse_encoded_uri(uri)
83
+ Addressable::URI.parse(URI.encode(uri))
84
+ end
85
+
86
+ def insecure_uri(uri)
87
+ uri.to_s.sub(/^https/i, 'http')
88
+ end
89
+
90
+ def profile_image_suffix(size)
91
+ :original == size.to_sym ? '\\1' : "_#{size}\\1"
92
+ end
93
+ end
94
+ end
@@ -109,7 +109,7 @@ module Twitter
109
109
  # @param ids [Enumerable<Integer>] A collection of direct message IDs.
110
110
  # @param options [Hash] A customizable set of options.
111
111
  def destroy_direct_message(*args)
112
- threaded_objects_from_response(Twitter::DirectMessage, :post, '/1.1/direct_messages/destroy.json', args)
112
+ parallel_objects_from_response(Twitter::DirectMessage, :post, '/1.1/direct_messages/destroy.json', args)
113
113
  end
114
114
  deprecate_alias :direct_message_destroy, :destroy_direct_message
115
115
 
@@ -49,7 +49,7 @@ module Twitter
49
49
  # @param tweets [Enumerable<Integer, String, URI, Twitter::Tweet>] A collection of Tweet IDs, URIs, or objects.
50
50
  # @param options [Hash] A customizable set of options.
51
51
  def unfavorite(*args)
52
- threaded_objects_from_response(Twitter::Tweet, :post, '/1.1/favorites/destroy.json', args)
52
+ parallel_objects_from_response(Twitter::Tweet, :post, '/1.1/favorites/destroy.json', args)
53
53
  end
54
54
  alias_method :destroy_favorite, :unfavorite
55
55
  deprecate_alias :favorite_destroy, :unfavorite
@@ -157,7 +157,7 @@ module Twitter
157
157
  # @param users [Enumerable<Integer, String, Twitter::User>] A collection of Twitter user IDs, screen names, or objects.
158
158
  # @param options [Hash] A customizable set of options.
159
159
  def unfollow(*args)
160
- threaded_user_objects_from_response(:post, '/1.1/friendships/destroy.json', args)
160
+ parallel_user_objects_from_response(:post, '/1.1/friendships/destroy.json', args)
161
161
  end
162
162
  alias_method :destroy_friendship, :unfollow
163
163
  deprecate_alias :friendship_destroy, :unfollow
@@ -20,7 +20,7 @@ module Twitter
20
20
  # @param users [Enumerable<Integer, String, Twitter::User>] A collection of Twitter user IDs, screen names, or objects.
21
21
  # @param options [Hash] A customizable set of options.
22
22
  def report_spam(*args)
23
- threaded_user_objects_from_response(:post, '/1.1/users/report_spam.json', args)
23
+ parallel_user_objects_from_response(:post, '/1.1/users/report_spam.json', args)
24
24
  end
25
25
  end
26
26
  end
@@ -77,7 +77,7 @@ module Twitter
77
77
  # @param options [Hash] A customizable set of options.
78
78
  # @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
79
79
  def statuses(*args)
80
- threaded_tweets_from_response(:get, '/1.1/statuses/show', args)
80
+ parallel_tweets_from_response(:get, '/1.1/statuses/show', args)
81
81
  end
82
82
 
83
83
  # Destroys the specified Tweets
@@ -95,7 +95,7 @@ module Twitter
95
95
  # @param options [Hash] A customizable set of options.
96
96
  # @option options [Boolean, String, Integer] :trim_user Each tweet returned in a timeline will include a user object with only the author's numerical ID when set to true, 't' or 1.
97
97
  def destroy_status(*args)
98
- threaded_tweets_from_response(:post, '/1.1/statuses/destroy', args)
98
+ parallel_tweets_from_response(:post, '/1.1/statuses/destroy', args)
99
99
  end
100
100
  alias_method :destroy_tweet, :destroy_status
101
101
  deprecate_alias :status_destroy, :destroy_status
@@ -280,7 +280,7 @@ module Twitter
280
280
  # @param path [String]
281
281
  # @param args [Array]
282
282
  # @return [Array<Twitter::Tweet>]
283
- def threaded_tweets_from_response(request_method, path, args)
283
+ def parallel_tweets_from_response(request_method, path, args)
284
284
  arguments = Twitter::Arguments.new(args)
285
285
  Twitter::Utils.parallel_map(arguments) do |tweet|
286
286
  id = extract_id(tweet)
@@ -167,13 +167,13 @@ module Twitter
167
167
  def block?(user, options = {})
168
168
  merge_default_cursor!(options)
169
169
  user_id = case user
170
- when Integer
171
- user
172
- when String, URI, Addressable::URI
173
- user(user).id
174
- when Twitter::User
175
- user.id
176
- end
170
+ when Integer
171
+ user
172
+ when String, URI, Addressable::URI
173
+ user(user).id
174
+ when Twitter::User
175
+ user.id
176
+ end
177
177
  blocked_ids(options).map(&:to_i).include?(user_id)
178
178
  end
179
179
 
@@ -191,7 +191,7 @@ module Twitter
191
191
  # @param users [Enumerable<Integer, String, Twitter::User>] A collection of Twitter user IDs, screen names, or objects.
192
192
  # @param options [Hash] A customizable set of options.
193
193
  def block(*args)
194
- threaded_user_objects_from_response(:post, '/1.1/blocks/create.json', args)
194
+ parallel_user_objects_from_response(:post, '/1.1/blocks/create.json', args)
195
195
  end
196
196
 
197
197
  # Un-blocks the users specified by the authenticating user
@@ -207,7 +207,7 @@ module Twitter
207
207
  # @param users [Enumerable<Integer, String, Twitter::User>] A collection of Twitter user IDs, screen names, or objects.
208
208
  # @param options [Hash] A customizable set of options.
209
209
  def unblock(*args)
210
- threaded_user_objects_from_response(:post, '/1.1/blocks/destroy.json', args)
210
+ parallel_user_objects_from_response(:post, '/1.1/blocks/destroy.json', args)
211
211
  end
212
212
 
213
213
  # Returns extended information for up to 100 users